Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
gr.uom.java.xmi.UMLModelASTReader Maven / Gradle / Ivy
package gr.uom.java.xmi;
import static gr.uom.java.xmi.decomposition.Visitor.stringify;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.compiler.IScanner;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.AbstractTagElement;
import org.eclipse.jdt.core.dom.AbstractTypeDeclaration;
import org.eclipse.jdt.core.dom.Annotation;
import org.eclipse.jdt.core.dom.AnnotationTypeDeclaration;
import org.eclipse.jdt.core.dom.AnnotationTypeMemberDeclaration;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.BodyDeclaration;
import org.eclipse.jdt.core.dom.ClassInstanceCreation;
import org.eclipse.jdt.core.dom.Comment;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.EnumConstantDeclaration;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.Expression;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.IDocElement;
import org.eclipse.jdt.core.dom.IExtendedModifier;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.Initializer;
import org.eclipse.jdt.core.dom.JavaDocRegion;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MemberRef;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.MethodRef;
import org.eclipse.jdt.core.dom.Modifier;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.RecordDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.SuperMethodInvocation;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.TagProperty;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclarationStatement;
import org.eclipse.jdt.core.dom.TypeParameter;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.VariableDeclarationStatement;
import com.github.gumtreediff.gen.jdt.JdtVisitor;
import com.github.gumtreediff.tree.TreeContext;
import gr.uom.java.xmi.LocationInfo.CodeElementType;
import gr.uom.java.xmi.decomposition.AbstractExpression;
import gr.uom.java.xmi.decomposition.OperationBody;
import gr.uom.java.xmi.decomposition.VariableDeclaration;
public class UMLModelASTReader {
private static final String FREE_MARKER_GENERATED = "generated using freemarker";
private static final String FREE_MARKER_GENERATED_2 = "generated using FreeMarker";
private static final String ANTLR_GENERATED = "// $ANTLR";
private static final String XTEXT_GENERATED = "generated by Xtext";
private static final String LWJGL_GENERATED = "MACHINE GENERATED FILE, DO NOT EDIT";
private static final String TEST_GENERATOR_GENERATED = "generated by TestGenerator";
private static final String THRIFT_GENERATED = "Autogenerated by Thrift Compiler";
private static final String AUTOREST_GENERATED = "AutoRest Code Generator";
private static final String FHIR_GENERATED = "for FHIR";
private static final String CAMEL_GENERATED = "Generated by camel-package-maven-plugin";
private static final String DEFAULT_JAVA_CORE_VERSION = JavaCore.VERSION_14;
private static final Pattern LEAD_WHITE_SPACE_JAVADOC = Pattern.compile("^\s+\\*", Pattern.MULTILINE);
private UMLModel umlModel;
public UMLModelASTReader(Map javaFileContents, Set repositoryDirectories, boolean astDiff) {
this.umlModel = new UMLModel(repositoryDirectories);
processJavaFileContents(javaFileContents, astDiff);
}
public static ASTNode processBlock(String methodBody) {
ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
Map options = JavaCore.getOptions();
options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, JavaCore.VERSION_1_8);
options.put(JavaCore.COMPILER_SOURCE, JavaCore.VERSION_1_8);
options.put(JavaCore.COMPILER_COMPLIANCE, JavaCore.VERSION_1_8);
parser.setCompilerOptions(options);
parser.setResolveBindings(false);
parser.setKind(ASTParser.K_STATEMENTS);
parser.setStatementsRecovery(true);
char[] charArray = methodBody.toCharArray();
parser.setSource(charArray);
ASTNode node = parser.createAST(null);
ASTNode methodBodyBlock = null;
if(node instanceof Block) {
Block extraBlockAddedByParser = (Block)node;
if(extraBlockAddedByParser.statements().size() > 0) {
methodBodyBlock = (ASTNode)extraBlockAddedByParser.statements().get(0);
}
}
return methodBodyBlock;
}
private void processJavaFileContents(Map javaFileContents, boolean astDiff) {
ASTParser parser = ASTParser.newParser(AST.getJLSLatest());
for(String filePath : javaFileContents.keySet()) {
String javaFileContent = javaFileContents.get(filePath);
if((javaFileContent.contains(FREE_MARKER_GENERATED) || javaFileContent.contains(FREE_MARKER_GENERATED_2) || javaFileContent.contains(ANTLR_GENERATED) ||
javaFileContent.contains(XTEXT_GENERATED) || javaFileContent.contains(LWJGL_GENERATED) || javaFileContent.contains(TEST_GENERATOR_GENERATED) ||
javaFileContent.contains(THRIFT_GENERATED) || javaFileContent.contains(AUTOREST_GENERATED) || javaFileContent.contains(FHIR_GENERATED) ||
javaFileContent.contains(CAMEL_GENERATED)) &&
!javaFileContent.contains("\"" + CAMEL_GENERATED + "\"") &&
!javaFileContent.contains("private static final String FREE_MARKER_GENERATED = \"generated using freemarker\";")) {
continue;
}
char[] charArray = javaFileContent.toCharArray();
try {
CompilationUnit compilationUnit = getCompilationUnit(DEFAULT_JAVA_CORE_VERSION, parser, charArray);
String maxRecommendedVersionFromProblems = getMaxRecommendedVersionFromProblems(compilationUnit);
if (maxRecommendedVersionFromProblems != null)
compilationUnit = getCompilationUnit(maxRecommendedVersionFromProblems, parser, charArray);
processCompilationUnit(filePath, compilationUnit, javaFileContent);
if(astDiff) {
IScanner scanner = ToolFactory.createScanner(true, false, false, false);
scanner.setSource(charArray);
JdtVisitor visitor = new JdtVisitor(scanner);
compilationUnit.accept(visitor);
TreeContext treeContext = visitor.getTreeContext();
this.umlModel.getTreeContextMap().put(filePath, treeContext);
}
}
catch(Exception e) {
//e.printStackTrace();
}
}
}
private static CompilationUnit getCompilationUnit(String javaCoreVersion, ASTParser parser, char[] charArray) {
Map options = JavaCore.getOptions();
options.put(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, javaCoreVersion);
options.put(JavaCore.COMPILER_SOURCE, javaCoreVersion);
options.put(JavaCore.COMPILER_COMPLIANCE, javaCoreVersion);
parser.setCompilerOptions(options);
parser.setResolveBindings(false);
parser.setKind(ASTParser.K_COMPILATION_UNIT);
parser.setStatementsRecovery(true);
parser.setSource(charArray);
return (CompilationUnit) parser.createAST(null);
}
private static String getMaxRecommendedVersionFromProblems(CompilationUnit compilationUnit) {
IProblem[] problems = compilationUnit.getProblems();
String result = null;
for (IProblem problem : problems) {
String[] arguments = problem.getArguments();
if (arguments != null && arguments.length > 1) {
try {
double value = Double.parseDouble(arguments[1]);
if (result == null || value > Double.parseDouble(result)) {
result = arguments[1];
}
} catch (NumberFormatException e) {
// System.out.println("Invalid number format in arguments: " + arguments[1]);
}
}
}
return result;
}
public UMLModel getUmlModel() {
return this.umlModel;
}
protected void processCompilationUnit(String sourceFilePath, CompilationUnit compilationUnit, String javaFileContent) {
List comments = extractInternalComments(compilationUnit, sourceFilePath, javaFileContent);
this.umlModel.getCommentMap().put(sourceFilePath, comments);
PackageDeclaration packageDeclaration = compilationUnit.getPackage();
String packageName = null;
UMLJavadoc packageDoc = null;
UMLPackage umlPackage = null;
if(packageDeclaration != null) {
packageName = packageDeclaration.getName().getFullyQualifiedName();
packageDoc = generateJavadoc(compilationUnit, sourceFilePath, packageDeclaration.getJavadoc(), javaFileContent);
LocationInfo packageLocationInfo = generateLocationInfo(compilationUnit, sourceFilePath, packageDeclaration, CodeElementType.PACKAGE_DECLARATION);
umlPackage = new UMLPackage(packageName, packageLocationInfo);
}
else {
packageName = "";
}
List imports = compilationUnit.imports();
List importedTypes = new ArrayList();
for(ImportDeclaration importDeclaration : imports) {
String elementName = importDeclaration.getName().getFullyQualifiedName();
LocationInfo locationInfo = generateLocationInfo(compilationUnit, sourceFilePath, importDeclaration, CodeElementType.IMPORT_DECLARATION);
UMLImport imported = new UMLImport(elementName, importDeclaration.isOnDemand(), importDeclaration.isStatic(), locationInfo);
importedTypes.add(imported);
}
List topLevelTypeDeclarations = compilationUnit.types();
for(AbstractTypeDeclaration abstractTypeDeclaration : topLevelTypeDeclarations) {
if(abstractTypeDeclaration instanceof TypeDeclaration) {
TypeDeclaration topLevelTypeDeclaration = (TypeDeclaration)abstractTypeDeclaration;
processTypeDeclaration(compilationUnit, topLevelTypeDeclaration, umlPackage, packageName, sourceFilePath, importedTypes, packageDoc, comments, javaFileContent);
}
else if(abstractTypeDeclaration instanceof EnumDeclaration) {
EnumDeclaration enumDeclaration = (EnumDeclaration)abstractTypeDeclaration;
processEnumDeclaration(compilationUnit, enumDeclaration, umlPackage, packageName, sourceFilePath, importedTypes, packageDoc, comments, javaFileContent);
}
else if(abstractTypeDeclaration instanceof AnnotationTypeDeclaration) {
AnnotationTypeDeclaration annotationDeclaration = (AnnotationTypeDeclaration)abstractTypeDeclaration;
processAnnotationTypeDeclaration(compilationUnit, annotationDeclaration, umlPackage, packageName, sourceFilePath, importedTypes, packageDoc, comments, javaFileContent);
}
else if(abstractTypeDeclaration instanceof RecordDeclaration) {
RecordDeclaration recordDeclaration = (RecordDeclaration)abstractTypeDeclaration;
processRecordDeclaration(compilationUnit, recordDeclaration, umlPackage, packageName, sourceFilePath, importedTypes, packageDoc, comments, javaFileContent);
}
}
}
private List extractInternalComments(CompilationUnit cu, String sourceFile, String javaFileContent) {
List astComments = cu.getCommentList();
List comments = new ArrayList();
for(Comment comment : astComments) {
LocationInfo locationInfo = null;
if(comment.isLineComment()) {
locationInfo = generateLocationInfo(cu, sourceFile, comment, CodeElementType.LINE_COMMENT);
}
else if(comment.isBlockComment()) {
locationInfo = generateLocationInfo(cu, sourceFile, comment, CodeElementType.BLOCK_COMMENT);
}
else if(comment.isDocComment() && comment.getParent() == null) {
locationInfo = generateLocationInfo(cu, sourceFile, comment, CodeElementType.BLOCK_COMMENT);
}
if(locationInfo != null) {
int start = comment.getStartPosition();
int end = start + comment.getLength();
String text = javaFileContent.substring(start, end);
UMLComment umlComment = new UMLComment(text, locationInfo);
comments.add(umlComment);
}
}
return comments;
}
private void distributeComments(List compilationUnitComments, LocationInfo codeElementLocationInfo, List codeElementComments) {
ListIterator listIterator = compilationUnitComments.listIterator(compilationUnitComments.size());
while(listIterator.hasPrevious()) {
UMLComment comment = listIterator.previous();
LocationInfo commentLocationInfo = comment.getLocationInfo();
if(codeElementLocationInfo.subsumes(commentLocationInfo) ||
codeElementLocationInfo.sameLine(commentLocationInfo) ||
(codeElementLocationInfo.nextLine(commentLocationInfo) && !codeElementLocationInfo.getCodeElementType().equals(CodeElementType.ANONYMOUS_CLASS_DECLARATION)) ||
(codeElementComments.size() > 0 && codeElementComments.get(0).getLocationInfo().nextLine(commentLocationInfo))) {
codeElementComments.add(0, comment);
}
}
compilationUnitComments.removeAll(codeElementComments);
}
private UMLJavadoc generateJavadoc(CompilationUnit cu, BodyDeclaration bodyDeclaration, String sourceFile, String javaFileContent) {
Javadoc javaDoc = bodyDeclaration.getJavadoc();
return generateJavadoc(cu, sourceFile, javaDoc, javaFileContent);
}
private UMLJavadoc generateJavadoc(CompilationUnit cu, String sourceFile, Javadoc javaDoc, String javaFileContent) {
UMLJavadoc doc = null;
if(javaDoc != null) {
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, javaDoc, CodeElementType.JAVADOC);
int start = javaDoc.getStartPosition();
int end = start + javaDoc.getLength();
String text = javaFileContent.substring(start, end);
Matcher matcher = LEAD_WHITE_SPACE_JAVADOC.matcher(text);
StringBuilder sb = new StringBuilder();
while (matcher.find()) {
matcher.appendReplacement(sb, " \\*");
}
matcher.appendTail(sb);
String trimLeadWhiteSpace = sb.toString();
doc = new UMLJavadoc(trimLeadWhiteSpace, locationInfo);
List tags = javaDoc.tags();
for(TagElement parentTag : tags) {
LocationInfo tagLocationInfo = generateLocationInfo(cu, sourceFile, parentTag, CodeElementType.TAG_ELEMENT);
UMLTagElement parentTagElement = new UMLTagElement(parentTag.getTagName(), tagLocationInfo);
processTagFragments(cu, sourceFile, parentTag, parentTagElement);
doc.addTag(parentTagElement);
}
}
return doc;
}
private void processTagFragments(CompilationUnit cu, String sourceFile, TagElement parentTag, UMLTagElement parentTagElement) {
List fragments = parentTag.fragments();
for(IDocElement docElement : fragments) {
LocationInfo docElementLocationInfo = generateLocationInfo(cu, sourceFile, (ASTNode)docElement, CodeElementType.DOC_ELEMENT);
if(docElement instanceof TagElement) {
TagElement nestedTag = (TagElement)docElement;
UMLTagElement nestedTagElement = new UMLTagElement(nestedTag.getTagName(), docElementLocationInfo);
processTagFragments(cu, sourceFile, nestedTag, nestedTagElement);
parentTagElement.addNestedTag(nestedTagElement);
}
else if(docElement instanceof JavaDocRegion) {
//TODO support JavaDocRegion
}
else {
UMLDocElement umlDocElement = new UMLDocElement(docElement.toString(), docElementLocationInfo);
if(docElement instanceof Name) {
umlDocElement.setName(true);
}
else if(docElement instanceof MemberRef) {
umlDocElement.setMemberRef(true);
}
else if(docElement instanceof MethodRef) {
umlDocElement.setMethodRef(true);
}
else if(docElement instanceof TagProperty) {
umlDocElement.setTagProperty(true);
}
parentTagElement.addFragment(umlDocElement);
}
}
}
private boolean generatedCode(UMLJavadoc javadoc) {
if(javadoc != null)
return javadoc.contains(FREE_MARKER_GENERATED) || javadoc.contains(FREE_MARKER_GENERATED_2) ||
javadoc.contains(ANTLR_GENERATED) || javadoc.contains(XTEXT_GENERATED);
return false;
}
private void processRecordDeclaration(CompilationUnit cu, RecordDeclaration recordDeclaration, UMLPackage umlPackage, String packageName, String sourceFile,
List importedTypes, UMLJavadoc packageDoc, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, recordDeclaration, sourceFile, javaFileContent);
if(generatedCode(javadoc)) {
return;
}
String recordName = recordDeclaration.getName().getFullyQualifiedName();
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, recordDeclaration, CodeElementType.RECORD_DECLARATION);
UMLClass umlClass = new UMLClass(packageName, recordName, locationInfo, recordDeclaration.isPackageMemberTypeDeclaration(), importedTypes);
umlClass.setJavadoc(javadoc);
if(recordDeclaration.isPackageMemberTypeDeclaration()) {
umlClass.setPackageDeclaration(umlPackage);
umlClass.setPackageDeclarationJavadoc(packageDoc);
for(UMLComment comment : comments) {
if(comment.getLocationInfo().before(locationInfo)) {
umlClass.getPackageDeclarationComments().add(comment);
}
}
comments.removeAll(umlClass.getPackageDeclarationComments());
}
umlClass.setRecord(true);
int startSignatureOffset = processModifiers(cu, sourceFile, recordDeclaration, umlClass);
if(startSignatureOffset == -1) {
startSignatureOffset = recordDeclaration.getName().getStartPosition();
}
List typeParameters = recordDeclaration.typeParameters();
for(TypeParameter typeParameter : typeParameters) {
UMLTypeParameter umlTypeParameter = new UMLTypeParameter(typeParameter.getName().getFullyQualifiedName(),
generateLocationInfo(cu, sourceFile, typeParameter, CodeElementType.TYPE_PARAMETER));
List typeBounds = typeParameter.typeBounds();
for(Type type : typeBounds) {
umlTypeParameter.addTypeBound(UMLType.extractTypeObject(cu, sourceFile, type, 0));
}
List typeParameterExtendedModifiers = typeParameter.modifiers();
for(IExtendedModifier extendedModifier : typeParameterExtendedModifiers) {
if(extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
umlTypeParameter.addAnnotation(new UMLAnnotation(cu, sourceFile, annotation));
}
}
umlClass.addTypeParameter(umlTypeParameter);
}
List superInterfaceTypes = recordDeclaration.superInterfaceTypes();
for(Type interfaceType : superInterfaceTypes) {
UMLType umlType = UMLType.extractTypeObject(cu, sourceFile, interfaceType, 0);
UMLRealization umlRealization = new UMLRealization(umlClass, umlType.getClassType());
umlClass.addImplementedInterface(umlType);
getUmlModel().addRealization(umlRealization);
}
List recordComponents = recordDeclaration.recordComponents();
for(SingleVariableDeclaration recordComponent : recordComponents) {
Type parameterType = recordComponent.getType();
String parameterName = recordComponent.getName().getFullyQualifiedName();
UMLType type = UMLType.extractTypeObject(cu, sourceFile, parameterType, recordComponent.getExtraDimensions());
if(recordComponent.isVarargs()) {
type.setVarargs();
}
LocationInfo recordComponentLocationInfo = new LocationInfo(cu, sourceFile, recordComponent, CodeElementType.RECORD_COMPONENT);
UMLRecordComponent umlRecordComponent = new UMLRecordComponent(parameterName, type, recordComponentLocationInfo);
VariableDeclaration variableDeclaration = new VariableDeclaration(cu, sourceFile, recordComponent, umlRecordComponent, recordComponent.isVarargs());
variableDeclaration.setAttribute(true);
umlRecordComponent.setVariableDeclaration(variableDeclaration);
umlRecordComponent.setClassName(umlClass.getName());
umlClass.addAttribute(umlRecordComponent);
}
Map map = processBodyDeclarations(cu, recordDeclaration, umlPackage, packageName, sourceFile, importedTypes, umlClass, packageDoc, comments, javaFileContent);
processAnonymousClassDeclarations(cu, recordDeclaration, umlPackage, packageName, sourceFile, recordName, importedTypes, packageDoc, comments, umlClass, javaFileContent);
for(BodyDeclaration declaration : map.keySet()) {
if(declaration instanceof MethodDeclaration) {
UMLOperation operation = (UMLOperation) map.get(declaration);
processMethodBody(cu, sourceFile, (MethodDeclaration) declaration, operation, umlClass.getAttributes());
}
else if(declaration instanceof Initializer) {
UMLInitializer initializer = (UMLInitializer) map.get(declaration);
processInitializerBody(cu, sourceFile, (Initializer) declaration, initializer, umlClass.getAttributes());
}
}
int endSignatureOffset = recordDeclaration.bodyDeclarations().size() > 0 ?
((BodyDeclaration)recordDeclaration.bodyDeclarations().get(0)).getStartPosition() :
recordDeclaration.getStartPosition() + recordDeclaration.getLength();
String text = javaFileContent.substring(startSignatureOffset, endSignatureOffset);
if(text.contains("{"))
text = text.substring(0, text.indexOf("{") + 1);
if(!text.contains("record ")) {
umlClass.setActualSignature("record " + text);
}
else {
umlClass.setActualSignature(text);
}
this.getUmlModel().addClass(umlClass);
distributeComments(comments, locationInfo, umlClass.getComments());
}
private void processAnnotationTypeDeclaration(CompilationUnit cu, AnnotationTypeDeclaration annotationDeclaration, UMLPackage umlPackage, String packageName, String sourceFile,
List importedTypes, UMLJavadoc packageDoc, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, annotationDeclaration, sourceFile, javaFileContent);
if(generatedCode(javadoc)) {
return;
}
String className = annotationDeclaration.getName().getFullyQualifiedName();
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, annotationDeclaration, CodeElementType.ANNOTATION_TYPE_DECLARATION);
UMLClass umlClass = new UMLClass(packageName, className, locationInfo, annotationDeclaration.isPackageMemberTypeDeclaration(), importedTypes);
umlClass.setJavadoc(javadoc);
if(annotationDeclaration.isPackageMemberTypeDeclaration()) {
umlClass.setPackageDeclaration(umlPackage);
umlClass.setPackageDeclarationJavadoc(packageDoc);
for(UMLComment comment : comments) {
if(comment.getLocationInfo().before(locationInfo)) {
umlClass.getPackageDeclarationComments().add(comment);
}
}
comments.removeAll(umlClass.getPackageDeclarationComments());
}
umlClass.setAnnotation(true);
int startSignatureOffset = processModifiers(cu, sourceFile, annotationDeclaration, umlClass);
if(startSignatureOffset == -1) {
startSignatureOffset = annotationDeclaration.getName().getStartPosition();
}
Map map = processBodyDeclarations(cu, annotationDeclaration, umlPackage, packageName, sourceFile, importedTypes, umlClass, packageDoc, comments, javaFileContent);
processAnonymousClassDeclarations(cu, annotationDeclaration, umlPackage, packageName, sourceFile, className, importedTypes, packageDoc, comments, umlClass, javaFileContent);
for(BodyDeclaration declaration : map.keySet()) {
if(declaration instanceof MethodDeclaration) {
UMLOperation operation = (UMLOperation) map.get(declaration);
processMethodBody(cu, sourceFile, (MethodDeclaration) declaration, operation, umlClass.getAttributes());
}
else if(declaration instanceof Initializer) {
UMLInitializer initializer = (UMLInitializer) map.get(declaration);
processInitializerBody(cu, sourceFile, (Initializer) declaration, initializer, umlClass.getAttributes());
}
}
int endSignatureOffset = annotationDeclaration.bodyDeclarations().size() > 0 ?
((BodyDeclaration)annotationDeclaration.bodyDeclarations().get(0)).getStartPosition() :
annotationDeclaration.getStartPosition() + annotationDeclaration.getLength();
String text = javaFileContent.substring(startSignatureOffset, endSignatureOffset);
if(text.contains("{"))
text = text.substring(0, text.indexOf("{") + 1);
if(!text.contains("@interface ")) {
umlClass.setActualSignature("@interface " + text);
}
else {
umlClass.setActualSignature(text);
}
this.getUmlModel().addClass(umlClass);
distributeComments(comments, locationInfo, umlClass.getComments());
}
private void processEnumDeclaration(CompilationUnit cu, EnumDeclaration enumDeclaration, UMLPackage umlPackage, String packageName, String sourceFile,
List importedTypes, UMLJavadoc packageDoc, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, enumDeclaration, sourceFile, javaFileContent);
if(generatedCode(javadoc)) {
return;
}
String className = enumDeclaration.getName().getFullyQualifiedName();
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, enumDeclaration, CodeElementType.ENUM_DECLARATION);
UMLClass umlClass = new UMLClass(packageName, className, locationInfo, enumDeclaration.isPackageMemberTypeDeclaration(), importedTypes);
umlClass.setJavadoc(javadoc);
if(enumDeclaration.isPackageMemberTypeDeclaration()) {
umlClass.setPackageDeclaration(umlPackage);
umlClass.setPackageDeclarationJavadoc(packageDoc);
for(UMLComment comment : comments) {
if(comment.getLocationInfo().before(locationInfo)) {
umlClass.getPackageDeclarationComments().add(comment);
}
}
comments.removeAll(umlClass.getPackageDeclarationComments());
}
umlClass.setEnum(true);
List superInterfaceTypes = enumDeclaration.superInterfaceTypes();
for(Type interfaceType : superInterfaceTypes) {
UMLType umlType = UMLType.extractTypeObject(cu, sourceFile, interfaceType, 0);
UMLRealization umlRealization = new UMLRealization(umlClass, umlType.getClassType());
umlClass.addImplementedInterface(umlType);
getUmlModel().addRealization(umlRealization);
}
List enumConstantDeclarations = enumDeclaration.enumConstants();
for(EnumConstantDeclaration enumConstantDeclaration : enumConstantDeclarations) {
processEnumConstantDeclaration(cu, enumConstantDeclaration, sourceFile, umlClass, comments, javaFileContent);
}
int startSignatureOffset = processModifiers(cu, sourceFile, enumDeclaration, umlClass);
if(startSignatureOffset == -1) {
startSignatureOffset = enumDeclaration.getName().getStartPosition();
}
Map map = processBodyDeclarations(cu, enumDeclaration, umlPackage, packageName, sourceFile, importedTypes, umlClass, packageDoc, comments, javaFileContent);
processAnonymousClassDeclarations(cu, enumDeclaration, umlPackage, packageName, sourceFile, className, importedTypes, packageDoc, comments, umlClass, javaFileContent);
for(BodyDeclaration declaration : map.keySet()) {
if(declaration instanceof MethodDeclaration) {
UMLOperation operation = (UMLOperation) map.get(declaration);
processMethodBody(cu, sourceFile, (MethodDeclaration) declaration, operation, umlClass.getAttributes());
}
else if(declaration instanceof Initializer) {
UMLInitializer initializer = (UMLInitializer) map.get(declaration);
processInitializerBody(cu, sourceFile, (Initializer) declaration, initializer, umlClass.getAttributes());
}
}
int endSignatureOffset = enumDeclaration.bodyDeclarations().size() > 0 ?
((BodyDeclaration)enumDeclaration.bodyDeclarations().get(0)).getStartPosition() :
enumDeclaration.getStartPosition() + enumDeclaration.getLength();
String text = javaFileContent.substring(startSignatureOffset, endSignatureOffset);
if(text.contains("{"))
text = text.substring(0, text.indexOf("{") + 1);
if(!text.contains("enum ")) {
umlClass.setActualSignature("enum " + text);
}
else {
umlClass.setActualSignature(text);
}
this.getUmlModel().addClass(umlClass);
distributeComments(comments, locationInfo, umlClass.getComments());
}
private Map processBodyDeclarations(CompilationUnit cu, AbstractTypeDeclaration abstractTypeDeclaration, UMLPackage umlPackage, String packageName,
String sourceFile, List importedTypes, UMLClass umlClass, UMLJavadoc packageDoc, List comments, String javaFileContent) {
Map map = new LinkedHashMap<>();
List bodyDeclarations = abstractTypeDeclaration.bodyDeclarations();
boolean interfaceOrAnnotation = umlClass.isInterface() || umlClass.isAnnotation();
for(BodyDeclaration bodyDeclaration : bodyDeclarations) {
if(bodyDeclaration instanceof FieldDeclaration) {
FieldDeclaration fieldDeclaration = (FieldDeclaration)bodyDeclaration;
List attributes = processFieldDeclaration(cu, fieldDeclaration, interfaceOrAnnotation, sourceFile, comments, javaFileContent);
for(UMLAttribute attribute : attributes) {
attribute.setClassName(umlClass.getName());
umlClass.addAttribute(attribute);
}
}
else if(bodyDeclaration instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration)bodyDeclaration;
UMLOperation operation = processMethodDeclaration(cu, methodDeclaration, packageName, interfaceOrAnnotation, sourceFile, comments, javaFileContent);
operation.setClassName(umlClass.getName());
umlClass.addOperation(operation);
map.put(methodDeclaration, operation);
}
else if(bodyDeclaration instanceof AnnotationTypeMemberDeclaration) {
AnnotationTypeMemberDeclaration annotationTypeMemberDeclaration = (AnnotationTypeMemberDeclaration)bodyDeclaration;
UMLOperation operation = processAnnotationTypeMember(cu, annotationTypeMemberDeclaration, packageName, interfaceOrAnnotation, sourceFile, comments, javaFileContent);
operation.setClassName(umlClass.getName());
umlClass.addOperation(operation);
map.put(annotationTypeMemberDeclaration, operation);
}
else if(bodyDeclaration instanceof Initializer) {
Initializer initializer = (Initializer)bodyDeclaration;
UMLInitializer umlInitializer = processInitializer(cu, initializer, packageName, false, sourceFile, comments, javaFileContent);
umlInitializer.setClassName(umlClass.getName());
umlClass.addInitializer(umlInitializer);
map.put(initializer, umlInitializer);
}
else if(bodyDeclaration instanceof TypeDeclaration) {
TypeDeclaration typeDeclaration = (TypeDeclaration)bodyDeclaration;
processTypeDeclaration(cu, typeDeclaration, umlPackage, umlClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
else if(bodyDeclaration instanceof EnumDeclaration) {
EnumDeclaration enumDeclaration = (EnumDeclaration)bodyDeclaration;
processEnumDeclaration(cu, enumDeclaration, umlPackage, umlClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
else if(bodyDeclaration instanceof AnnotationTypeDeclaration) {
AnnotationTypeDeclaration annotationDeclaration = (AnnotationTypeDeclaration)bodyDeclaration;
processAnnotationTypeDeclaration(cu, annotationDeclaration, umlPackage, umlClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
else if(bodyDeclaration instanceof RecordDeclaration) {
RecordDeclaration recordDeclaration = (RecordDeclaration)bodyDeclaration;
processRecordDeclaration(cu, recordDeclaration, umlPackage, umlClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
}
return map;
}
private void processTypeDeclaration(CompilationUnit cu, TypeDeclaration typeDeclaration, UMLPackage umlPackage, String packageName, String sourceFile,
List importedTypes, UMLJavadoc packageDoc, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, typeDeclaration, sourceFile, javaFileContent);
if(generatedCode(javadoc)) {
return;
}
String className = typeDeclaration.getName().getFullyQualifiedName();
if(className.equals("$")) {
return;
}
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, typeDeclaration, CodeElementType.TYPE_DECLARATION);
UMLClass umlClass = new UMLClass(packageName, className, locationInfo, typeDeclaration.isPackageMemberTypeDeclaration(), importedTypes);
umlClass.setJavadoc(javadoc);
if(typeDeclaration.isPackageMemberTypeDeclaration()) {
umlClass.setPackageDeclaration(umlPackage);
umlClass.setPackageDeclarationJavadoc(packageDoc);
for(UMLComment comment : comments) {
if(comment.getLocationInfo().before(locationInfo)) {
umlClass.getPackageDeclarationComments().add(comment);
}
}
comments.removeAll(umlClass.getPackageDeclarationComments());
}
if(typeDeclaration.isInterface()) {
umlClass.setInterface(true);
}
int startSignatureOffset = processModifiers(cu, sourceFile, typeDeclaration, umlClass);
if(startSignatureOffset == -1) {
startSignatureOffset = typeDeclaration.getName().getStartPosition();
}
List typeParameters = typeDeclaration.typeParameters();
for(TypeParameter typeParameter : typeParameters) {
UMLTypeParameter umlTypeParameter = new UMLTypeParameter(typeParameter.getName().getFullyQualifiedName(),
generateLocationInfo(cu, sourceFile, typeParameter, CodeElementType.TYPE_PARAMETER));
List typeBounds = typeParameter.typeBounds();
for(Type type : typeBounds) {
umlTypeParameter.addTypeBound(UMLType.extractTypeObject(cu, sourceFile, type, 0));
}
List typeParameterExtendedModifiers = typeParameter.modifiers();
for(IExtendedModifier extendedModifier : typeParameterExtendedModifiers) {
if(extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
umlTypeParameter.addAnnotation(new UMLAnnotation(cu, sourceFile, annotation));
}
}
umlClass.addTypeParameter(umlTypeParameter);
}
Type superclassType = typeDeclaration.getSuperclassType();
if(superclassType != null) {
UMLType umlType = UMLType.extractTypeObject(cu, sourceFile, superclassType, 0);
UMLGeneralization umlGeneralization = new UMLGeneralization(umlClass, umlType.getClassType());
umlClass.setSuperclass(umlType);
getUmlModel().addGeneralization(umlGeneralization);
}
List superInterfaceTypes = typeDeclaration.superInterfaceTypes();
for(Type interfaceType : superInterfaceTypes) {
UMLType umlType = UMLType.extractTypeObject(cu, sourceFile, interfaceType, 0);
UMLRealization umlRealization = new UMLRealization(umlClass, umlType.getClassType());
umlClass.addImplementedInterface(umlType);
getUmlModel().addRealization(umlRealization);
}
Map map = processBodyDeclarations(cu, typeDeclaration, umlPackage, packageName, sourceFile, importedTypes, umlClass, packageDoc, comments, javaFileContent);
processAnonymousClassDeclarations(cu, typeDeclaration, umlPackage, packageName, sourceFile, className, importedTypes, packageDoc, comments, umlClass, javaFileContent);
for(BodyDeclaration declaration : map.keySet()) {
if(declaration instanceof MethodDeclaration) {
UMLOperation operation = (UMLOperation) map.get(declaration);
processMethodBody(cu, sourceFile, (MethodDeclaration) declaration, operation, umlClass.getAttributes());
}
else if(declaration instanceof Initializer) {
UMLInitializer initializer = (UMLInitializer) map.get(declaration);
processInitializerBody(cu, sourceFile, (Initializer) declaration, initializer, umlClass.getAttributes());
}
}
int endSignatureOffset = typeDeclaration.bodyDeclarations().size() > 0 ?
((BodyDeclaration)typeDeclaration.bodyDeclarations().get(0)).getStartPosition() :
typeDeclaration.getStartPosition() + typeDeclaration.getLength();
String text = javaFileContent.substring(startSignatureOffset, endSignatureOffset);
if(text.contains("{"))
text = text.substring(0, text.indexOf("{") + 1);
if(!text.contains("class ") && !text.contains("interface ")) {
if(typeDeclaration.isInterface()) {
umlClass.setActualSignature("interface " + text);
}
else {
umlClass.setActualSignature("class " + text);
}
}
else {
umlClass.setActualSignature(text);
}
this.getUmlModel().addClass(umlClass);
distributeComments(comments, locationInfo, umlClass.getComments());
}
private void processAnonymousClassDeclarations(CompilationUnit cu, AbstractTypeDeclaration typeDeclaration,
UMLPackage umlPackage, String packageName, String sourceFile, String className,
List importedTypes, UMLJavadoc packageDoc, List allComments, UMLClass umlClass, String javaFileContent) {
AnonymousClassDeclarationVisitor visitor = new AnonymousClassDeclarationVisitor();
typeDeclaration.accept(visitor);
Set anonymousClassDeclarations = visitor.getAnonymousClassDeclarations();
Set typeDeclarationStatements = visitor.getTypeDeclarationStatements();
for(TypeDeclarationStatement statement : typeDeclarationStatements) {
String methodNamePath = getMethodNamePath(statement);
String fullName = packageName + "." + className + "." + methodNamePath;
AbstractTypeDeclaration localTypeDeclaration = statement.getDeclaration();
if(localTypeDeclaration instanceof TypeDeclaration) {
TypeDeclaration typeDeclaration2 = (TypeDeclaration)localTypeDeclaration;
processTypeDeclaration(cu, typeDeclaration2, umlPackage, fullName, sourceFile, importedTypes, packageDoc, allComments, javaFileContent);
}
else if(localTypeDeclaration instanceof EnumDeclaration) {
EnumDeclaration enumDeclaration = (EnumDeclaration)localTypeDeclaration;
processEnumDeclaration(cu, enumDeclaration, umlPackage, fullName, sourceFile, importedTypes, packageDoc, allComments, javaFileContent);
}
else if(localTypeDeclaration instanceof AnnotationTypeDeclaration) {
AnnotationTypeDeclaration annotationDeclaration = (AnnotationTypeDeclaration)localTypeDeclaration;
processAnnotationTypeDeclaration(cu, annotationDeclaration, umlPackage, fullName, sourceFile, importedTypes, packageDoc, allComments, javaFileContent);
}
else if(localTypeDeclaration instanceof RecordDeclaration) {
RecordDeclaration recordDeclaration = (RecordDeclaration)localTypeDeclaration;
processRecordDeclaration(cu, recordDeclaration, umlPackage, fullName, sourceFile, importedTypes, packageDoc, allComments, javaFileContent);
}
}
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
for(AnonymousClassDeclaration anonymous : anonymousClassDeclarations) {
insertNode(anonymous, root);
}
List createdAnonymousClasses = new ArrayList();
Enumeration enumeration = root.postorderEnumeration();
while(enumeration.hasMoreElements()) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)enumeration.nextElement();
if(node.getUserObject() != null) {
AnonymousClassDeclaration anonymous = (AnonymousClassDeclaration)node.getUserObject();
boolean operationFound = false;
boolean attributeFound = false;
boolean initializerFound = false;
UMLOperation matchingOperation = null;
UMLAttribute matchingAttribute = null;
UMLInitializer matchingInitializer = null;
UMLEnumConstant matchingEnumConstant = null;
List comments = null;
for(UMLOperation operation : umlClass.getOperations()) {
if(operation.getLocationInfo().getStartOffset() <= anonymous.getStartPosition() &&
operation.getLocationInfo().getEndOffset() >= anonymous.getStartPosition()+anonymous.getLength()) {
comments = operation.getComments();
operationFound = true;
matchingOperation = operation;
break;
}
}
if(!operationFound) {
for(UMLAttribute attribute : umlClass.getAttributes()) {
if(attribute.getLocationInfo().getStartOffset() <= anonymous.getStartPosition() &&
attribute.getLocationInfo().getEndOffset() >= anonymous.getStartPosition()+anonymous.getLength()) {
comments = attribute.getComments();
attributeFound = true;
matchingAttribute = attribute;
break;
}
}
}
if(!operationFound && !attributeFound) {
for(UMLInitializer initializer : umlClass.getInitializers()) {
if(initializer.getLocationInfo().getStartOffset() <= anonymous.getStartPosition() &&
initializer.getLocationInfo().getEndOffset() >= anonymous.getStartPosition()+anonymous.getLength()) {
comments = initializer.getComments();
initializerFound = true;
matchingInitializer = initializer;
break;
}
}
}
if(!operationFound && !attributeFound && !initializerFound) {
for(UMLEnumConstant enumConstant : umlClass.getEnumConstants()) {
if(enumConstant.getLocationInfo().getStartOffset() <= anonymous.getStartPosition() &&
enumConstant.getLocationInfo().getEndOffset() >= anonymous.getStartPosition()+anonymous.getLength()) {
comments = enumConstant.getComments();
matchingEnumConstant = enumConstant;
break;
}
}
}
if(matchingOperation != null || matchingAttribute != null || matchingInitializer != null || matchingEnumConstant != null) {
String anonymousBinaryName = getAnonymousBinaryName(node);
String anonymousCodePath = getAnonymousCodePath(node);
UMLAnonymousClass anonymousClass = processAnonymousClassDeclaration(cu, anonymous, umlPackage, packageName + "." + className, anonymousBinaryName, anonymousCodePath, sourceFile, packageDoc, comments, umlClass.getImportedTypes(), javaFileContent);
umlClass.addAnonymousClass(anonymousClass);
if(matchingOperation != null) {
matchingOperation.addAnonymousClass(anonymousClass);
anonymousClass.addParentContainer(matchingOperation);
}
if(matchingAttribute != null) {
matchingAttribute.addAnonymousClass(anonymousClass);
anonymousClass.addParentContainer(matchingAttribute);
}
if(matchingInitializer != null) {
matchingInitializer.addAnonymousClass(anonymousClass);
anonymousClass.addParentContainer(matchingInitializer);
}
if(matchingEnumConstant != null) {
matchingEnumConstant.addAnonymousClass(anonymousClass);
anonymousClass.addParentContainer(matchingEnumConstant);
}
for(UMLOperation operation : anonymousClass.getOperations()) {
for(UMLAnonymousClass createdAnonymousClass : createdAnonymousClasses) {
if(operation.getLocationInfo().subsumes(createdAnonymousClass.getLocationInfo())) {
operation.addAnonymousClass(createdAnonymousClass);
createdAnonymousClass.addParentContainer(operation);
}
}
}
for(UMLAttribute attribute : anonymousClass.getAttributes()) {
for(UMLAnonymousClass createdAnonymousClass : createdAnonymousClasses) {
if(attribute.getLocationInfo().subsumes(createdAnonymousClass.getLocationInfo())) {
attribute.addAnonymousClass(createdAnonymousClass);
createdAnonymousClass.addParentContainer(attribute);
}
}
}
for(UMLInitializer initializer : anonymousClass.getInitializers()) {
for(UMLAnonymousClass createdAnonymousClass : createdAnonymousClasses) {
if(initializer.getLocationInfo().subsumes(createdAnonymousClass.getLocationInfo())) {
initializer.addAnonymousClass(createdAnonymousClass);
createdAnonymousClass.addParentContainer(initializer);
}
}
}
for(UMLEnumConstant enumConstant : anonymousClass.getEnumConstants()) {
for(UMLAnonymousClass createdAnonymousClass : createdAnonymousClasses) {
if(enumConstant.getLocationInfo().subsumes(createdAnonymousClass.getLocationInfo())) {
enumConstant.addAnonymousClass(createdAnonymousClass);
createdAnonymousClass.addParentContainer(enumConstant);
}
}
}
createdAnonymousClasses.add(anonymousClass);
List bodyDeclarations = anonymous.bodyDeclarations();
int i=0;
int j=0;
for(BodyDeclaration bodyDeclaration : bodyDeclarations) {
if(bodyDeclaration instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration)bodyDeclaration;
UMLOperation operation = anonymousClass.getOperations().get(i);
processMethodBody(cu, sourceFile, methodDeclaration, operation, umlClass.getAttributes());
i++;
}
else if(bodyDeclaration instanceof Initializer) {
Initializer initializer = (Initializer)bodyDeclaration;
UMLInitializer umlInitializer = anonymousClass.getInitializers().get(j);
processInitializerBody(cu, sourceFile, initializer, umlInitializer, umlClass.getAttributes());
j++;
}
}
}
}
}
}
private void processMethodBody(CompilationUnit cu, String sourceFile, MethodDeclaration methodDeclaration, UMLOperation operation, List attributes) {
Block block = methodDeclaration.getBody();
if(block != null) {
OperationBody body = new OperationBody(cu, sourceFile, block, operation, attributes);
operation.setBody(body);
}
else {
operation.setBody(null);
}
}
private void processInitializerBody(CompilationUnit cu, String sourceFile, Initializer initializer, UMLInitializer umlInitializer, List attributes) {
Block block = initializer.getBody();
if(block != null) {
OperationBody body = new OperationBody(cu, sourceFile, block, umlInitializer, attributes);
umlInitializer.setBody(body);
}
else {
umlInitializer.setBody(null);
}
}
private int processModifiers(CompilationUnit cu, String sourceFile, AbstractTypeDeclaration typeDeclaration, UMLClass umlClass) {
int startSignatureOffset = -1;
int modifiers = typeDeclaration.getModifiers();
if((modifiers & Modifier.ABSTRACT) != 0)
umlClass.setAbstract(true);
if((modifiers & Modifier.STATIC) != 0)
umlClass.setStatic(true);
if((modifiers & Modifier.FINAL) != 0)
umlClass.setFinal(true);
if((modifiers & Modifier.PUBLIC) != 0)
umlClass.setVisibility(Visibility.PUBLIC);
else if((modifiers & Modifier.PROTECTED) != 0)
umlClass.setVisibility(Visibility.PROTECTED);
else if((modifiers & Modifier.PRIVATE) != 0)
umlClass.setVisibility(Visibility.PRIVATE);
else
umlClass.setVisibility(Visibility.PACKAGE);
List extendedModifiers = typeDeclaration.modifiers();
for(IExtendedModifier extendedModifier : extendedModifiers) {
if(extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
umlClass.addAnnotation(new UMLAnnotation(cu, sourceFile, annotation));
}
else if(extendedModifier.isModifier()) {
Modifier modifier = (Modifier)extendedModifier;
umlClass.addModifier(new UMLModifier(cu, sourceFile, modifier));
if(startSignatureOffset == -1) {
startSignatureOffset = modifier.getStartPosition();
}
}
}
return startSignatureOffset;
}
private UMLInitializer processInitializer(CompilationUnit cu, Initializer initializer, String packageName, boolean isInterfaceMethod, String sourceFile, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, initializer, sourceFile, javaFileContent);
String name = "";
if(initializer.getParent() instanceof AnonymousClassDeclaration && initializer.getParent().getParent() instanceof ClassInstanceCreation) {
ClassInstanceCreation creation = (ClassInstanceCreation)initializer.getParent().getParent();
name = stringify(creation.getType());
}
else if(initializer.getParent() instanceof AbstractTypeDeclaration) {
AbstractTypeDeclaration typeDeclaration = (AbstractTypeDeclaration)initializer.getParent();
name = typeDeclaration.getName().getIdentifier();
}
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, initializer, CodeElementType.INITIALIZER);
UMLInitializer umlInitializer = new UMLInitializer(name, locationInfo);
umlInitializer.setJavadoc(javadoc);
distributeComments(comments, locationInfo, umlInitializer.getComments());
int methodModifiers = initializer.getModifiers();
if((methodModifiers & Modifier.STATIC) != 0)
umlInitializer.setStatic(true);
return umlInitializer;
}
private UMLOperation processAnnotationTypeMember(CompilationUnit cu, AnnotationTypeMemberDeclaration annotationTypeMemberDeclatation, String packageName, boolean isInterfaceMethod, String sourceFile, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, annotationTypeMemberDeclatation, sourceFile, javaFileContent);
String methodName = annotationTypeMemberDeclatation.getName().getFullyQualifiedName();
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, annotationTypeMemberDeclatation, CodeElementType.ANNOTATION_TYPE_MEMBER_DECLARATION);
UMLOperation umlOperation = new UMLOperation(methodName, locationInfo);
umlOperation.setJavadoc(javadoc);
distributeComments(comments, locationInfo, umlOperation.getComments());
int methodModifiers = annotationTypeMemberDeclatation.getModifiers();
if((methodModifiers & Modifier.PUBLIC) != 0)
umlOperation.setVisibility(Visibility.PUBLIC);
else if((methodModifiers & Modifier.PROTECTED) != 0)
umlOperation.setVisibility(Visibility.PROTECTED);
else if((methodModifiers & Modifier.PRIVATE) != 0)
umlOperation.setVisibility(Visibility.PRIVATE);
else if(isInterfaceMethod)
umlOperation.setVisibility(Visibility.PUBLIC);
else
umlOperation.setVisibility(Visibility.PACKAGE);
if((methodModifiers & Modifier.ABSTRACT) != 0)
umlOperation.setAbstract(true);
if((methodModifiers & Modifier.FINAL) != 0)
umlOperation.setFinal(true);
if((methodModifiers & Modifier.STATIC) != 0)
umlOperation.setStatic(true);
if((methodModifiers & Modifier.SYNCHRONIZED) != 0)
umlOperation.setSynchronized(true);
if((methodModifiers & Modifier.NATIVE) != 0)
umlOperation.setNative(true);
if((methodModifiers & Modifier.DEFAULT) != 0)
umlOperation.setDefault(true);
List extendedModifiers = annotationTypeMemberDeclatation.modifiers();
for(IExtendedModifier extendedModifier : extendedModifiers) {
if(extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
umlOperation.addAnnotation(new UMLAnnotation(cu, sourceFile, annotation));
}
else if(extendedModifier.isModifier()) {
Modifier modifier = (Modifier)extendedModifier;
umlOperation.addModifier(new UMLModifier(cu, sourceFile, modifier));
}
}
Type returnType = annotationTypeMemberDeclatation.getType();
if(returnType != null) {
UMLType type = UMLType.extractTypeObject(cu, sourceFile, returnType, 0);
UMLParameter returnParameter = new UMLParameter("return", type, "return", false);
umlOperation.addParameter(returnParameter);
}
if(annotationTypeMemberDeclatation.getDefault() != null) {
AbstractExpression defaultExpression = new AbstractExpression(cu, sourceFile, annotationTypeMemberDeclatation.getDefault(), CodeElementType.ANNOTATION_TYPE_MEMBER_DEFAULT_EXPRESSION, umlOperation);
umlOperation.setDefaultExpression(defaultExpression);
}
return umlOperation;
}
private UMLOperation processMethodDeclaration(CompilationUnit cu, MethodDeclaration methodDeclaration, String packageName, boolean isInterfaceMethod, String sourceFile, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, methodDeclaration, sourceFile, javaFileContent);
String methodName = methodDeclaration.getName().getFullyQualifiedName();
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, methodDeclaration, CodeElementType.METHOD_DECLARATION);
UMLOperation umlOperation = new UMLOperation(methodName, locationInfo);
umlOperation.setJavadoc(javadoc);
distributeComments(comments, locationInfo, umlOperation.getComments());
if(methodDeclaration.isConstructor())
umlOperation.setConstructor(true);
int methodModifiers = methodDeclaration.getModifiers();
if((methodModifiers & Modifier.PUBLIC) != 0)
umlOperation.setVisibility(Visibility.PUBLIC);
else if((methodModifiers & Modifier.PROTECTED) != 0)
umlOperation.setVisibility(Visibility.PROTECTED);
else if((methodModifiers & Modifier.PRIVATE) != 0)
umlOperation.setVisibility(Visibility.PRIVATE);
else if(isInterfaceMethod)
umlOperation.setVisibility(Visibility.PUBLIC);
else
umlOperation.setVisibility(Visibility.PACKAGE);
if((methodModifiers & Modifier.ABSTRACT) != 0)
umlOperation.setAbstract(true);
if((methodModifiers & Modifier.FINAL) != 0)
umlOperation.setFinal(true);
if((methodModifiers & Modifier.STATIC) != 0)
umlOperation.setStatic(true);
if((methodModifiers & Modifier.SYNCHRONIZED) != 0)
umlOperation.setSynchronized(true);
if((methodModifiers & Modifier.NATIVE) != 0)
umlOperation.setNative(true);
if((methodModifiers & Modifier.DEFAULT) != 0)
umlOperation.setDefault(true);
List extendedModifiers = methodDeclaration.modifiers();
int startSignatureOffset = -1;
for(IExtendedModifier extendedModifier : extendedModifiers) {
if(extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
umlOperation.addAnnotation(new UMLAnnotation(cu, sourceFile, annotation));
}
else if(extendedModifier.isModifier()) {
Modifier modifier = (Modifier)extendedModifier;
umlOperation.addModifier(new UMLModifier(cu, sourceFile, modifier));
if(startSignatureOffset == -1) {
startSignatureOffset = modifier.getStartPosition();
}
}
}
List typeParameters = methodDeclaration.typeParameters();
if(startSignatureOffset == -1 && typeParameters.size() > 0) {
startSignatureOffset = typeParameters.get(0).getStartPosition();
}
for(TypeParameter typeParameter : typeParameters) {
UMLTypeParameter umlTypeParameter = new UMLTypeParameter(typeParameter.getName().getFullyQualifiedName(),
generateLocationInfo(cu, sourceFile, typeParameter, CodeElementType.TYPE_PARAMETER));
List typeBounds = typeParameter.typeBounds();
for(Type type : typeBounds) {
umlTypeParameter.addTypeBound(UMLType.extractTypeObject(cu, sourceFile, type, 0));
}
List typeParameterExtendedModifiers = typeParameter.modifiers();
for(IExtendedModifier extendedModifier : typeParameterExtendedModifiers) {
if(extendedModifier.isAnnotation()) {
Annotation annotation = (Annotation)extendedModifier;
umlTypeParameter.addAnnotation(new UMLAnnotation(cu, sourceFile, annotation));
}
}
umlOperation.addTypeParameter(umlTypeParameter);
}
Type returnType = methodDeclaration.getReturnType2();
if(returnType != null) {
if(startSignatureOffset == -1) {
startSignatureOffset = returnType.getStartPosition();
}
UMLType type = UMLType.extractTypeObject(cu, sourceFile, returnType, methodDeclaration.getExtraDimensions());
UMLParameter returnParameter = new UMLParameter("return", type, "return", false);
umlOperation.addParameter(returnParameter);
}
if(startSignatureOffset == -1) {
startSignatureOffset = methodDeclaration.getName().getStartPosition();
}
List parameters = methodDeclaration.parameters();
for(SingleVariableDeclaration parameter : parameters) {
Type parameterType = parameter.getType();
String parameterName = parameter.getName().getFullyQualifiedName();
UMLType type = UMLType.extractTypeObject(cu, sourceFile, parameterType, parameter.getExtraDimensions());
if(parameter.isVarargs()) {
type.setVarargs();
}
UMLParameter umlParameter = new UMLParameter(parameterName, type, "in", parameter.isVarargs());
VariableDeclaration variableDeclaration = new VariableDeclaration(cu, sourceFile, parameter, umlOperation, parameter.isVarargs());
variableDeclaration.setParameter(true);
umlParameter.setVariableDeclaration(variableDeclaration);
umlOperation.addParameter(umlParameter);
}
List thrownExceptionTypes = methodDeclaration.thrownExceptionTypes();
for(Type thrownExceptionType : thrownExceptionTypes) {
UMLType type = UMLType.extractTypeObject(cu, sourceFile, thrownExceptionType, 0);
umlOperation.addThrownExceptionType(type);
}
int endSignatureOffset = methodDeclaration.getBody() != null ?
methodDeclaration.getBody().getStartPosition() + 1 :
methodDeclaration.getStartPosition() + methodDeclaration.getLength();
String text = javaFileContent.substring(startSignatureOffset, endSignatureOffset);
umlOperation.setActualSignature(text);
return umlOperation;
}
private void processEnumConstantDeclaration(CompilationUnit cu, EnumConstantDeclaration enumConstantDeclaration, String sourceFile, UMLClass umlClass, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, enumConstantDeclaration, sourceFile, javaFileContent);
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, enumConstantDeclaration, CodeElementType.ENUM_CONSTANT_DECLARATION);
UMLEnumConstant enumConstant = new UMLEnumConstant(enumConstantDeclaration.getName().getIdentifier(), UMLType.extractTypeObject(umlClass.getName()), locationInfo);
VariableDeclaration variableDeclaration = new VariableDeclaration(cu, sourceFile, enumConstantDeclaration, javaFileContent);
enumConstant.setVariableDeclaration(variableDeclaration);
enumConstant.setJavadoc(javadoc);
distributeComments(comments, locationInfo, enumConstant.getComments());
enumConstant.setFinal(true);
enumConstant.setStatic(true);
enumConstant.setVisibility(Visibility.PUBLIC);
List arguments = enumConstantDeclaration.arguments();
for(Expression argument : arguments) {
enumConstant.addArgument(stringify(argument));
}
enumConstant.setClassName(umlClass.getName());
umlClass.addEnumConstant(enumConstant);
}
private List processFieldDeclaration(CompilationUnit cu, FieldDeclaration fieldDeclaration, boolean isInterfaceField, String sourceFile, List comments, String javaFileContent) {
UMLJavadoc javadoc = generateJavadoc(cu, fieldDeclaration, sourceFile, javaFileContent);
List attributes = new ArrayList();
Type fieldType = fieldDeclaration.getType();
List fragments = fieldDeclaration.fragments();
for(VariableDeclarationFragment fragment : fragments) {
UMLType type = UMLType.extractTypeObject(cu, sourceFile, fieldType, fragment.getExtraDimensions());
String fieldName = fragment.getName().getFullyQualifiedName();
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, fragment, CodeElementType.FIELD_DECLARATION);
UMLAttribute umlAttribute = new UMLAttribute(fieldName, type, locationInfo);
umlAttribute.setFieldDeclarationLocationInfo(generateLocationInfo(cu, sourceFile, fieldDeclaration, CodeElementType.FIELD_DECLARATION));
VariableDeclaration variableDeclaration = new VariableDeclaration(cu, sourceFile, fragment, umlAttribute, javaFileContent);
variableDeclaration.setAttribute(true);
umlAttribute.setVariableDeclaration(variableDeclaration);
umlAttribute.setJavadoc(javadoc);
distributeComments(comments, locationInfo, umlAttribute.getComments());
int fieldModifiers = fieldDeclaration.getModifiers();
if((fieldModifiers & Modifier.PUBLIC) != 0)
umlAttribute.setVisibility(Visibility.PUBLIC);
else if((fieldModifiers & Modifier.PROTECTED) != 0)
umlAttribute.setVisibility(Visibility.PROTECTED);
else if((fieldModifiers & Modifier.PRIVATE) != 0)
umlAttribute.setVisibility(Visibility.PRIVATE);
else if(isInterfaceField)
umlAttribute.setVisibility(Visibility.PUBLIC);
else
umlAttribute.setVisibility(Visibility.PACKAGE);
if((fieldModifiers & Modifier.FINAL) != 0)
umlAttribute.setFinal(true);
if((fieldModifiers & Modifier.STATIC) != 0)
umlAttribute.setStatic(true);
if((fieldModifiers & Modifier.VOLATILE) != 0)
umlAttribute.setVolatile(true);
if((fieldModifiers & Modifier.TRANSIENT) != 0)
umlAttribute.setTransient(true);
attributes.add(umlAttribute);
}
return attributes;
}
private UMLAnonymousClass processAnonymousClassDeclaration(CompilationUnit cu, AnonymousClassDeclaration anonymous, UMLPackage umlPackage, String packageName, String binaryName, String codePath, String sourceFile, UMLJavadoc packageDoc, List comments, List importedTypes, String javaFileContent) {
List bodyDeclarations = anonymous.bodyDeclarations();
LocationInfo locationInfo = generateLocationInfo(cu, sourceFile, anonymous, CodeElementType.ANONYMOUS_CLASS_DECLARATION);
UMLAnonymousClass anonymousClass = new UMLAnonymousClass(packageName, binaryName, codePath, locationInfo, importedTypes);
for(BodyDeclaration bodyDeclaration : bodyDeclarations) {
if(bodyDeclaration instanceof FieldDeclaration) {
FieldDeclaration fieldDeclaration = (FieldDeclaration)bodyDeclaration;
List attributes = processFieldDeclaration(cu, fieldDeclaration, false, sourceFile, comments, javaFileContent);
for(UMLAttribute attribute : attributes) {
attribute.setClassName(anonymousClass.getCodePath());
attribute.setAnonymousClassContainer(anonymousClass);
anonymousClass.addAttribute(attribute);
}
}
else if(bodyDeclaration instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration)bodyDeclaration;
UMLOperation operation = processMethodDeclaration(cu, methodDeclaration, packageName, false, sourceFile, comments, javaFileContent);
operation.setClassName(anonymousClass.getCodePath());
operation.setAnonymousClassContainer(anonymousClass);
anonymousClass.addOperation(operation);
}
else if(bodyDeclaration instanceof Initializer) {
Initializer initializer = (Initializer)bodyDeclaration;
UMLInitializer umlInitializer = processInitializer(cu, initializer, packageName, false, sourceFile, comments, javaFileContent);
umlInitializer.setClassName(anonymousClass.getCodePath());
umlInitializer.setAnonymousClassContainer(anonymousClass);
anonymousClass.addInitializer(umlInitializer);
}
else if(bodyDeclaration instanceof TypeDeclaration) {
TypeDeclaration typeDeclaration = (TypeDeclaration)bodyDeclaration;
processTypeDeclaration(cu, typeDeclaration, umlPackage, anonymousClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
else if(bodyDeclaration instanceof EnumDeclaration) {
EnumDeclaration enumDeclaration = (EnumDeclaration)bodyDeclaration;
processEnumDeclaration(cu, enumDeclaration, umlPackage, anonymousClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
else if(bodyDeclaration instanceof AnnotationTypeDeclaration) {
AnnotationTypeDeclaration annotationDeclaration = (AnnotationTypeDeclaration)bodyDeclaration;
processAnnotationTypeDeclaration(cu, annotationDeclaration, umlPackage, anonymousClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
else if(bodyDeclaration instanceof RecordDeclaration) {
RecordDeclaration recordDeclaration = (RecordDeclaration)bodyDeclaration;
processRecordDeclaration(cu, recordDeclaration, umlPackage, anonymousClass.getName(), sourceFile, importedTypes, packageDoc, comments, javaFileContent);
}
}
distributeComments(comments, locationInfo, anonymousClass.getComments());
return anonymousClass;
}
private void insertNode(AnonymousClassDeclaration childAnonymous, DefaultMutableTreeNode root) {
Enumeration enumeration = root.postorderEnumeration();
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(childAnonymous);
DefaultMutableTreeNode parentNode = root;
while(enumeration.hasMoreElements()) {
DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode)enumeration.nextElement();
AnonymousClassDeclaration currentAnonymous = (AnonymousClassDeclaration)currentNode.getUserObject();
if(currentAnonymous != null && isParent(childAnonymous, currentAnonymous)) {
parentNode = currentNode;
break;
}
}
parentNode.add(childNode);
}
private String getMethodNamePath(TypeDeclarationStatement statement) {
String name = "";
ASTNode parent = statement.getParent();
while(parent != null) {
if(parent instanceof MethodDeclaration) {
String methodName = ((MethodDeclaration)parent).getName().getIdentifier();
if(name.isEmpty()) {
name = methodName;
}
else {
name = methodName + "." + name;
}
}
parent = parent.getParent();
}
return name;
}
private String getAnonymousCodePath(DefaultMutableTreeNode node) {
AnonymousClassDeclaration anonymous = (AnonymousClassDeclaration)node.getUserObject();
String name = "";
ASTNode parent = anonymous.getParent();
while(parent != null) {
if(parent instanceof MethodDeclaration) {
String methodName = ((MethodDeclaration)parent).getName().getIdentifier();
if(name.isEmpty()) {
name = methodName;
}
else {
name = methodName + "." + name;
}
}
else if(parent instanceof VariableDeclarationFragment &&
(parent.getParent() instanceof FieldDeclaration ||
parent.getParent() instanceof VariableDeclarationStatement)) {
String fieldName = ((VariableDeclarationFragment)parent).getName().getIdentifier();
if(name.isEmpty()) {
name = fieldName;
}
else {
name = fieldName + "." + name;
}
}
else if(parent instanceof MethodInvocation) {
String invocationName = ((MethodInvocation)parent).getName().getIdentifier();
if(name.isEmpty()) {
name = invocationName;
}
else {
name = invocationName + "." + name;
}
}
else if(parent instanceof SuperMethodInvocation) {
String invocationName = ((SuperMethodInvocation)parent).getName().getIdentifier();
if(name.isEmpty()) {
name = invocationName;
}
else {
name = invocationName + "." + name;
}
}
else if(parent instanceof ClassInstanceCreation) {
String invocationName = stringify(((ClassInstanceCreation)parent).getType());
if(name.isEmpty()) {
name = "new " + invocationName;
}
else {
name = "new " + invocationName + "." + name;
}
}
parent = parent.getParent();
}
return name.toString();
}
private String getAnonymousBinaryName(DefaultMutableTreeNode node) {
StringBuilder name = new StringBuilder();
TreeNode[] path = node.getPath();
for(int i=0; i