See More

import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.expr.FieldAccessExpr; import com.github.javaparser.ast.expr.VariableDeclarationExpr; import com.github.javaparser.ast.stmt.ReturnStmt; import com.github.javaparser.ast.type.ClassOrInterfaceType; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import java.util.*; /** * Created by karanbir on 9/28/15. */ public class UseJavaParser { //attributes of JavaParser static List classNames; static List interfaceNames; static List associationItemMap; //find association and multiplicity static List extendItemList; //save all the extend relationship static Set useInterfaceList; //find ball and socket interface static List implementInterfaceList; static List classStrUML; // string input to umlGenerator for generating UML class static List associationStrUML; // string input to umlGenerator for generating association UML static List extendStrUML; // string input to umlGenerator for generating extend relation static List interfaceStrUML; // string input to umlGenerator for generating ball and socket form of interface class AssociationItem { String startName; String endName; String attributeName; boolean ifMultiple; } class ExtendItem { String superClassName; String subClassName; } class UseInterfaceItem { String interfaceName; String useName; @Override public int hashCode() { int hashcode = 0; hashcode=interfaceName.hashCode()*20; hashcode += useName.hashCode(); return hashcode; } @Override public boolean equals(Object obj) { if (obj instanceof UseInterfaceItem) { UseInterfaceItem item = (UseInterfaceItem) obj; return (item.interfaceName.equals(this.interfaceName) && item.useName.equals(this.useName)); } else { return false; } } } class ImplementInterfaceItem { String interfaceName; String implementName; } class FieldAccessLocation { String fieldname; boolean hasGetter; boolean hasSetter; } class SetterGetterLocation { String methodName; String fieldName; boolean isSetter; boolean isGetter; } class ReturnStatement { String returnName; int lineNumber; } //1. used to save output from ClassVisitor static String nameClassVisitor; static boolean isInterfaceClassVisitor; static int modifierClassVisitor; static List extendClassVisitor; static List implementClassVisitor; //2. used to save output from MethodVisitor static List nameMethodVisitor; static List modifierMethodVisitor; static List typeMethodVisitor; static List> parameterListMethodVisitor; //3. used to save output from FieldVisitor static List nameFieldVisitor; static List modifierFieldVistor; static List typeFieldVisitor; //4. used to save output from ConstructorVisitor static List nameConstructorVisitor; static List modifierConstructorVisitor; static List> parameterListConstructorVisitor; //5. used to save inner attribute types of methods static ArrayList innerAttributeTypes ; //6. used to save field access locations static ArrayList fieldAccessVisitor; //7. used to save setter and getter method location static ArrayList setterGetterLocationVisitor; static ArrayList setGetMethodNameVisitor; static ArrayList setGetFieldNameVisitor; static ArrayList setGetIsGetVisitor; static ArrayList setGetIsSetVisitor; //8. used to save return statement static ArrayList returnStatementVisitor; UseJavaParser(){ classNames = new ArrayList(); interfaceNames = new ArrayList(); associationItemMap = new ArrayList(); extendItemList = new ArrayList(); useInterfaceList = new LinkedHashSet(); implementInterfaceList = new ArrayList(); classStrUML = new ArrayList(); associationStrUML = new ArrayList(); extendStrUML = new ArrayList(); interfaceStrUML = new ArrayList(); extendClassVisitor = new ArrayList(); implementClassVisitor = new ArrayList(); nameMethodVisitor = new ArrayList(); modifierMethodVisitor = new ArrayList(); typeMethodVisitor = new ArrayList(); parameterListMethodVisitor = new ArrayList>(); nameFieldVisitor = new ArrayList(); modifierFieldVistor = new ArrayList(); typeFieldVisitor = new ArrayList(); nameConstructorVisitor = new ArrayList(); modifierConstructorVisitor = new ArrayList(); parameterListConstructorVisitor = new ArrayList>(); innerAttributeTypes = new ArrayList(); fieldAccessVisitor = new ArrayList(); setterGetterLocationVisitor = new ArrayList(); setGetMethodNameVisitor = new ArrayList(); setGetFieldNameVisitor = new ArrayList(); setGetIsGetVisitor = new ArrayList(); setGetIsSetVisitor = new ArrayList(); returnStatementVisitor = new ArrayList(); } //1. try to visit class and interface names public static class ClassVisitor extends VoidVisitorAdapter { @Override public void visit(ClassOrInterfaceDeclaration n, Object arg) { nameClassVisitor = n.getName(); isInterfaceClassVisitor = n.isInterface(); extendClassVisitor = n.getExtends(); implementClassVisitor = n.getImplements(); modifierClassVisitor = n.getModifiers(); //print class name // System.out.println("Class name is: " + n.getName()); /* System.out.println(n.getEndLine()); if(n.isInterface()) intefaceNames.add(n.getName()); else classNames.add(n.getName()); //new ClassVisitor().visit(n.getMembers(), null); */ } } //2. try to visit method in the class public static class MethodVisitor extends VoidVisitorAdapter { @Override public void visit(MethodDeclaration n, Object arg) { modifierMethodVisitor.add(n.getModifiers()); nameMethodVisitor.add(n.getName()); typeMethodVisitor.add(n.getType().toString()); parameterListMethodVisitor.add(n.getParameters()); // check if method is getter or setter if(n.getName().toUpperCase().indexOf("SET")>=0) { for(String nameItem:nameFieldVisitor) { if(n.getName().toUpperCase().equals(("set" + nameItem).toUpperCase())) { setGetMethodNameVisitor.add(n.getName()); setGetFieldNameVisitor.add(nameItem); setGetIsGetVisitor.add(false); setGetIsSetVisitor.add(true); } } } else if(n.getName().toUpperCase().indexOf("GET")>=0) { for(String nameItem:nameFieldVisitor) { if(n.getName().toUpperCase().equals(("get"+nameItem).toUpperCase())) { setGetMethodNameVisitor.add(n.getName()); setGetFieldNameVisitor.add(nameItem); setGetIsGetVisitor.add(true); setGetIsSetVisitor.add(false); } } } } } //3. visit attribute public static class FieldVisitor extends VoidVisitorAdapter { @Override public void visit(FieldDeclaration n, Object arg) { typeFieldVisitor.add(n.getType().toString()); String varName=n.getVariables().get(0).toString(); if (varName.indexOf("=")>=0) { varName=varName.substring(0, varName.indexOf("=")); } nameFieldVisitor.add(varName); modifierFieldVistor.add(n.getModifiers()); } } //4. visit constructor public static class ConstructorVisitor extends VoidVisitorAdapter { @Override public void visit(ConstructorDeclaration n, Object arg) { modifierConstructorVisitor.add(n.getModifiers()); nameConstructorVisitor.add(n.getName()); parameterListConstructorVisitor.add(n.getParameters()); } } //5. visit inner attributes in methods public static class VariableDecVisitor extends VoidVisitorAdapter { @Override public void visit(VariableDeclarationExpr n, Object arg) { innerAttributeTypes.add(n.getType().toString()); } } /* //6. visit field access location in the code public static class FieldAccessExprVisitor extends VoidVisitorAdapter { @Override public void visit(FieldAccessExpr n, Object arg) { //System.out.println(n.getField()); // System.out.println(n.getBeginLine()); FieldAccessLocation fieldAccessLocation = (FieldAccessLocation) arg; fieldAccessLocation.fieldname = n.getField(); fieldAccessLocation.lineNumber=n.getBeginLine(); System.out.println(n.getField()); System.out.println(n.getBeginLine()); fieldAccessVisitor.add(fieldAccessLocation); } } //7. visit return type of method for getter method check public static class ReturnStmtVisitor extends VoidVisitorAdapter { @Override public void visit(ReturnStmt n, Object arg) { ReturnStatement returnStatement = (ReturnStatement) arg; returnStatement.returnName = n.getExpr().toString(); returnStatement.lineNumber = n.getBeginLine(); returnStatementVisitor.add(returnStatement); } } */ //1. create class UML & save use of interfaces & save association public void createClassStrUML() { for(SetterGetterLocation setterGetterItem:setterGetterLocationVisitor) { System.out.println(setterGetterItem.methodName+ " fieldName:"+setterGetterItem.fieldName+" getter:"+setterGetterItem.isGetter+"setter:"+setterGetterItem.isSetter); } String source = ""; if(isInterfaceClassVisitor){ source +="interface " + nameClassVisitor +" {\n"; } else { if(ModifierSet.isAbstract(modifierClassVisitor)) { source +="abstract class " + nameClassVisitor +" {\n"; } else { source +="class " + nameClassVisitor +" {\n"; } } //A. Making UML FIELD string for (String field: nameFieldVisitor) { //1. create field string of class UML int index = nameFieldVisitor.indexOf(field); // if field has associations with other classes, then it will not be printed in the class UML, but put into associationItemMap String substr1=""; if (typeFieldVisitor.get(index).indexOf('[')>=0) { substr1 += typeFieldVisitor.get(index).substring(0,typeFieldVisitor.get(index).indexOf('[')); } else if(typeFieldVisitor.get(index).contains("Collection") || typeFieldVisitor.get(index).contains("List") || typeFieldVisitor.get(index).contains("Map") || typeFieldVisitor.get(index).contains("Set")){ substr1 += typeFieldVisitor.get(index).substring(typeFieldVisitor.get(index).indexOf('<')+1,typeFieldVisitor.get(index).indexOf('>')); } if(classNames.indexOf(typeFieldVisitor.get(index))>=0 || classNames.indexOf(substr1)>=0 ||interfaceNames.indexOf(typeFieldVisitor.get(index))>=0 || interfaceNames.indexOf(substr1)>=0){ AssociationItem associationItem = new AssociationItem(); associationItem.startName=nameClassVisitor; if(substr1!="") associationItem.endName=substr1; else associationItem.endName=typeFieldVisitor.get(index); associationItem.attributeName=field; if(substr1!="") associationItem.ifMultiple=true; else associationItem.ifMultiple=false; associationItemMap.add(associationItem); } else{ String typefieldstr=""; if (typeFieldVisitor.get(index).indexOf('[')>=0) { typefieldstr += typeFieldVisitor.get(index).substring(0,typeFieldVisitor.get(index).indexOf('[')); typefieldstr += "(*)"; } else if(typeFieldVisitor.get(index).contains("Collection") || typeFieldVisitor.get(index).contains("List") || typeFieldVisitor.get(index).contains("Map") || typeFieldVisitor.get(index).contains("Set")){ typefieldstr += typeFieldVisitor.get(index).substring(typeFieldVisitor.get(index).indexOf('<')+1,typeFieldVisitor.get(index).indexOf('>')); typefieldstr += "(*)"; } else { typefieldstr +=typeFieldVisitor.get(index); } if (ModifierSet.isPublic(modifierFieldVistor.get(index))){ source += "+" + field + ":" + typefieldstr + "\n"; } else if(isFieldHasGetterSetter(field)) { source += "+" + field + ":" + typefieldstr + "\n"; } else if (ModifierSet.isPrivate(modifierFieldVistor.get(index))) { source += "-" + field + ":" + typefieldstr + "\n"; } } //2.find if any use of interface in the field type, save to useInterfaceList // for(String interfaceName:interfaceNames) { // // if (interfaceName.equals(substr1) || interfaceName.equals(typeFieldVisitor.get(index))) { // UseInterfaceItem useInterfaceItem = new UseInterfaceItem(); // useInterfaceItem.interfaceName = interfaceName; // useInterfaceItem.useName = nameClassVisitor; // // //if use is a class, added to useInterfaceList, ignore used by a interface // if(classNames.contains(nameClassVisitor)) // useInterfaceList.add(useInterfaceItem); // } // } } source += "__\n"; //B. making constructor UML String for(String methodName:nameConstructorVisitor) { int index = nameConstructorVisitor.indexOf(methodName); if (ModifierSet.isPublic(modifierConstructorVisitor.get(index))) { String parameterStr = ""; for (Parameter parameterSingle : parameterListConstructorVisitor.get(index)) { String[] parts = parameterSingle.toString().split(" "); parameterStr += parts[1] + ":" + parameterSingle.getType(); if (parameterListConstructorVisitor.get(index).indexOf(parameterSingle) + 1 != parameterListConstructorVisitor.get(index).size()) parameterStr += ","; } source += "+" + methodName + "(" + parameterStr + ")" + "\n"; } //find if any use of interface in parameters, save to useInterfaceList for (Parameter parameterSingle : parameterListConstructorVisitor.get(index)) { String substr1 = ""; String paramtertype = parameterSingle.getType().toString(); if (paramtertype.indexOf('[') >= 0) { substr1 += paramtertype.substring(0, paramtertype.indexOf('[')); } else if (paramtertype.contains("Collection") || paramtertype.contains("List") || paramtertype.contains("Map") || paramtertype.contains("Set")) { substr1 += paramtertype.substring(paramtertype.indexOf('<') + 1, paramtertype.indexOf('>')); } else substr1 += paramtertype; for (String interfaceName : interfaceNames) { if (interfaceName.equals(substr1)) { UseInterfaceItem useInterfaceItem = new UseInterfaceItem(); useInterfaceItem.interfaceName = interfaceName; useInterfaceItem.useName = nameClassVisitor; //if use is a class, added to useInterfaceList, ignore used by a interface if(classNames.contains(nameClassVisitor)) useInterfaceList.add(useInterfaceItem); } } } } //C. making method UML String for(String methodName:nameMethodVisitor) { int index = nameMethodVisitor.indexOf(methodName); if((ModifierSet.isPublic(modifierMethodVisitor.get(index)) || interfaceNames.contains(nameClassVisitor)) && !isMethodGetterSetter(methodName)) { String parameterStr=""; for(Parameter parameterSingle:parameterListMethodVisitor.get(index)) { String[] parts=parameterSingle.toString().split(" "); parameterStr += parts[1] + ":"+parameterSingle.getType(); if(parameterListMethodVisitor.get(index).indexOf(parameterSingle)+1!=parameterListMethodVisitor.get(index).size()) parameterStr +=","; } source += "+" + methodName + "("+ parameterStr +"):"+typeMethodVisitor.get(index)+"\n"; } //find if any use of interface in parameters, save to useInterfaceList for(Parameter parameterSingle:parameterListMethodVisitor.get(index)) { String substr1=""; String paramtertype = parameterSingle.getType().toString(); if(paramtertype.indexOf('[')>=0) { substr1 += paramtertype.substring(0, paramtertype.indexOf('[')); } else if(paramtertype.contains("Collection") || paramtertype.contains("List") || paramtertype.contains("Map") ||paramtertype.contains("Set") ) { substr1 += paramtertype.substring(paramtertype.indexOf('<')+1,paramtertype.indexOf('>')); } else substr1 +=paramtertype; for(String interfaceName:interfaceNames) { if (interfaceName.equals(substr1)) { UseInterfaceItem useInterfaceItem = new UseInterfaceItem(); useInterfaceItem.interfaceName = interfaceName; useInterfaceItem.useName = nameClassVisitor; //if use is a class, added to useInterfaceList, ignore used by a interface if(classNames.contains(nameClassVisitor)) useInterfaceList.add(useInterfaceItem); } } } //find if any use of interface in return type, save to useInterfaceList String substr1=""; String returntype=typeMethodVisitor.get(index); if(returntype.indexOf('[')>=0) { substr1 += returntype.substring(0, returntype.indexOf('[')); } else if(returntype.contains("Collection") || returntype.contains("List") || returntype.contains("Map") ||returntype.contains("Set") ) { substr1 += returntype.substring(returntype.indexOf('<')+1,returntype.indexOf('>')); } else substr1 +=returntype; for(String interfaceName:interfaceNames) { if (interfaceName.equals(substr1)) { UseInterfaceItem useInterfaceItem = new UseInterfaceItem(); useInterfaceItem.interfaceName = interfaceName; useInterfaceItem.useName = nameClassVisitor; //if use is a class, added to useInterfaceList, ignore use by a interface if(classNames.contains(nameClassVisitor)) useInterfaceList.add(useInterfaceItem); } } } source +="}\n"; //D. find if any use of interface inside a method for(String innervarType: innerAttributeTypes){ for(String interfaceName:interfaceNames) { if (interfaceName.equals(innervarType)) { UseInterfaceItem useInterfaceItem = new UseInterfaceItem(); useInterfaceItem.interfaceName = interfaceName; useInterfaceItem.useName = nameClassVisitor; //if use is a class, added to useInterfaceList, ignore use by a interface if(classNames.contains(nameClassVisitor)) useInterfaceList.add(useInterfaceItem); } } } classStrUML.add(source); } //2. create association UML public void createAssociationStrUML() { String source = ""; while(!associationItemMap.isEmpty()){ String class1 = associationItemMap.get(0).startName; String class2 = associationItemMap.get(0).endName; int i=0; for( ; i " +item.interfaceName + ": use\n"; } // while(!implementInterfaceList.isEmpty()){ // String interfaceName=implementInterfaceList.get(0).interfaceName; // List implementList=new ArrayList(); // List useList=new ArrayList(); // // int index = 0; // while(index 1) { // source +="mix_usecase " + usecase1 + "\n"; // source += implementList.get(0) + "-0)- " + usecase1 + ":`"+ interfaceName +"\n"; // for(String useName: useList) { // source += usecase1 + " -- " + useName + ":use\n"; // } // } // // else if(implementList.size() > 1 && useList.size()==0) { // source +="mix_usecase "+ usecase1 +"\n"; // source += interfaceName + "()- "+ usecase1 + "\n"; // for(String implementName:implementList) { // source += usecase1+" --" + implementName + "\n"; // } // } // // else if(implementList.size() > 1 && useList.size() == 1) { // source +="mix_usecase "+ usecase1 +"\n"; // source +=usecase1 + " -0)-" + useList.get(0) + ":`"+ interfaceName +"\n"; // for(String implementName:implementList) { // source += implementName + " -- "+ usecase1 +"\n"; // } // } // // else if(implementList.size() > 1 && useList.size() > 1) { // source +="mix_usecase "+ usecase1+ "\n"; // source +="mix_usecase "+ usecase2+ "\n"; // source += usecase1 + " -0)- "+ usecase2 + ":`"+ interfaceName +"\n"; // // for(String implementName:implementList) { // source += implementName + " -- "+ usecase1 +"\n"; // } // // for(String useName: useList) { // source +=usecase2 + " -- " + useName + ":use\n"; // } // } // // usecase1=usecase1+2; // usecase2=usecase2+2; // // } /* for(ImplementInterfaceItem implementItem:implementInterfaceList) { boolean used = false; for (UseInterfaceItem useItem:useInterfaceList) { if(implementItem.interfaceName.equals(useItem.interfaceName)){ source += implementItem.implementName + "-0)-" + useItem.useName+":`"+implementItem.interfaceName+"\n"; used= true; } } if(!used) { source += implementItem.interfaceName + "()-" + implementItem.implementName +"\n"; } } */ interfaceStrUML.add(source); } public void clearTempStaticClass() { nameMethodVisitor.clear(); modifierMethodVisitor.clear(); typeMethodVisitor.clear(); parameterListMethodVisitor.clear(); nameFieldVisitor.clear(); modifierFieldVistor.clear(); typeFieldVisitor.clear(); nameConstructorVisitor.clear(); modifierConstructorVisitor.clear(); parameterListConstructorVisitor.clear(); innerAttributeTypes.clear(); fieldAccessVisitor.clear(); setterGetterLocationVisitor.clear(); setGetMethodNameVisitor.clear(); setGetFieldNameVisitor.clear(); setGetIsGetVisitor.clear(); setGetIsSetVisitor.clear(); returnStatementVisitor.clear(); } public boolean isFieldHasGetterSetter (String fieldName) { boolean hasSetter=false; boolean hasGetter=false; for( int i =0; i