Introduction
Some people are asking how they can use some of Class Dependency Analyzer (CDA) capabilities in their own projects. Usually that means that no UI is needed. Instead the functionality of embedded CDA libraries is supposed to be programmatically.
One such functionality is the export of a dependency model to XML files. While being available via CDA UI for a long time it was hard to find out how to do it from your own code.
This short guide shows how to do that with CDA up to version 2.3.0 and for the improved API of CDA 2.4.0.
Step by Step
Following the steps below should allow exporting the dependencies of your applications to an XML file.
Prerequisite: Add the required CDA libraries to your project (see ).
-
Create a workset that defines the archives of class files to be analyzed
-
Initialize the workset (i.e. loading all containers and class files)
-
Create an XML exporter with a target output file
-
Run the export on a specific model element and its sub-elements
Required CDA Libraries
All required libraries are available in the following Maven repository:
http://programmers-friend.org/maven/repo/
Most of them can also be found in https://mvnrepository.com/
Note
|
For the version numbers below please user either 2.3.0 or 2.4.0 |
Gradle dependencies
dependencies {
compile group: 'org.pfsw', name: 'pf-cda-core', version: '2.x.0'
compile group: 'org.pfsw', name: 'pf-cda-extensions', version: '2.x.0'
}
Maven dependencies
<dependency>
<groupId>org.pfsw</groupId>
<artifactId>pf-cda-core</artifactId>
<version>2.x.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.pfsw</groupId>
<artifactId>pf-cda-extensions</artifactId>
<version>2.x.0</version>
<scope>compile</scope>
</dependency>
Code Examples
This examples shows how to create programmatically the ODEM export of all containers and classes of MyApp.war.
CDA 2.3.0 and before
Workset workset = new Workset("export-example");
workset.addClasspathPartDefinition(new ClasspathPartDefinition("MyApp.war"));
WorksetInitializer.initWorksetAndWait(workset);
AModelExporter exporter = new XmlFileODEMExporter();
PluginConfiguration pluginConfig = new PluginConfiguration();
pluginConfig.set(XmlFileODEMExporter.PARAM_OUTPUT_FILENAME, "/tmp/myapp-dependencies.odem");
exporter.initialize(pluginConfig);
try
{
ModelExportEngine.instance().export(workset, null, exporter);
}
catch (Exception e)
{
e.printStackTrace();
}
CDA 2.4.0 and later
Workset workset = new Workset("export-example", "MyApp.war");
WorksetInitializer.initWorksetAndWait(workset);
AModelExporter exporter = XmlFileODEMExporter.forOutput("/tmp/myapp-dependencies.odem");
try
{
ModelExportEngine.instance().export(workset, exporter);
}
catch (Exception e)
{
e.printStackTrace();
}
Advanced
Implementing Your Own Exporter
You can also implement your own exporter by extending abstract class org.pfsw.tools.cda.plugin.export.spi.AModelExporter
.
That implies the extension of its superclass org.pfsw.tools.cda.xpi.AModelObjectVisitor
.
Just override the methods necessary to produce the output you want to create.
Tip
|
This approach could be used to export the object dependency model to a database. |
Provide a Progress Monitor
Passing a progress monitor to the export execution can solve two purposes: . Track the elements that are processed . Abort export processing if necessary
A progress monitor just simply needs to implement interface org.pfsw.tools.cda.core.processing.IProgressMonitor
.
Below is a very simple implementation of a progress monitor.
package org.pfsw.tools.cda.examples;
import org.pfsw.tools.cda.core.processing.IProgressMonitor;
public class SimpleConsoleMonitor implements IProgressMonitor
{
@Override
public void startProgressMonitor()
{
System.out.println("=== Start of workset processing ===");
}
@Override
public void terminateProgressMonitor()
{
System.out.println("=== End of workset processing. ===");
System.out.flush();
}
@Override
public boolean showProgress(int value, Object...info)
{
for (Object object : info)
{
System.out.print("Processing: ");
System.out.println(object);
}
return true; // returning false would cancel further processing
}
}