Scripting with Groovy#
Introduction#
The Lattix API allows you to write Groovy scripts to extend and customize the functionality of Lattix. Groovy is a powerful dynamic language. Groovy scripts are loaded and compiled at runtime, so scripts can be quickly written and edited while Lattix is running. Groovy scripts use a Java-like syntax. Further information on how to program groovy scripts can be found here: http://groovy-lang.org/documentation.html.
Lattix will look for a directory under the install directory called “scripts”. You can also configure your own script directories by going through View–>Preference–>Scripting. All the scripts (all files with the .groovy extension) in the script directories will be compiled and loaded. A script file can contain a simple code block, and/or it can contain methods/class definitions. Each script file can produce zero or more “script actions” that will be available via the user interface (either a menu item or via the ldcscript command line program).
Specifying Actions#
A script can define “script actions” in the following ways:
Any block code in the script not contained in a method or class will produce a “script action” that has the same name as the script file (without the .groovy extension).
Any method with the name “action” will produce a “script action” that by default has the same name as the script file.
Any method that has the annotation
@Action
will produce a “script action” that by default has the same name as the script file
Simple Scripts with a One Action and no Arguments:#
script1.groovy:
print("This is the Script1 script\n");
script2.groovy:
def action() {
print("This is the Script2 script\n");
}
script3.groovy:
@Action
def sample_method() {
print("This is the Script3 script\n");
}
Script with Multiple Actions:#
multi.groovy:
@Action("Function1 Action")
def func1(){
print("func1\n");
}
@Action("Function2 Action")
def func2() {
print("func2\n");
}
Note: The @Action
annotation can accept an optional label string for the action.
Script with Action that takes Arguments:#
Here is an example in which the action accepts arguments. When the action is run from the Graphical User Interface, a dialog appears allowing the user to enter the values of the arguments.
params.groovy:
def action(java.io.File fileArg, Integer intArg) {
}
params.groovy:
@Action("Params Action")
def action(@Arg("File") java.io.File fileArg, @Arg("Number value") Integer intArg) {
}
Script Annotations#
A variety of annotations are provided to allow the user to configure where the script menu items shows up, to generate a user interface, localize for other languages, and other capabilities.
@Action
@Arg
@Cancelable
@ClassPath
@Description
@Init
@Keyword
@Localize
@Report
@RequiresVersion
@ScriptDescription
@Shortcut
@Action#
The @Action annotation defines a new action menu item.
@Action("Name of the action")``
@Arg#
The @Arg annotation defines the display name of the action arguments.
@Action("Sample Action")
def action(
@Arg("Partition Argument") Partition part)
{ ...
@Cancelable#
The @Cancelable should be specified if the action is long running and is cancelable
@Action("Sample Action")
@Cancelable
def action()
{
...
@ClassPath#
The @ClassPath allows for jars/classes to be loaded dynamically. For best results, the @ClassPath should be specified right before the action
@ClassPath([ "\${lattix_dir}/lib/plugins/ojdbc6.jar"] )
@Action("Sample Action")
def action()
{
...
The following variables are understood by the @ClassPath annotation. (Note the $ needs to be escaped with a backslash, as shown in the example above)
${lattix_dir} - Lattix Install directory
${lattix_user_dir} - User home directory
${script_dir} - directory script is located
@Description#
The @Description annotation will specify a detailed description of the action. It appears as a tooltip when you hover over the menu item.
@Action("Sample Action")
@Description("Tooltip Description")
def action()
{
...
@Keyword#
The @Keyword annotation will register the script using pre-defined name/value pairs. The following example show how to assign the given action to certain profiles.
@Keyword(id="domain", value="Java,.NET,C/C++,LDI")
@Action("Sample Action")
def action()
{
...
@Localize#
The @Localize annotation
@Localize()
def en = [
"LOCALIZE_ME": "This should be the default (english) localization"
];
@Localize("ja")
def ja = [
"LOCALIZE_ME": "This should be the Japanese localization"
];
// The action name is a localization lookup
@Action("LOCALIZE_ME")
def action()
{
...
@Report#
The @Report annotation configures a custom report into Lattix. The string specified by name appears as a sub-menu item of “Custom Reports” in the Report Menu. Every report is identified by a unique id.
@Report(id="Missing Dependencies", name="Find Missing Package Dependency Relationships", group="Custom Reports")
def findMissingDependencies()
{
...
@RequiresVersion#
The @RequiresVersion annotation informs what the minimum version of Lattix that is required.
@RequiresVersion("7.0")
@Action("Sample Action")
def action()
{
...
@ScriptDescription#
The @ScriptDescription annotation is used for the display in the profile pane.
@ScriptDescription("Display String for Profile Pane")
@Action("Sample Action")
def action()
{
...
@Shortcut#
The @Shortcut annotation allows you to specify a keyboard shortcut for the action. Use the java swing syntax for the shortcut.
@Action("Sample Action")
@Shortcut("ctrl A")
def action()
{
...
Key Interfaces of the API#
Builtin Methods#
There are a few built-in methods that allow you to obtain certain key classes. For instance, every script needs the current ProjectModel, and it can be obtained from a builtin method.
ProjectModel model = getModel();
will allow you to access the current Lattix project. See the Java Doc API interface com.lattix.api.ProjectQuery
to see other methods that are available on the “model-
ProjectSelection selection = getSelection()
will allow you to access the current selection in Architect. The selection only applies to the current view in the Lattix Project. See Java doc API com.lattix.api.ProjectSelection
.
ProjectManager app = getApp();
will allow you to access application feature like opening, closing, saving projects. See Java doc API com.lattix.api.ProjectManager.
ProjectUpdater updater = getProjectUpdater()
will allow you to update the current project with new data sources. See Java doc API com.lattix.api.ProjectUpdater.
Key Classes#
Here are some of the key classes that you are likely to use most often:
ProjectModel
Partition
Atom
DependencyEdge/Dependency
Tag
Note that internally, Lattix is a giant data store. So, any query you make will typically be on the ProjectModel. A Partition is the subsystem that you see in the DSM or the CAD. An Atom is a domain element that is contained within a partition.
The dependencies are between atoms. A DependencyEdge identifies the source and target atoms, while a Dependency identifies only the target atom. While Dependency objects are more efficient from a memory perspective, we find DependencyEdge easier to use. In most of the scripts that we write we choose not to use the Dependency objects.
Project Model#
The interface com.lattix.api.ProjectModel represents the data store. Here are the key sections of the methods in Project Model:
Atom#
The interface com.lattix.core.depends.Atom represents a basic domain element. Partitions contain atoms.
DependencyEdge#
The interface com.lattix.core.depends.DependencyEdge represents a dependency between a source and a target atom. Remember that a target atom can be an external atom.
Partition#
The interface com.lattix.core.partition.Partition represents the basic element of a Lattix project that is visible in a DSM or a CAD.
Tag#
The interface com.lattix.core.partition.Tag represents the tag that can be applied to a partition.
Example Scripts#
To see more examples of scripts, simply look in the scripts directory of your Lattix installation.
Iterate through all Subsystems#
/*
* Iterates through all subsystems (aka partitions) starting at the top (root).
*/
import com.lattix.core.depends.*;
import com.lattix.core.partition.*;
import com.lattix.api.*;
@Action("Iterate through all Subsystems")
def iterate_partitions() {
ProjectModel model = getModel();
Partition root = model.getRootPartition();
process(root);
}
// Recursively iterate through all partitions
void process(Partition curp) {
println("Subsystem: " + curp.getName());
PartitionCollection pc = model.getSubPartitions(curp);
for (Partition p : pc) {
process(p);
}
}
Create New Project from Visual Studio Solution File using Clang module#
@Action("NewSolutionFileProject")
@Description("Create new project from Solution File")
def action(){
ProjectManager manager = getApp();
ProjectContext project = app.newProject();
ProjectUpdater updater = project.getProjectUpdater();
File file = new File("c:/users/default/project/app.sln");
String dataSource = "vs-sln-file:sln_name=" + file.toString() + ",sln_cfg=Debug|x64";
Set ds = new LinkedHashSet();
ds.add(dataSource);
updater.addModuleDataSources("lattix.plugin.clang", ds);
ProjectUpdater.UpdateResult result = updater.updateProject();
}
Create Rule on selection#
@Action("CreateRule")
def createRule(){
def model = getModel();
def selection = getSelection(); // get current selection
PartitionRelationCollection rels = selection.getSelectedRelations();
if (rels && !rels.isEmpty()){
PartitionRelation rel = rels.iterator().next(); // get first selection
// create CAN-USE rule
model.newRule(rel.getSourcePartition(), RuleType.CAN_USE, rel.getTargetPartition());
}
}
Expand/collapse hierarchical expansion#
@Action("Expand view for selected partition")
def view_expand_demo(){
ProjectModel model = getModel();
def root = model.getRootPartition();
def selection = getSelection();
def parts = selection.getSelectedPartitions();
if (!parts.isEmpty()){
Partition child = parts[0];
ProjectModelViewCollection views = model.getProjectModelViewCollection();
ProjectModelView view = views.getView(0);
if (view.isPartitionExpanded(child)){
view.collapsePartitions(child);
}else{
view.expandPartitions(child);
}
}else{
throw new Exception("no partition selected");
}
}
Extract Metrics#
@Action("ExtractMetrics")
@Description("Extract metric for partition")
def action(){
def model = getModel();
def partition = model.getRootPartition();
def metric = model.getMetricDefinition("partition.metric.stability");
Object value = model.getMetricValue(partition, metric);
String metricLabel = getResourceString(metric.getName());
out.println("partition: " + partition.getName());
out.println("metric: " + metricLabel + " = " + value);
}
Dump Dependencies for Selected Subsystem into File#
/*
* The script puts up a graphical interface that allows a user to specify an input
* subsystem. By default, the selected subsystem is chosen. The interface also
* allows the user to specify a file into which the output is generated.
*/
import com.lattix.core.depends.*;
import com.lattix.core.partition.*;
import com.lattix.api.*;
@Action("Dump Dependencies for Selected Subsystem")
def dump_dependencies_to_file(@Init("selection")Partition source, File file)
{
// Extract Project Model
ProjectModel model = getModel();
// Setup the writer
PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(file)));
// Extract all the dependencies FROM the selected partitions
DependencyEdgeCollection edges = model.getEdges(source);
writer.print("FROM dependency edges:");
writer.println();
// Loop through the dependency edges
for (DependencyEdge edge : edges) {
// Get the source and target of the dependency edge
Atom sourceAtom = model.getSourceAtomFor(edge);
Atom targetAtom = model.getTargetAtomFor(edge);
// Write to file (tab separator for easy reading into excel spreadsheet also)
if (targetAtom != null) {
writer.print(sourceAtom.getDisplayName());0
writer.print("\t");
writer.print(targetAtom.getDisplayName());
writer.println();
}
}
// Extract all dependencies TO the selected partitions
edges = model.getUsedByEdges(source); // Need Lattix 7.6 for this api
writer.println();
writer.print("TO dependency edges:");
writer.println();
// Loop through the dependency edges
for (DependencyEdge edge : edges) {
// Get the source and target of the dependency edge
Atom sourceAtom = model.getSourceAtomFor(edge);
Atom targetAtom = model.getTargetAtomFor(edge);
// Write to file (tab separator for easy reading into excel spreadsheet also)
if (targetAtom != null) {
writer.print(sourceAtom.getDisplayName());
writer.print("\t");
writer.print(targetAtom.getDisplayName());
writer.println();
}
}
writer.close();
}
Custom Report: Generate File Name and Line Number of each Violation#
/*
* This custom report generates the file name and line number of
* violation instead of the source atom. The output consists of a table with
* three columns:
*
* Column1- FileName : LineNumber
* Column2- Dependency Kind
* Column3- Target Atom Name
*
* Note: Report annotation ensures that menu item shows up under Reports
* instead of under Scripts
*/
@Report(id="violations_with_lines", name="ViolationsWithLineNumbers", group="Custom Reports")
def usage_report()
{
def model = getModel();
Query query = model.getQuery();
// Query: "select edges.source_atom.sourcefile || ':' || edges.details.line_number as Source, edges.dependency.kind.display_name, edges.target_atom from T_VIOLATORS"
String s1 = "edges.source_atom.sourcefile || ':' || edges.details.line_number as Source";
String s2 = "edges.dependency.kind.display_name";
String s3 = "edges.target_atom";
String queryString = "select " + s1 + ", " + s2 + ", " + s3 + " from T_VIOLATORS";
// Run the Query
Object set = query.runQuery(queryString);
// Generate the Report
def theReport = getReport();
theReport.addDefaultHeaders();
theReport.addResultSetReport(set);
}
@Localize()
def map = [
"ViolationsWithLineNumbers":"Violations with Line Numbers",
];
Custom Report: Uses (inherits) report with Line Numbers#
/*
* UsesKindsDBReportWithLines.groovy
*
* This custom report generates the file name and line number of Uses instead of the source atom, for the inherits dependency
*
* Created on May 27,2015
*
* Copyright (c) 2003-2015 Lattix, Inc. All rights reserved.
*
*/
@Report(id="uses_kinds_db_report_with_lines", name="UsesKindsDBReportWithLineNumbers", group="Custom Reports")
def usage_report(){
def model = getModel();
Query query = model.getQuery();
// Create a QueryBuilder Object
IQueryBuilder qb = query.getQueryBuilder();
// find all the dependency kinds that represent an "inherits" relationship
def kinds = qb.tDependencyKinds().select().cIsInherits().whereEqualTo(Boolean.TRUE).execute();
// Create an edge query on the "edge database";
def edgeQuery = qb.tEdgedb();
// get reference to the linenumber
def lineNumber = edgeQuery.cDetails().cLineNumber();
// select the source file and linenumber
edgeQuery.cSourceAtom().cSourcefile().select().concat(":").concat(lineNumber).selectAs("Source");
// select the dependency kind
def kind = edgeQuery.cDependency().cKind();
// only include dependency kinds that are in the "kinds" set
kind.whereIn(kinds);
kind.select();
// select the target Atom
edgeQuery.cTargetAtom().select();
// Run the query
Results res = edgeQuery.execute();
// get the ResultSet
ObjectResultSet rs = res.getResultSet();
def report = getReport();
// add the ResultSet to the report
report.add(rs);
}
@Localize()
def map = [
"UsesKindsDBReportWithLineNumbers":"Expanded Uses (Inherit) Report With Line Numbers",
];
Custom Report: Uses report with Line Numbers#
/*
* UsesReportWithLines.groovy
*
* This custom report generates the file name and line number of Uses instead of the source atom.
*
* Created on May 27,2015
*
* Copyright (c) 2003-2015 Lattix, Inc. All rights reserved.
*
*/
@Report(id="uses_db_report_with_lines", name="UsesDBReportWithLineNumbers", group="Custom Reports")
def usage_report(){
def model = getModel();
Query query = model.getQuery();
// Create a QueryBuilder Object
IQueryBuilder qb = query.getQueryBuilder();
// Create an edge query on the "edge database";
def edgeQuery = qb.tEdgedb();
// get reference to the linenumber
def lineNumber = edgeQuery.cDetails().cLineNumber();
// select the source file and linenumber
edgeQuery.cSourceAtom().cSourcefile().select().concat(":").concat(lineNumber).selectAs("Source");
// select the dependency kind
edgeQuery.cDependency().cKind().select();
// select the target Atom
edgeQuery.cTargetAtom().select();
// Run the query
Results res = edgeQuery.execute();
// get the ResultSet
ObjectResultSet rs = res.getResultSet();
def report = getReport();
// add the ResultSet to the report
report.add(rs);
}
@Localize()
def map = [
"UsesDBReportWithLineNumbers":"Expanded Uses Report With Line Numbers",
];
Custom Metric#
/*
* Implements a custom metric that shows the number of atoms in a subsystem.
*
* Copyright (c) 2003-2015 Lattix, Inc. All rights reserved.
*
*
*/
@APIMetric(id = "atoms", name = "Atom Count")
def metric(Partition src, Partition target){
def model = getModel();
def atoms = model.getAtomsAt(src);
if (atoms != null){
return atoms.size();
}
return 0;
}
Custom Metric using partition properties#
You can create a new metric by creating a script This metric will use partition properties to retrieve the value of the metric.
This shows how the Decision Coverage metric is calculated
The @Description
annotation informs Lattix how the metric will be calculated and handled:
|
This will let the metric appear in the heatmap |
|
This tells Lattix which partition property to use to calculate the metric |
|
This gives default values that are used to calculate heatmap thresholds |
@APIMetric(id = "coverage.decision", name = "DecisionCoverage", lowerIsBetter="false", aggregate="min", precision="percent" )
@Description("DecisionCoverageDesc")
@Definition(["heatmap=true", "partitionProperty=coverage.decision", "warning=.8", "error=.5"])
@HelpURL("https://cp.lattix.com/help/v12/import/coverage")
def metric3(Partition src, Partition target){
// no implementation needed
}
@Localize("en")
def en = [
"Decision Coverage": "Decision Coverage",
"DecisionCoverageDesc": "Decision Coverage",
];
This metric will return “undefined” until the partition property named “coverage.decision” is set. This API call allows you to set the named partition property like this:
model.setPartitionProperty(partition, "coverage.decision", 0.5);
Expand Members#
/*
* Expand members in the entire project
*/
@Action("Expand members")
def expand_members(){
def model = getModel();
Partition p = model.getRootPartition();
model.expandMembers(p);
}
Partitioning Algorithms#
Apply one of the current Partitioning Algorithms to selected partition#
/*
* 1. Lists the ids of all the partitioning algorithms
* 2. Applies the component partitioner to the selected partition. If
* partition is selected the partitioning is applied to $root.
*
* The interface illustrates how to apply partitioning recursively also.
*
* Copyright (c) 2003-2014 Lattix, Inc. All rights reserved.
*
*/
@RequiresVersion("9.5")
@Action("Component Partitioning by Script")
def action(boolean recursive){
def model = getModel();
// Get the list of all partitioning algorithms configured.
// The list will appear in the Lattix Message Pane.
Iterator it = model.getOrderingAlgorithms();
it.each {
String id = it.getId();
println("Partitioner id: " + id);
}
// Select node to apply partitioning (use root if none selected)
Partition part = model.getRootPartition();
def selection = getSelection();
PartitionCollection pc = selection.getSelectedPartitions();
if (!pc.isEmpty()) {
part = pc.iterator().next();
}
// Apply the component partitioner
DsmOrderingAlgorithm alg = model.getOrderingAlgorithm("component");
model.performOrdering(part, alg, false, recursive);
}
Custom Partitioning Algorithms#
/*
* Note: The use of Ordering annotation ensures that menu item shows up
* in the list of Partitioning algorithms instead of under Scripts.
*
* Copyright (c) 2003-2014 Lattix, Inc. All rights reserved.
*/
@RequiresVersion("9.5")
// --- Reverse the order of the selected partition ---
@Ordering(id="reverse_ordering.demo", name="Reverse Ordering by Script")
def action(partitions) {
def list = new ArrayList();
// This will reverse the order
partitions.each {
Partition part = it;
list.add(0, part);
}
return list;
}
// --- Create a partition group for each partition ----
@Ordering(id="partitioning.demo", name="Partitioning by Script")
def action1(partitions) {
Map map = new LinkedHashMap();
int layer = 0;
// this will put each partition in its own layer
partitions.each {
map.put(it, new Integer(layer));
layer++;
}
return map;
}
class MyItem {
Number value;
Partition part;
MyItem(Partition part, Number value){
this.value= value;
this.part = part;
}
}
// --- Order the partitions by code size ----
@Ordering(id="ordering_size.demo", name="Code Size Order by Script")
def action2(partitions) {
// Create a queue for sorting by value
PriorityQueue sorted = new PriorityQueue(10, new Comparator(){
public int compare(MyItem o1, MyItem o2){
return o1.value.compareTo(o2.value);
}
});
def model = getModel();
String metricId = "metric.atomprop.codesize";
//String metricId = "partition.metric.atomCount";
// get the metric definition
Metric metric = model.getMetricDefinition(metricId);
// Sort the partitions by the value of the given metric
partitions.each {
Partition part = it;
Number value = model.getMetricValue(part, metric);
MyItem item = new MyItem(part, value);
sorted.add(item);
}
// Create list to hold the ordered partitions
ArrayList list = new ArrayList();
// Get the partitions in value order, and add them to the list
MyItem i;
while((i = sorted.poll()) != null){
list.add(i.part);
}
return list;
}
API Reference#
The API documentation is shipped with Lattix. Please see <Lattix Install Directory>/api/lattix_api_doc.zip
QueryBuilder API#
Lattix Query Language allows you to use SQL-like queries.
The queries will allow you to select objects like atoms, partitions, and edges based on specific criteria, including name, metric values and property values. The model data is represented by table-like interfaces. For instance, the IAtoms interface is used to access the atoms, while the IEdges interface is used to access the edges. The relationships among interfaces are represented by the methods on each interface.
Examples#
Find atoms in which the atom name contains the string “work”#
IQueryBuilder queryBuilder = model.getQueryBuilder();
IAtoms atoms = queryBuilder.tAtoms();
Results rs = atoms.cName().whereContains("work").select().execute();
rs.each { println("$it"); }
Find edges in which the target atom name contains the string “test”#
IQueryBuilder queryBuilder = model.getQueryBuilder();
IEdges edges = queryBuilder.tEdges();
Results rs = edges.cTargetAtom().cName().whereContains("test").select().execute();
rs.each { println("$it"); }
Find partitions in which the display name ends with the string “.h”#
IQueryBuilder queryBuilder = model.getQueryBuilder();
IPartitions partitions = queryBuilder.tPartitions();
Results rs = partitions.cDisplayName().whereEndsWith(".h").select().execute();
rs.each { println("$it"); }
Find partitions in which the display name ends with the string “.h” and the partition contains an atom that has a property test=”true”#
IQueryBuilder queryBuilder = model.getQueryBuilder();
IPartitions partitions = queryBuilder.tPartitions();
partitions.cDisplayName().whereEndsWith(".h");
partitions.cAtoms().cProperties("test").cValue().whereEqualTo(Boolean.TRUE);
Results rs = partitions.select().execute();
rs.each { println("$it"); }
IQueryBuilder#
interface IQueryBuilder {
tAtomKinds(); |
All of the atom kinds in the model |
|
tAtomPropertyDefinitions(); |
All of the atom property definitions in the model |
|
tAtomdb(); |
All the atoms in the atom database |
|
tAtoms(); |
All the atoms in the model |
|
tDatasources(); |
All of the data sources in the model |
|
tDependencies(); |
All of the dependencies in the model |
|
tDependencyKinds(); |
All of the dependency kinds in the model |
|
tDependencyPropertyDefinitions(); |
All of the property definitionsin the model |
|
tDisplayPartitions(); |
All of the visible partitions in the current view |
|
tEdgedb(); |
All the edges in the atomdatabase |
|
tEdges(); |
All of the visible edges in the model |
|
tHiddenEdges(); |
All of the hidden edges in the model |
|
tHighLevelCycles(); |
All of the high level cycles in the model |
|
tImpactSet(); |
ImpactSet |
|
tLowLevelCycles(); |
All of the low level cycles in the model |
|
tLowLevelCyclesWithMembers(); |
All of the low level cycles in the model, including members |
|
tMainAtomPartitions(); |
All of the atom partitions that are defined as “main” types |
|
tMetricDefinitions(); |
All metrics defined in the model |
|
IModuleDefinitions |
tModuleDefinitions(); |
The available modules |
tModules(); |
Of the modules in the model |
|
tPartitionDirectories(); |
||
tPartitions(); |
All the partitions in the model |
|
tRules(); |
All of the rules in the model |
|
tTags(); |
All of the tags in the model |
|
tUsedbyEdges(); |
All visible impact edges in the model |
|
tUsesPartitions(); |
All uses partition relations |
|
tViolators(); |
All of the violations in the model |
|
tWorklist(); |
The worklist for the model |
}
IAtomKinds#
interface IAtomKinds {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Atom id |
IStringType |
cDisplayName(); |
Atom displayname |
cModule(); |
Module that created the atom kind |
|
IBooleanType |
cIsType(); |
Atom kind is a type |
IBooleanType |
cIsMethod(); |
Atom kind is a method |
IBooleanType |
cIsField(); |
Atom kind is a field |
IBooleanType |
cIsFile(); |
Atom kind is a file |
IBooleanType |
cIsInterface(); |
Atom kind is an interface |
}
IAtoms#
interface IAtoms {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Name of the atom |
IStringType |
cDisplayName(); |
Display name of the atom |
cKind(); |
Kind of the atom |
|
cParent(); |
Parent of the atom |
|
cMainParent(); |
Main parent of the atom |
|
cModule(); |
Module that created the atom |
|
cDatasource(); |
Container datasource for the atom |
|
IStringType |
cExternalNames(); |
Display external names of the atom |
cPartition(); |
Partition that holds the atom |
|
cProperties(); |
Properties on the atom |
|
cUses(); |
All dependencies on the atom |
|
cEdges(); |
All edges from the atom |
|
cEdgesClosure(); |
All edges of the partition (transitive closure) |
|
cUsedbyEdges(); |
All edges to the atom (reverse edges) |
|
cUsedbyEdgesClosure(); |
All edges to the atom closure (reverse edges) |
|
IStringType |
cSourcefile(); |
Name of the source file if any |
}
ICycleComponents#
interface ICycleComponents {
cThisColumn(); |
Actual row object |
|
INumberType |
cNum(); |
Number of items in the cycle |
INumberType |
cSize(); |
Size of the cycle |
cCycle(); |
Partitions in the cycle |
|
cCycleRelations(); |
Partition Relations in the cycle |
|
cAllRelations(); |
All Partitions Relations in the cycle |
}
ICycles#
interface ICycles {
cThisColumn(); |
Actual row object |
|
cContainer(); |
Container Partition |
|
cCycles(); |
Partitions in the cycle |
|
INumberType |
cNumCycles(); |
Number of cycles |
ISimpleType |
cGraph(); |
Graph of cycles |
cBadEdges(); |
Bad edges |
|
cGoodEdges(); |
Good edges |
|
cEdges(); |
Edges |
}
IDatasource#
interface IDatasource {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Name of the data source |
IStringType |
cDisplayName(); |
Display name of the datasource |
cModule(); |
Module that created the data source |
|
cAtoms(); |
All atoms in the datasource |
|
IProperty |
cInit(); |
Properties of original datasource (i.e. database connection properties) |
IProperty |
cOptions(); |
Options of the data source |
}
IDependency#
interface IDependency {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Dependency name |
cKind(); |
Dependency kind |
|
cModule(); |
Source module of the dependency |
}
IDependencyKinds#
interface IDependencyKinds {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Dependency kind id |
IStringType |
cDisplayName(); |
Dependency kind displayname |
cModule(); |
Module that created the dependency kind |
|
IBooleanType |
cIsInherits(); |
true if is inherits |
IBooleanType |
cIsInvokes(); |
true if is invokes |
IBooleanType |
cIsConstructs(); |
true if is constructs |
IBooleanType |
cIsDataRef(); |
true if is a data reference |
IBooleanType |
cIsTypeRef(); |
true if is a type reference |
}
IEdgeDetails#
interface IEdgeDetails {
cThisColumn(); |
Actual row object |
|
INumberType |
cLineNumber(); |
Line number |
ISourceCode |
cSourceCode(); |
Source Code |
}
IEdges#
interface IEdges {
cThisColumn(); |
Actual row object |
|
IStringType |
cDisplayName(); |
Display name |
cSourceAtom(); |
Source atom of the edge |
|
cDependency(); |
Dependency object of the edge |
|
cKind(); |
Dependency kind of the edge |
|
cTargetAtom(); |
Target atom of the edge |
|
cSourceAndTargetAtom(); |
Source and target atoms of the edge |
|
IBooleanType |
cIsTargetExternal(); |
Target atom is external |
INumberType |
cStrength(); |
Strength of the edge |
cProperties(); |
Property of the edge |
|
ISourceCode |
cSourceCode(); |
Source Code |
cDetails(); |
Edge Details |
|
ISourceCode |
cSourceCodeRegion(); |
Source Code |
cWorkitems(); |
Work items associated with edge |
}
IMetricDefinitions#
interface IMetricDefinitions {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Metric name |
IStringType |
cDisplayName(); |
Metric display name |
IStringType |
cDescription(); |
Metric description |
}
IMetrics#
interface IMetrics {
cThisColumn(); |
Actual row object |
|
cDefinition(); |
Metric |
|
IStringType |
cName(); |
Metric id |
IStringType |
cDisplayName(); |
Metric display name |
ISimpleType |
cValue(); |
Metric Value |
}
IModules#
interface IModules {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Module id |
IStringType |
cDisplayName(); |
Module display name |
IMap |
cKeywords(); |
Module keywords |
}
IPartitionRelations#
interface IPartitionRelations {
cThisColumn(); |
Actual row object |
|
cSource(); |
Source Partition of the partition edge |
|
cTarget(); |
Target Partition of the partition edge |
|
cEdges(); |
edges |
}
IPartitions#
interface IPartitions {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Partition name |
IStringType |
cDisplayName(); |
Partition display name |
IStringType |
cShortDisplayName(); |
Partition short display name |
cAtoms(); |
Atoms contained in the partition |
|
cAtomdb(); |
Atomdatabase atoms contained in the partition |
|
cMainAtom(); |
Main atom contained in the partition |
|
cMetrics(); |
Metrics for the partition |
|
cRules(); |
Rules on the partition |
|
cTags(); |
Tags on the partition |
|
cNonReferencePartition(); |
Return the partition that is not the reference partition |
|
cParent(); |
Parent of the partition |
|
cSiblings(); |
All siblings of the partition |
|
cChildren(); |
All children of the partition |
|
cDependencies(); |
Dependencies of the partition |
|
cAllDependencies(); |
All Dependencies of the partition |
|
cUsesSiblings(); |
All siblings used by the partition |
|
IBooleanType |
cIsRoot(); |
true if the partition is the root |
IBooleanType |
cIsReference(); |
true if the partition is a Reference Partition |
IBooleanType |
cIsOrphan(); |
true if the partition isorphaned |
INumberType |
cDepth(); |
The depth of the partition |
cAncestors(); |
All ancestorsof the partition |
|
cAncestorsInclusive(); |
All ancestors of the partition, including currrent partition |
|
cDescendants(); |
All descendants of the partition |
|
cDescendantsInclusive(); |
All descendants of the partition, including the current partition |
|
cUsesEdges(); |
All edges of the partition |
|
cUsedbyEdges(); |
All edges using the partition |
|
cMainPartition(); |
Closest ancestor that represents container partition. (i.e. non-member partition) |
|
cUsesEdgesClosure(); |
All edges of the partition (transitive closure) |
|
cPartitionImpact(); |
Impact of the partition |
|
cMainAtomPartitionImpact(); |
Impact of the partition |
|
cMainAtomPartitionImpactClosure(); |
Closure Impact of the partition |
|
cImpactClosure(); |
Closure Impact of the partition |
|
cUsesPartitions(); |
Partitions used by this partition |
|
cMainUsesPartitions(); |
Partitions used by this partition |
|
cRelationPartitions(); |
Parent of the partition |
}
IProperties#
interface IProperties {
cThisColumn(); |
Actual row object |
|
cDefinition(); |
Property Definition |
|
IStringType |
cName(); |
Property name |
IStringType |
cDisplayName(); |
Property display name |
ISimpleType |
cValue(); |
Property Value |
}
IPropertyDefinitions#
interface IPropertyDefinitions {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Definition name |
IStringType |
cDisplayName(); |
Definition display name |
IStringType |
cType(); |
Type, true |
cModule(); |
Module |
}
IRules#
interface IRules {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Name of the rule |
IStringType |
cRule(); |
Rule title |
IStringType |
cSource(); |
Source of the rule |
IStringType |
cTarget(); |
Target of the rule |
IBooleanType |
cIsDefault(); |
true if this is the default rule |
}
IViolators#
interface IViolators {
cThisColumn(); |
Actual row object |
|
cSourceAtom(); |
Source atom of the violation |
|
cRule(); |
Rule that caused the violation |
|
cPartition(); |
Source partition of the violation |
|
cDependencies(); |
Dependencies that caused the violation |
|
cEdges(); |
Edges that caused the violation |
|
cEdgedb(); |
Edges (from Edge Database) that caused the violation |
}
IWorkList#
interface IWorkList {
cThisColumn(); |
Actual row object |
|
IStringType |
cName(); |
Work item name |
IStringType |
cDisplayName(); |
Work item title |
IStringType |
cDescription(); |
Work item description |
cParentWorkItem(); |
Parent work items |
|
cSubItems(); |
Subwork items |
|
IWorkItemData |
cData(); |
Data in the work item |
IWorkItemData |
cNamedData(); |
Data in the work item |
}
Select#
interface Select {
Object |
concat(Object param0); |
Object |
function(String param0, Object[] param1); |
Object |
groupBy(); |
Object |
orderBy(boolean param0); |
Object |
select(); |
Object |
forall(Object param0, Object[] param1); |
Object |
foreach(Object param0, Object[] param1); |
Object |
selectAs(String param0); |
}
Table#
interface Table extends Select, Where {
Object |
concat(Object param0); |
Object |
function(String param0, Object[] param1); |
Object |
select(); |
Object |
groupBy(); |
Object |
orderBy(boolean param0); |
Object |
forall(Object param0, Object[] param1); |
Object |
foreach(Object param0, Object[] param1); |
Object |
selectAs(String param0); |
Results |
execute(); |
Results |
execute(String param0, Object[] param1); |
SubQuery |
subQueryLink(String param0, Object[] param1); |
Class |
getTableClass(); |
}
Where#
interface Where {
whereLike(String param0); |
|
whereContains(Stringparam0); |
|
whereLessThan(Objectparam0); |
|
whereNotNull(); |
|
whereNull(); |
|
whereOr(); |
|
whereEndsWith(Stringparam0); |
|
whereAnd(); |
|
whereEqualTo(Object param0); |
|
whereIn(Object param0); |
|
whereNotIn(Object param0); |
|
whereGreaterThan(Objectparam0); |
|
whereStartsWith(Stringparam0); |
|
whereNotEqualTo(Objectparam0); |
|
whereOpenParen(); |
|
whereLessThanOrEqualTo(Objectparam0); |
|
whereCloseParen(); |
|
whereGreaterThanOrEqualTo(Objectparam0); |
}
Script Editor Tool#
Lattix Provides a groovy script editing tool that works with the Lattix environment. Please contact support@code-clinic.com to get a copy of the Lattix Script Editor for Windows or Linux
Before You Start#
The script editor is based on eclipse and requires Java. You will need to have Java 1.8 installed.
On Windows: unless you are Administrator on your computer, you will not be able to edit the scripts that are installed in c:/Program Files with Lattix Architect.
You can add your own script directories that will allow you to edit your scripts. You can add your own script directories from Lattix Architect via the menu View->Preferences. Then select “Scripting” on the left.
Note: Before you run the Script Editor, close Lattix Architect. (You will be able to launch Lattix Architect from the script editor if you wish to debug the script)
Setting Up Editor#
Select the Menu Windows->Preferences.
In the Preferences Dialog, select “Lattix Preferences”
Turn on “Use External Lattix Install”
Enter the location of the Lattix Install in the first text box
The second text box is the name of your Lattix user properties file
Click OK. (You may need to close GUI and reopen)
Debugging Scripts#
Open the script you want to debug by doubling clicking on it in the Script Navigator.
If there are no scripts in the navigator, double check that you have the correct Lattix Install directory specified. Also try clicking the “Refresh” button
When the script opens, you will see errors int he script. These are due to a bug in the groovy plugin that is preventing groovy “aliases” from being recognized in the editor
To start debugging, launch Lattix Architect by clicking the “Debug Lattix” button.
If you see an “Errors in workspace” dialog, you can ignore it by checking the “Always launch without asking” checkbox and clicking the “Proceed” button
If Architect does not launch, try closing and restarting the Script Editor
You can add breakpoints in the script by doubling clicking to the left of the line of code you wish to stop on
You should be able to edit the script while debugging, however, if you change the script you will need to open the “Scripts” menu in Lattix to force the script to be recompiled.
Troubleshooting#
-startup
plugins/org.eclipse.equinox.launcher_1.3.0.v20140415-2008.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20150204-1316
-data
@noDefault
-vm
c:\jdk1.8.0_161\jre\bin\javaw.exe
-vmargs
-XX:MaxPermSize=128M
-Xmx999m