This is an old revision of the document!
Outline:
There is actually three different levels of abstraction to model programs, collectively called abstract-level models:
The following diagram shows the hierarchy of the interface describing models. (This hierarchy has been built thanks to Green.) The root of the models is the interface IAbstractModel, which descibes any model that could be handled by most of Ptidej analyses and tools. This interface abstracts IAbstractLevelModel, which represents models of programs, and IDesignMotif, which represents models of design motifs.
The PADL project also provides IAnalysis interface that must be implemented by any PADL analyses. This interface just requires that an analysis provides a invoke(IAbstractModel) method to return a new model.
The PADL meta-model (Pattern and Abstract-level Description Language) is a semi-language independent meta-model. It is at the core of the Ptidej Tool Suite. It provides a set of interface and a reference implementation of the meta-model. It also provides several parsers to create PADL models from various representations of programs: AOL, AspectJ, C++, Java (byte-code), Eclipse JDT Project, and MSE files.
A PADL model is typically created using the following code:
final ICodeLevelModel codeLevelModel = Factory.getInstance().createCodeLevelModel("A"); codeLevelModel.create( new CompleteClassFileCreator( DefaultFileRepository.getInstance(), new String[] { "dir1/dir2/A.class" }), true);
In general, a code-level model can be obtain for a system through reverse-engineering/parsing using:
final ICodeLevelModel codeLevelModel = Factory.getInstance().createCodeLevelModel(A Name); codeLevelModel.create( new A Creator( A File Repository.getInstance(), new String[] { Some files }), Recurse in directories);
where:
Each constituent of a model has a unique ID, obtained using the getID() method. Navigation through a model is typically performed using recursive calls to the getIteratorOnActors() and getIteratorOnConcurrentActors() methods. (The PADL Creator ClassFile project provides two methods to retrieve (and create if needed) member entities: Utils.searchForEntity(…) and Utils.searchForEnclosingEntity(…). However, these methods should be used as little as possible as they potentially return new instances of IMemberClass (or IMemberInterface or IMemberGhost). Using these methods outside of the creator would be a Dirty Hack!).
A third-party project provides a means to create a PADL model from source code (instead of class files). Fetch PADL Creator Java from the SVN and use the following idiom:
new padl.creator.CreatorJava(DiagnosticListener, Options, Files) .create(Model);
Each argument is described in the JavaDoc of the padl.creator.CreatorJava class.
The PADL meta-model provides you with two distinct but related visitors: IWalker and IGenerator. Both visitors inherit from IVisitor but provide different methods to retreive the results of the visit: getResult() and getCode() respectively. A typical example of using one of these visitors is:
final IWalker walker = new InheritanceImplementationCounter(); final ICodeLevelModel codeLevelModel = Primitive.getFactory().createCodeLevelModel(""); codeLevelModel.create( new CompleteClassFileCreator( DefaultFileRepository.getInstance(), new String[] { path }, true)); final IIdiomLevelModel idiomLevelModel = (IIdiomLevelModel) new AACRelationshipsAnalysis().invoke(codeLevelModel); walker.reset(); idiomLevelModel.walk(walker); System.out.println(walker.getResult());
Obviously, the class InheritanceImplementationCounter implements IWalker.
The PADL meta-model includes an extensive hierarchy of interfaces to describes binary class relationships. The following figure highlights these relationships. Of particular interest are the following relationships, presented in order from the most constraining to the least constraining. Whenever a relationship is identified between two entities, the following least constraining relationships are not included. For example, if an aggregation relationships exists between two classes A and B, no corresponding use relationship would exist.
The existence of binary class relationships is inferred from an ICodeLevelModel based on the presence of certain fields and methods and method invocations in classes by the AACRelationshipsAnalysis.
As part of an effort to improve code representation in PADL. The concept of method invocation has been added since 2004-2005. An interface IMethodInvocation represents method invocations. This concept is as-of-today not quite clean and is used to describes both method invocations and field accesses. Therefore, the interface IMethodInvocation (and its reference implementation) includes:
Although the getID(), getName(), and getPath() methods form a trio, they have different semantics. The getID() must return a unique identifier for each constituent in a model. The getName() returns the name of a constituent, its signature or fully-qualitied name, depending on the constituent. For an entity, a class, an interface, or a ghost, getName() returns the entity fully-qualified name, for example java.lang.Object, for Historical Reason. For any other constituent, binary class relationships and method invocations, the name returned by getName() is less important, it could simply be Method Invocation, for example. (Their ID must still be unique, though.)
Here are some examples of getID() :
Here are some examples of getName() :
The paths are used to represent how to get to a constituent within a model.
The paths start with a '/' and the name of the model (optional).
Then, each constituent to go through until the target is specified the same way:
The class padl.path.Finder can be used to walk the paths.