SoMoX Extractor / JDT-Based Java Extractor
Overview
The JDT-based Java extractor is an extractor plugin for the SoMoX Extractor able to parse java source code and build up according elements in a GAST model. The according workflow job reads the GAST Model from the SoMoX Extractor blackboard and uses this as an input for the Java extractor itself which is workflow independent by default. This GAST model handed over to the extractor is then filled with the information extracted from the source code.
Features
Auto Sourcepath Detection
The JDT-based extractor requires a GAST model as input which includes a representation of the file system (files and directories) of the software. It makes use of an auto detection, which receives all java files from the gast model and parse them to extract the java source code information and entities.
Reference Solving
While the code is parsed, a class may be processed which extends another class that has not been processed yet and no according element in the GAST model exists which could be linked. As a result, this reference could not be solved while the JDT AST ist traversed.
To handle those references a reference registry and solver are provided to take care for this. While the JDT AST is traversed, type specific references (e.g. "extends") are registered in the ReferenceRegistry. As a post processing, a ReferenceSolver checks this registry and tries to solve those references based on the GAST model that has been build up during the initial JDT AST processing.
JDT Elements to GAST Mapping
JAVA Model | GAST Model | Status | Used by SoMoX |
---|---|---|---|
Package | Package | implemented | yes |
Class (Regular) | GASTClass | implemented | yes |
Class (Inner) | GASTClass (inner: true) | open | unknown |
Interface (Regular) | GASTClass (isInterface: true) | implemented | unknown |
Class Extends Class Relationship | InheritanceTypeAccess | implemented | yes |
Class Implements Interface Relationship | InheritanceTypeAccess | open | yes |
Root | open | yes | |
BasePath | open | yes | |
Directory | open | yes | |
File | open | yes | |
Method | open | yes | |
Function | open | yes | |
BlockStatement | open | yes | |
Visibilities | open | yes | |
FormalParameter | open | yes | |
Access | open | yes | |
FunctionAccess | open | yes | |
CompositeAccess | open | yes | |
ModelElement | open | yes | |
GASTStruct | open | yes |
SISSy SQL Statements to get SoMoX GAST usage
Java Language Enhancements: http://download.oracle.com/javase/7/docs/technotes/guides/language/enhancements.html
Extraction Method
The JDT provides two different extraction methods (Java Model and AST Parser) but SoMoX uses only the AST Parser based method.
This decision is done because of the pros and cons of those two. However, the main reason was the requirement of the Java Model alternative to have all the source code within a java project what might not be realistic in a general application of the parser. Further Details about the comparision of those two extraction alternatives:
AST – Abstract Syntax Tree
Advantages
- Complete representation of the code (including expressions)
- Allows code manipulation
- Is not limited to Eclipse JAVA projects
Disadvantages
- slower than java model because of more extracted information
- requires code without compilation errors (Not clear if this holds because it is also able access problems in the compilation units)
- not able to let the parser solve all references by himself when he is working with an incomplete context (i.e. parsing a single java file)
Java Model
Is used i.e. for the outline view because faster to be updated.
Advantages
- Faster because of less information extracted
- is able to handle code with compilation errors
Disadvantages
- Not all information (e.g., the body of a method is not available)
- Disadvantage using IJavaProject
- The libraries available in the current eclipse environment become available, too
- it is required to create a new project in the workspace. That needs to be cleaned up. The extractor cannot run within a simple unit test. A plugin unit test is required to ramp up an eclipse environment -> resource demanding
- All sources must be located within the project or a subdirectory of the project. It is not possible to link external resources. -> it is required to copy all sources into the project
Resources
Good Tutorials about working with the JDT:
- http://www.eclipsecon.org/2005/presentations/EclipseCON2005_Tutorial29.pdf
- http://www.vogella.de/articles/EclipseJDT/article.html
- http://www.eclipse.org/articles/article.php?file=Article-JavaCodeManipulation_AST/index.html
GAST Elements used by SoMoX
Paket | Klasse | Methode | Attributbezug | Rückgabetyp |
---|---|---|---|---|
de.fzi.gast.accesses | Access | getAccessedClass | GASTClass | |
de.fzi.gast.accesses | Access | setAccessedTarget | void | |
de.fzi.gast.accesses | InheritanceTypeAccess | setImplementationInheritance | implementationInheritance | void |
de.fzi.gast.core | BasePath | getDirectories | EList<Directory> | |
de.fzi.gast.core | BasePath | setPath | path | void |
de.fzi.gast.core | BasePath | setRoot | void | |
de.fzi.gast.core | Directory | getFiles | EList<File> | |
de.fzi.gast.core | Directory | getFileSystemPath | fileSystemPath | String |
de.fzi.gast.core | Directory | getParentDirectory | Directory | |
de.fzi.gast.core | Directory | getSubDirectory | EList<Directory> | |
de.fzi.gast.core | Directory | setBasePath | void | |
de.fzi.gast.core | Directory | setParentDirectory | void | |
de.fzi.gast.core | File | getDirectory | Directory | |
de.fzi.gast.core | File | getFileSystemPath | fileSystemPath | String |
de.fzi.gast.core | File | getFullQualifiedPath | fullQualifiedPath | String |
de.fzi.gast.core | File | getTypes | EList<GASTType> | |
de.fzi.gast.core | File | setDirectory | void | |
de.fzi.gast.core | File | setLinesOfCode | linesOfCode | void |
de.fzi.gast.core | File | setSize | size | void |
de.fzi.gast.core | File | setSourceFile | sourceFile | void |
de.fzi.gast.core | ModelElement | getSissyId | sissyId | int |
de.fzi.gast.core | ModelElement | setSissyId | sissyId | void |
de.fzi.gast.core | ModelElement | setStatus | void | |
de.fzi.gast.core | Package | getClasses | EList<GASTClass> | |
de.fzi.gast.core | Package | getQualifiedName | qualifiedName | String |
de.fzi.gast.core | Package | getSubPackages | EList<Package> | |
de.fzi.gast.core | Package | getSurroundingPackage | Package | |
de.fzi.gast.core | Package | setSurroundingPackage | void | |
de.fzi.gast.core | Root | getAllInterfaces | interface | EList<GASTClass> |
de.fzi.gast.core | Root | getAllNormalClasses | EList<GASTClass> | |
de.fzi.gast.core | Root | getBasePaths | EList<BasePath> | |
de.fzi.gast.core | Root | getPackageByQualifiedName | qualifiedName (Package) | Package |
de.fzi.gast.core | Root | getPackages | EList<Package> | |
de.fzi.gast.functions | Function | getBody | BlockStatement | |
de.fzi.gast.functions | Function | getFormalParameters | EList<FormalParameter> | |
de.fzi.gast.functions | Function | getReturnTypeDeclaration | DeclarationTypeAccess | |
de.fzi.gast.statements | BlockStatement | getStatements | EList<Statement> | |
de.fzi.gast.types | GASTClass | getAllAccessedClasses | EList<GASTClass> | |
de.fzi.gast.types | GASTClass | getAllAccesses | EList<Access> | |
de.fzi.gast.types | GASTClass | getInheritanceTypeAccesses | EList<InheritanceTypeAccess> | |
de.fzi.gast.types | GASTClass | getInnerClasses | inner | EList<GASTClass> |
de.fzi.gast.types | GASTClass | getMethods | EList<Method> | |
de.fzi.gast.types | GASTClass | getSuperTypes | EList<GASTClass> | |
de.fzi.gast.types | GASTClass | getSurroundingPackage | Package | |
de.fzi.gast.types | GASTClass | isInner | inner | boolean |
de.fzi.gast.types | GASTClass | isInterface | interface | boolean |
de.fzi.gast.types | GASTClass | isPrimitive | primitive | boolean |
de.fzi.gast.types | GASTClass | setSurroundingPackage | void | |
de.fzi.gast.accesses | DeclarationTypeAccess | (parameter from return type) | ||
de.fzi.gast.variables | FormalParameter | (parameter from return type) | ||
de.fzi.gast.statements | Statement | (parameter from return type) | ||
de.fzi.gast.types | GASTType | (parameter from return type) | ||
de.fzi.gast.functions | Method | (parameter from return type) |