diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 0dbc844b6..c31501189 100644 --- a/org.hl7.fhir.convertors/pom.xml +++ b/org.hl7.fhir.convertors/pom.xml @@ -59,13 +59,6 @@ true - - - com.github.javaparser - javaparser-symbol-solver-core - 3.15.9 - - diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/Parser.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/Parser.java deleted file mode 100644 index b3e6cd24a..000000000 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/Parser.java +++ /dev/null @@ -1,1782 +0,0 @@ -package org.hl7.fhir.convertors.parser; - -import com.github.javaparser.StaticJavaParser; -import com.github.javaparser.ast.*; -import com.github.javaparser.ast.body.*; -import com.github.javaparser.ast.comments.Comment; -import com.github.javaparser.ast.expr.Expression; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.expr.NameExpr; -import com.github.javaparser.ast.nodeTypes.NodeWithIdentifier; -import com.github.javaparser.ast.nodeTypes.NodeWithName; -import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; -import com.github.javaparser.ast.nodeTypes.modifiers.NodeWithStaticModifier; -import com.github.javaparser.ast.stmt.*; -import com.github.javaparser.ast.type.Type; -import com.github.javaparser.ast.type.VarType; -import com.github.javaparser.ast.visitor.ModifierVisitor; -import com.github.javaparser.ast.visitor.Visitable; -import com.github.javaparser.ast.visitor.VoidVisitorAdapter; -import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration; -import com.github.javaparser.symbolsolver.JavaSymbolSolver; -import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver; -import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver; -import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver; -import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver; -import org.hl7.fhir.dstu3.model.Enumeration; -import org.hl7.fhir.dstu3.model.MedicationAdministration; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * TODO Line auditing function, try copying based on line numbers and based on MethodDeclr, and compare the outputs - */ -public class Parser { - - public static final String ELEMENT = "Element"; - private static final String RESOURCE_FILE_FORMAT = "_%s"; //TODO fix - private static final List VERSION_FILES = Arrays.asList("10_30", "10_40", "10_50", "14_30", "14_40", "14_50", "30_40", "30_50", "40_50"); - private static final List BASE_TYPES = Arrays.asList("Base64Binary", "Boolean", "boolean", "Canonical", "Code", - "Enumeration", "Date", "DateTime", "DateType", "Decimal", "BigDecimal", "Id", "Instant", "Integer", "int", "Integer64", - "Markdown", "Oid", "PositiveInt", "String", "Time", "UnsignedInt", "Uri", "Url", - "Uuid", "XhtmlNode"); - -// private static org.hl7.fhir.r5.model.Enumeration -// convertMedicationAdministrationStatus(org.hl7.fhir.dstu3.model.Enumeration src) { -// if (src == null) -// return null; -// org.hl7.fhir.r5.model.Enumeration tgt -// = new org.hl7.fhir.r5.model.Enumeration(); -// copyElement(src, tgt); -// tgt.setValue(org.hl7.fhir.r5.model.MedicationAdministration.MedicationAdministrationStatusCodes.fromCode(src.getValueAsString())); -// return tgt; -// } -// -// private static void copyElement(java.util.Enumeration src, -// org.hl7.fhir.r5.model.Enumeration tgt) { -// -// } - - - /** - * @param args - */ - public static void main(String[] args) { - /* - * every tgt.setX(convertT(src.getX)) should be dependent on a hasX - in principle that doesn't matter when you're - * dealing with singleton elements if convertT checks for null and setX accepts null - which *should* be the case. - * But there's enough special cases and other things that I have a lot less bugs where we always do if (src.hasX()) - */ - - List listOfPrimitiveTypes = BASE_TYPES;//getListOfPrimitiveTypes(); - - try { - initializeResolver(new File("").getAbsolutePath(), DIRECTORY_WHERE_THE_CODE_LIVES); - } catch (IOException e) { - e.printStackTrace(); - } - - System.out.println("get to version AuditEvent10_30 :: " + getModelImportToVersion("AuditEvent10_30")); - System.out.println("get from version AuditEvent10_30 :: " + getModelImportFromVersion("AuditEvent10_30")); - - -// VERSION_FILES.forEach(version -> { - String version = "30_50"; - List filenames = listAllJavaFilesInDirectory(new File("").getAbsolutePath() + "/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv" + version + "/"); - System.out.println("Checking the following files:"); - Collections.sort(filenames); - filenames.forEach(System.out::println); - filenames.forEach(name -> { - try { - modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv" + version + "/", name, ".java", listOfPrimitiveTypes, version); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - }); -// }); -// - try { -// modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv14_30/", "DataElement14_30", ".java", listOfPrimitiveTypes, "14_30"); -// modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_30/", "AuditEvent10_30", ".java", listOfPrimitiveTypes, "10_30"); -// modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_30/", "Binary10_30", ".java", listOfPrimitiveTypes, "10_30"); -// modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_30/", "Bundle10_30", ".java", listOfPrimitiveTypes, "10_30"); -// modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_30/", "ClinicalImpression10_30", ".java", listOfPrimitiveTypes, "10_30"); -// modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_30/", "Communication10_30", ".java", listOfPrimitiveTypes, "10_30"); - } catch (Exception e) { - System.out.println(); - } - System.out.println(); - } - - public static void modifyElementNotField(String srcdirectory, String filename, String extension, List listOfPrimitiveTypes, String version) throws FileNotFoundException { - System.out.println("File :: " + filename); - - String projectDirectory = new File("").getAbsolutePath(); - String srcFilePathWithExtension = projectDirectory + srcdirectory + filename + extension; - long start = System.currentTimeMillis(); - - CompilationUnit compilationUnit = getCompilationUnit(projectDirectory + srcdirectory + filename + extension); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = initializeTypeSovlerAndParser(compilationUnit, - projectDirectory, srcdirectory, filename); - - Set visited = new HashSet<>(); - - HashMap ifStatementToConditions = new HashMap<>(); - HashMap> keyWordToIfStatement = new HashMap<>(); - - final HashMap generatedBlockStmt = new HashMap<>(); - - MethodDeclaration declaration = classOrInterfaceDeclaration.getMethods().stream() - .filter(md -> md.getNameAsString().equals("convert" + extractName(filename))) - .findFirst().get(); - - String lowerVersionTypeAbsPath = getLowerVersionAbsPathFromImportStatement(declaration.getTypeAsString(), declaration.getParameter(0).getTypeAsString(), version); - String higherVersionTypeAbsPath = getHigherVersionAbsPath(declaration.getTypeAsString(), declaration.getParameter(0).getTypeAsString(), version); - - CompilationUnit lowerCU = StaticJavaParser.parse(new File(lowerVersionTypeAbsPath)); - CompilationUnit higherCU = StaticJavaParser.parse(new File(higherVersionTypeAbsPath)); - System.out.println(); - - List methods = classOrInterfaceDeclaration.getMethods(); - methods.forEach(md -> { - - String toType = importStatementToAbsolutePath(md.getType().asString()); - String fromType = importStatementToAbsolutePath(md.getParameter(0).getType().asString()); - - ClassOrInterfaceDeclaration toTypeClass = null; - ClassOrInterfaceDeclaration fromTypeClass = null; - - String lowerVersionAbsPath = getLowerVersionAbsPathFromAbsPath(toType, fromType, version); - String toString = toType.substring(toType.lastIndexOf('/') + 1, toType.lastIndexOf('.')); - - String fromString = fromType.substring(fromType.lastIndexOf('/') + 1, fromType.lastIndexOf('.')); - if (toType.equals(lowerVersionAbsPath)) { - try { - if (toString.equals(extractName(filename))) { - toTypeClass = lowerCU.getClassByName(toString).get(); - fromTypeClass = higherCU.getClassByName(fromString).get(); - } else { - Node declaration1 = getDeclaration(lowerCU, filename, toString); - if (declaration1 instanceof ClassOrInterfaceDeclaration) { - toTypeClass = (ClassOrInterfaceDeclaration) declaration1; - } else if (declaration1 instanceof EnumDeclaration) { - System.out.println("Filename " + filename + " target String " + toString + ", is an EnumDeclaration"); - } - - Node declaration2 = getDeclaration(higherCU, filename, fromString); - if (declaration2 instanceof ClassOrInterfaceDeclaration) { - fromTypeClass = (ClassOrInterfaceDeclaration) declaration2; - } else if (declaration2 instanceof EnumDeclaration) { - System.out.println("Filename " + filename + " target String " + toString + ", is an EnumDeclaration"); - } - } - } catch (Exception e) { - System.out.println(); - } - } else { - try { - if (toString.equals(extractName(filename))) { - toTypeClass = higherCU.getClassByName(toString).get(); - fromTypeClass = lowerCU.getClassByName(fromString).get(); - } else { - Node declaration1 = getDeclaration(higherCU, filename, toString); - if (declaration1 instanceof ClassOrInterfaceDeclaration) { - toTypeClass = (ClassOrInterfaceDeclaration) declaration1; - } else if (declaration1 instanceof EnumDeclaration) { - System.out.println("Filename " + filename + " target String " + toString + ", is an EnumDeclaration"); - } - Node declaration2 = getDeclaration(lowerCU, filename, fromString); - if (declaration2 instanceof ClassOrInterfaceDeclaration) { - fromTypeClass = (ClassOrInterfaceDeclaration) declaration2; - } else if (declaration2 instanceof EnumDeclaration) { - System.out.println("Filename " + filename + " target String " + toString + ", is an EnumDeclaration"); - } - } - } catch (Exception e) { - System.out.println(); - } - } - - if (toTypeClass != null && fromTypeClass != null) { - ClassOrInterfaceDeclaration finalFromTypeClass = fromTypeClass; - ClassOrInterfaceDeclaration finalToTypeClass = toTypeClass; - md.accept(new ModifierVisitor() { - @Override - public Visitable visit(MethodCallExpr n, Void arg) { - super.visit(n, arg); - - if (n.getNameAsString().contains("get") && !visited.contains(n.getNameAsString())) { - visited.add(n.getNameAsString()); - - Optional first = finalFromTypeClass.getMethods().stream() - .filter(md -> md.getNameAsString().equals(n.getNameAsString())) - .findFirst(); - - if (first.isPresent()) { - - Node topLevelMethodExpr = getTopLevelMethodExpr(n); - Node topLevelIfStatement = getTopLevelIfStatement(n); - - String type = first.get().getType().toString(); - - String baseString = n.getNameAsString().replace("get", ""); - - if (listOfPrimitiveTypes.contains(type)) { - ElementParserEntry e = new ElementParserEntry(); - // do get - Optional firstGetElementMethod = finalFromTypeClass.getMethods().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals("get" + baseString + ELEMENT)) - .findFirst(); - if (firstGetElementMethod.isPresent()) { - e.setGetType(firstGetElementMethod.get().getType().toString()); - } else { - finalFromTypeClass.getMethods().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals("get" + baseString)) - .findFirst().ifPresent(md -> e.setGetType(md.getType().toString())); - } - - // do set and add - Optional firstSetElementMethod = finalToTypeClass.getMethods().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals("set" + baseString + ELEMENT)) - .findFirst(); - if (firstSetElementMethod.isPresent()) { - e.setSetType(firstSetElementMethod.get().getParameter(0).getType().toString()); - } else { - finalToTypeClass.getMethods().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals("set" + baseString)) - .findFirst().ifPresent(md -> e.setSetType(md.getParameter(0).getType().toString())); - } - - Optional firstAddElementMethod = finalToTypeClass.getMethods().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals("add" + baseString + ELEMENT)) - .findFirst(); - if (firstAddElementMethod.isPresent()) { - e.setAddType(firstAddElementMethod.get().getType().toString()); - } else { - finalToTypeClass.getMethods().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals("add" + baseString + ELEMENT)) - .findFirst().ifPresent(md -> e.setAddType(md.getType().toString())); - } - - // do check - if (topLevelIfStatement != null && (((IfStmt) topLevelIfStatement).getCondition() instanceof MethodCallExpr)) { - String nameAsString = ((MethodCallExpr) ((IfStmt) topLevelIfStatement).getCondition()).getNameAsString(); - String finalNameAsString = nameAsString; - finalFromTypeClass.getMethods().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals(finalNameAsString)) - .findFirst().ifPresent(methodDeclaration -> { - e.setHasCheck(methodDeclaration.getType().toString()); - }); - } - - ifStatementToConditions.put((IfStmt) topLevelIfStatement, e); - if (!keyWordToIfStatement.containsKey(baseString)) { - keyWordToIfStatement.put(baseString, new ArrayList<>()); - } - keyWordToIfStatement.get(baseString).add((IfStmt) topLevelIfStatement); - } - } - } - - return n; - } - }, null); - visited.clear(); - } - - String returnTypeDir = null; - try { - returnTypeDir = getDirectoryOfOppositeModel(md.getParameter(0).getTypeAsString(), version); - } catch (Exception e) { - System.out.println(); - } - - String condition = "src.has%1$sElement()"; - String statementWithSet = "tgt.set%1$sElement((%3$s%4$s) VersionConvertor_%2$s.convertType(src.get%1$sElement()));"; - - String oneToOne = "tgt.set%1$sElement((%3$s%4$s) VersionConvertor_%2$s.convertType(src.get%1$sElement()));"; - String oneToMany = "tgt.set%1$s(Collections.singletonList((%3$s%4$s) VersionConvertor_%2$s.convertType(src.get%1$sElement())));"; - String manyToOne = "tgt.set%1$sElement((%3$s%4$s) VersionConvertor_%2$s.convertType(src.get%1$s().get(0)));"; - String manyToMany = "tgt.set%1$s(src.get%1$s().stream()\n" + - ".map(toConvert -> (%3$s%4$s) VersionConvertor_%2$s.convertType(toConvert))\n" + - ".collect(Collectors.toList())\n" + - ");"; - - if (returnTypeDir != null) { - for (String s : keyWordToIfStatement.keySet()) { - for (IfStmt ifState : keyWordToIfStatement.get(s)) { - ElementParserEntry e = ifStatementToConditions.get(ifState); - String finalReturnTypeDir = returnTypeDir; - if (e.hasAdd || e.hasSet) { - md.accept(new ModifierVisitor() { - @Override - public Visitable visit(IfStmt n, Void arg) { - super.visit(n, arg); - if (n.equals(ifState)) { - String template = null; - if (e.getType.contains("List") && getToType(e).contains("List")) { - template = manyToMany; - } else if (e.getType.contains("List") && !getToType(e).contains("List")) { - template = manyToOne; - } else if (!e.getType.contains("List") && getToType(e).contains("List")) { - template = oneToMany; - } else { - template = oneToOne; - } - - e.setType = e.setType.replaceAll("List", "").replaceAll("<", "").replaceAll(">", ""); - e.addType = e.setType.replaceAll("List", "").replaceAll("<", "").replaceAll(">", ""); - - Expression conditionExp = e.hasCheck ? StaticJavaParser.parseExpression(String.format(condition, s)) : n.getCondition(); - Statement thenStatement = null; - try { - thenStatement = StaticJavaParser.parseStatement(String.format(template, s, version, finalReturnTypeDir, e.hasSet ? e.setType : e.addType)); - n = new IfStmt(conditionExp, thenStatement, null); - } catch (Exception e1) { - System.out.println(); - } - } - return n; - } - - private String getToType(ElementParserEntry e) { - if (e.hasSet) { - return e.setType; - } else { - return ""; - } - } - }, null); - } - } - } - } - }); - - deleteFile(srcFilePathWithExtension); - - try { - compilationUnit.addImport("java.util.Collections"); - writeStringToFile(compilationUnit.toString(), srcFilePathWithExtension); - } catch (IOException e) { - e.printStackTrace(); - } - - System.out.println("Execution time :: " + (System.currentTimeMillis() - start) / 1000); - - } - - public static Node getDeclaration(CompilationUnit cu, String filename, String targetNodeString) { - Optional classByName = cu.getClassByName(extractName(filename)); - Optional first = null; - if (classByName.isPresent()) { - - first = classByName.get().getChildNodes().stream() - .filter(node -> node instanceof ClassOrInterfaceDeclaration) - .filter(node -> ((ClassOrInterfaceDeclaration) node).getNameAsString().equals(targetNodeString)) - .findFirst(); - - if (!first.isPresent()) { - first = classByName.get().getChildNodes().stream() - .filter(node -> node instanceof EnumDeclaration) - .filter(node -> ((EnumDeclaration) node).getNameAsString().equals(targetNodeString)) - .findFirst(); - } - } - - if (first == null || !first.isPresent()) { - throw new IllegalStateException("No target with name " + targetNodeString + " found in file " + filename); - } else { - return first.get(); - } - } - - public static class ElementParserEntry { - - public boolean hasGet = false; - public boolean hasCheck = false; - public boolean hasSet = false; - public boolean hasAdd = false; - - public String baseNoun = ""; - - public String getType = ""; - public String checkType = ""; - public String setType = ""; - public String addType = ""; - - public void setGetType(String type) { - hasGet = true; - this.getType = type; - } - - public void setSetType(String type) { - hasSet = true; - this.setType = type; - } - - public void setHasCheck(String type) { - hasCheck = true; - this.checkType = type; - } - - public void setAddType(String type) { - hasAdd = true; - this.addType = type; - } - - public ElementParserEntry() { - } - - } - - - public static List getListOfPrimitiveTypes() { - String path = "/Users/markiantorno/Documents/Development/fhir/org.hl7.fhir.core/org.hl7.fhir.r5/src/main/java/org/hl7/fhir/r5/model/"; - - List result = new ArrayList<>(); - - try (Stream walk = Files.walk(Paths.get(path))) { - walk.map(Path::toString) - .filter(f -> f.endsWith(".java")) - .collect(Collectors.toCollection(() -> result)); - } catch (IOException e) { - e.printStackTrace(); - } - - List primitiveTypes = new ArrayList<>(); - result.forEach(filePath -> { - try { - CompilationUnit cu = StaticJavaParser.parse(new File(filePath)); - String className = pullFileNameFromPath(filePath); - cu.getClassByName(className).ifPresent(classOrInterfaceDeclaration -> { - if (classOrInterfaceDeclaration.getExtendedTypes().stream() - .map(NodeWithSimpleName::getNameAsString) - .collect(Collectors.toList()).contains("PrimitiveType")) { - primitiveTypes.add(className.replace("Type", "")); - } - }); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - }); - primitiveTypes.forEach(System.out::println); - return primitiveTypes; - } - - public static void cleanAccessorsForFile(String srcdirectory, String filename, String extension) { - String projectDirectory = new File("").getAbsolutePath(); - String srcFilePathWithExtension = projectDirectory + srcdirectory + filename + extension; - - CompilationUnit compilationUnit = getCompilationUnit(projectDirectory + srcdirectory + filename + extension); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = initializeTypeSovlerAndParser(compilationUnit, - projectDirectory, srcdirectory, filename); - - String ifStatementTemplate = "if(%1$s){%2$s;}"; - String ifStatementTemplate2 = "if(%1$s){%2$s}"; - - final HashMap replacementMap = new HashMap<>(); - final HashMap generatedBlockStmt = new HashMap<>(); - - List methods = classOrInterfaceDeclaration.getMethods(); - methods.forEach(md -> { - String assembledMethod = ""; - md.accept(new ModifierVisitor() { - @Override - public Visitable visit(MethodCallExpr n, String arg) { - super.visit(n, arg); - if (n.getTokenRange().toString().contains("src.get")) { - - Node getStatement = getRootGetMethodCall(n); - String topLevelMethodExpr = getTopLevelMethodExpr(n).toString(); - if (topLevelMethodExpr != null) { - String condition = "src.has" + getStatement.toString().replace("FirstRep", "").replaceFirst("get", "") + "()"; - - String statement = topLevelMethodExpr; - String ifStmt = String.format(statement.startsWith("for") ? ifStatementTemplate2 : ifStatementTemplate, condition, statement); - if (!replacementMap.containsKey(topLevelMethodExpr)) { - replacementMap.put(topLevelMethodExpr, ifStmt); - } - } - } - return n; - } - }, assembledMethod); - String body = md.getBody().get().toString(); - Set keySet = replacementMap.keySet(); - for (String key : keySet) { - if (key.startsWith("for")) { - body = body.replace(key, replacementMap.get(key)); - } else { - body = body.replace(key + ";", replacementMap.get(key)); - } - } - replacementMap.clear(); - try { - generatedBlockStmt.put(md, StaticJavaParser.parseBlock(body)); - } catch (Exception e) { - System.out.println(); - } - }); - - classOrInterfaceDeclaration.accept(new ModifierVisitor() { - @Override - public MethodDeclaration visit(MethodDeclaration md, Void arg) { - super.visit(md, arg); - if (generatedBlockStmt.containsKey(md)) { - return md.setBody(generatedBlockStmt.get(md)); - } else { - return md; - } - } - }, null); - - deleteFile(srcFilePathWithExtension); - - try { - writeStringToFile(compilationUnit.toString(), srcFilePathWithExtension); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private static Node getRootGetMethodCall(Node n) { - if (n.getChildNodes().size() == 0) return n; - - Optional get = n.getChildNodes().stream() - .filter(node -> node.toString().contains("get")) - .findFirst(); - - return get.map(Parser::getRootGetMethodCall).orElse(null); - } - - private static Node getTopLevelMethodExpr(Node exp) { - Optional node = exp.getParentNode(); - if (node.isPresent() && node.get() instanceof ExpressionStmt && node.get().getParentNode().get() instanceof IfStmt) { - return null; - } else if ((node.isPresent()) && ((node.get() instanceof MethodCallExpr) || (node.get() instanceof ForEachStmt))) { - return getTopLevelMethodExpr(node.get()); - } - return exp; - } - - private static Node getTopLevelIfStatement(Node exp) { - Optional node = exp.getParentNode(); - if (!node.isPresent() || (node.get() instanceof ClassOrInterfaceDeclaration)) { - return null; - } else if (node.get() instanceof IfStmt) { - return node.get(); - } - return getTopLevelIfStatement(node.get()); - } - - // ================== OLD CODE ====================== - - - private static final String COMMON_FILENAME = "Common"; - private static final String DEST_DIRECTORY_FORMAT = "conv%s"; - private static final String SRC_FILE_FORMAT = "VersionConvertor_%s"; - - private static final String KEYWORD_CONVERT = "convert"; - private static final String KEYWORD_COPY = "copy"; - private static final String KEYWORD_FIND = "find"; - private static final String KEYWORD_GOD_METHOD = "convertResource"; - - private static final String DIRECTORY_WHERE_THE_CODE_LIVES = "/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/"; - private static final String COMMENT_REPORT = "comment_report%s.txt"; - - //Exception case variables - public static final String DSTU = "dstu"; - public static final String R = "r"; - - public static final String MODEL_RESOURCE = "org.hl7.fhir.%1$s%2$s.model.Resource"; - public static final String MODEL_VALUESET = "org.hl7.fhir.%1$s%2$s.model.ValueSet"; - public static final String MODEL_BUNDLECOMP = "org.hl7.fhir.%1$s%2$s.model.Bundle.BundleEntryComponent"; - public static final String MODEL_BUNDLE = "org.hl7.fhir.%1$s%2$s.model.Bundle"; - public static final String VERSION_CONVERTOR_IMPORT = "org.hl7.fhir.convertors.VersionConvertorAdvisor%s0"; - public static final String VERSION_CONVERTOR = "VersionConvertorAdvisor%s0"; - public static final String ADVISOR_VARIABLE = "advisor"; - - public static String convertPath(String path, String version) { - String versionloc = (version.equals("2") || version.equals("3")) ? DSTU : R; - return String.format(path, versionloc, version); - } - - public static void parseAllTheCodes() { - String projectDirectory = new File("").getAbsolutePath(); - - VERSION_FILES.forEach(version -> { - - String srcFilePathWithExtension = projectDirectory + DIRECTORY_WHERE_THE_CODE_LIVES + String.format(SRC_FILE_FORMAT, version) + ".java"; - String destDirectoryName = String.format(DEST_DIRECTORY_FORMAT, version); - - CompilationUnit compilationUnit = getCompilationUnit(srcFilePathWithExtension); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration - = initializeTypeSovlerAndParser(compilationUnit, projectDirectory, DIRECTORY_WHERE_THE_CODE_LIVES, String.format(SRC_FILE_FORMAT, version)); - - if (version.contains("10")) - dealWithV2ExceptionCasesPreProcessing(compilationUnit, classOrInterfaceDeclaration, version); - - List externalClassNames = getAdditionalClassDeclarations(classOrInterfaceDeclaration).stream() - .filter(c -> !c.getNameAsString().equals(classOrInterfaceDeclaration.getNameAsString())) - .map(NodeWithSimpleName::getNameAsString) - .collect(Collectors.toList()); - - HashMap> generatedTopLevelMethodMap = generateMapOfTopLevelMethods(classOrInterfaceDeclaration); - HashMap generatedMethodMap = new HashMap<>(); - HashMap> generatedStaticFieldMappings = new HashMap<>(); - populateMethodAndFieldMaps(classOrInterfaceDeclaration, generatedTopLevelMethodMap, generatedMethodMap, generatedStaticFieldMappings); - - if (version.equals("10_40") || version.equals("10_50")) { - generatedMethodMap.keySet().stream() - .filter(methodDeclaration -> methodDeclaration.getNameAsString().equals("hasConcept")) - .collect(Collectors.toList()) - .forEach(methodDeclaration -> { - generatedMethodMap.put(methodDeclaration, COMMON_FILENAME); - }); - } - - populateClassMappings(generatedTopLevelMethodMap, generatedMethodMap); - - createCommentReport(srcFilePathWithExtension, - projectDirectory + DIRECTORY_WHERE_THE_CODE_LIVES + String.format(COMMENT_REPORT, version)); - - modifySourceFile(compilationUnit, classOrInterfaceDeclaration, srcFilePathWithExtension, - generatedTopLevelMethodMap, generatedStaticFieldMappings, version); - - String packageDeclaration = compilationUnit.getPackageDeclaration().get().getNameAsString() + "." - + destDirectoryName; - System.out.println("Files will be generated with the package :: " + packageDeclaration); - NodeList imports = compilationUnit.getImports(); - System.out.println("Imports will be taken from the top level file <" + String.format(SRC_FILE_FORMAT, version) + ".java>, you will have to " + - "optimize imports on the generated files. Import list as follows :: \n-----"); - imports.stream().map(NodeWithName::getNameAsString).forEach(System.out::println); - System.out.println("-----\n"); - String directoryPath = projectDirectory + DIRECTORY_WHERE_THE_CODE_LIVES + destDirectoryName + "/"; - createDirectory(directoryPath); - System.out.println("Generated type conversion files will be stored in :: " + directoryPath); - - createJavaFiles(classOrInterfaceDeclaration, generatedTopLevelMethodMap, generatedStaticFieldMappings, - String.format(SRC_FILE_FORMAT, version), packageDeclaration, imports, directoryPath, externalClassNames, version); - }); - - - } - - private static List getAdditionalClassDeclarations(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) { - List collect = new ArrayList<>(); - classOrInterfaceDeclaration.accept(new VoidVisitorAdapter() { - @Override - public void visit(ClassOrInterfaceDeclaration n, Void arg) { - super.visit(n, arg); - collect.add(n); - } - }, null); - return collect; - } - - private static CompilationUnit getCompilationUnit(String filePathWithExtension) { - Optional compilationUnit = initializeParser(filePathWithExtension); - if (!compilationUnit.isPresent()) { - System.out.println("\nNo compilation unit generated during class parsing...aborting."); - System.exit(0); - } - return compilationUnit.get(); - } - - private static ClassOrInterfaceDeclaration initializeTypeSovlerAndParser(CompilationUnit compilationUnit, - String projectDirectory, - String codeDirectory, - String filename) { -// System.out.println("==================== Initializing TypeSolver and Parser ====================\n"); - - try { - initializeResolver(projectDirectory, codeDirectory); - } catch (IOException e) { - System.out.println("Error initializing typesolver, exiting process..."); - e.printStackTrace(); - System.exit(0); - } - -// System.out.println("Loading class: " + filename); - Optional classOrInterfaceDeclaration = loadClass(compilationUnit, filename); - if (!classOrInterfaceDeclaration.isPresent()) { - System.out.println("\nNo class or interface declaration loaded during parsing...aborting."); - System.exit(0); - } - -// System.out.println("\n"); - - return classOrInterfaceDeclaration.get(); - } - - private static HashMap> generateMapOfTopLevelMethods(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) { - System.out.println("==================== Generating List of Parsable Types ====================\n"); - - HashMap> mapToReturn = new HashMap<>(); - - System.out.println("Fetching list of top level parsing methods..."); - System.out.println("---------------------------------------------"); - List listOfParsableMethodCalls = getListOfParsableTypes(classOrInterfaceDeclaration).stream() - .map(methodCallExpr -> methodCallExpr.getName().toString()) - .sorted(Comparator.comparing(Function.identity())) - .distinct() - .collect(Collectors.toList()); - listOfParsableMethodCalls.forEach(System.out::println); - System.out.println("---------------------------------------------"); - System.out.println("\n"); - - System.out.println("==================== Generate Map of Top Level Method Names ====================\n"); - System.out.println("Pulling all top level methods from the parsed class --> " + classOrInterfaceDeclaration.getNameAsString()); - List topLevelMethods = getTopLevelMethods(classOrInterfaceDeclaration, listOfParsableMethodCalls); - System.out.println("\nFetched the following top level methods:"); - System.out.println("------------------------------------------"); - topLevelMethods.forEach(md -> System.out.println(md.getSignature().toString())); - System.out.println("------------------------------------------\n"); - System.out.println("\n"); - - for (String type : listOfParsableMethodCalls) { - topLevelMethods.stream() - .filter(methodDeclaration -> type.equals(methodDeclaration.getName().asString())) - .forEach(md -> { - if (!mapToReturn.containsKey(type.replaceFirst(KEYWORD_CONVERT, ""))) { - mapToReturn.put(type.replaceFirst(KEYWORD_CONVERT, ""), new ArrayList<>()); - } - mapToReturn.get(type.replaceFirst(KEYWORD_CONVERT, "")).add(md); - }); - } - return mapToReturn; - } - - public static void populateMethodAndFieldMaps(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, - HashMap> generatedTopLevelMethodMap, - HashMap methodMapToPopulate, - HashMap> fieldMapToPopulate) { - - System.out.println("==================== Generate Method and Field Maps ====================\n"); - - HashMap fieldDeclarationMap = new HashMap<>(); - - List fieldDeclarations = classOrInterfaceDeclaration.getFields().stream() - .filter(NodeWithStaticModifier::isStatic) - .collect(Collectors.toList()); - - for (String key : generatedTopLevelMethodMap.keySet()) { - for (MethodDeclaration md : generatedTopLevelMethodMap.get(key)) { - recursiveSearchAndAdd(classOrInterfaceDeclaration, methodMapToPopulate, fieldDeclarationMap, fieldDeclarations, md, key); - } - } - - fieldDeclarationMap.keySet().forEach(key -> { - if (!fieldMapToPopulate.containsKey(fieldDeclarationMap.get(key))) { - fieldMapToPopulate.put(fieldDeclarationMap.get(key), new ArrayList<>()); - } - fieldMapToPopulate.get(fieldDeclarationMap.get(key)).add(key); - }); - } - - public static void populateClassMappings(HashMap> generatedTopLevelMethodMap, - HashMap generatedMethodMap) { - System.out.println("==================== Generate Method to Class Mappings ====================\n"); - - generatedTopLevelMethodMap.put(COMMON_FILENAME, new ArrayList<>()); - generatedTopLevelMethodMap.clear(); - generatedMethodMap.keySet().forEach(md -> { - if (!generatedTopLevelMethodMap.containsKey(generatedMethodMap.get(md))) { - generatedTopLevelMethodMap.put(generatedMethodMap.get(md), new ArrayList<>()); - } - generatedTopLevelMethodMap.get(generatedMethodMap.get(md)).add(md); - }); - - for (String className : generatedTopLevelMethodMap.keySet()) { - System.out.println("Class :: " + className); - generatedTopLevelMethodMap.get(className).stream() - .sorted(Comparator.comparing(methodDeclaration -> methodDeclaration.getName().toString())) - .forEach(md -> System.out.println("\t" + md.getSignature())); - System.out.println("\n"); - } - } - - public static void createCommentReport(String fullSrcFilePath, String fullDstFilePath) { - try { - List commentReportEntries = generateCommentReportData(fullSrcFilePath); - String report = commentReportEntries.stream() - .map(Object::toString).collect(Collectors.joining("\n")); - writeStringToFile(report, fullDstFilePath); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static void dealWithV2ExceptionCasesPreProcessing(CompilationUnit cu, ClassOrInterfaceDeclaration classOrInterfaceDeclaration, String version) { - String from = "2";//version.substring(0, version.indexOf('_')); - String to = version.substring(version.indexOf('_') + 1, version.indexOf('_') + 2); - - - modifyConvertResourceCalls(classOrInterfaceDeclaration, to, from, to, MODEL_VALUESET, "convertValueSet"); - modifyConvertResourceCalls(classOrInterfaceDeclaration, from, to, to, MODEL_VALUESET, "convertValueSet"); - modifyConvertResourceCalls(classOrInterfaceDeclaration, to, from, to, MODEL_BUNDLECOMP, "convertBundleEntryComponent"); - modifyConvertResourceCalls(classOrInterfaceDeclaration, to, from, to, MODEL_BUNDLE, "convertBundle"); - - addAdvisorToMethodCalls(classOrInterfaceDeclaration, "convertBundle", MODEL_BUNDLE, from, "convertBundleEntryComponent"); - - } - - public static void dealWithV2ExceptionCasesPostProcessing(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, String version) { - String from = "2";//version.substring(0, version.indexOf('_')); - String to = version.substring(version.indexOf('_') + 1, version.indexOf('_') + 2); - - Optional advisorOptional = classOrInterfaceDeclaration.getFields().stream() - .map(FieldDeclaration::getVariables) - .flatMap(Collection::stream) - .filter(v -> v.getNameAsString().equals(ADVISOR_VARIABLE)) - .findFirst(); - - if (advisorOptional.isPresent()) { - VariableDeclarator advisorVariable = advisorOptional.get(); - Type advisorType = advisorVariable.getType(); - advisorOptional.get().getParentNode().ifPresent(Node::remove); - - modifyConvertResourceCalls(classOrInterfaceDeclaration, from, to, to, MODEL_RESOURCE, "convertResource"); - modifyConvertResourceCalls(classOrInterfaceDeclaration, to, from, to, MODEL_RESOURCE, "convertResource"); - - addAdvisorToMethodCalls(classOrInterfaceDeclaration, "convertResource", MODEL_RESOURCE, from, "convertBundle"); - addAdvisorToMethodCalls(classOrInterfaceDeclaration, "convertResource", MODEL_RESOURCE, from, "convertValueSet"); - addAdvisorToMethodCalls(classOrInterfaceDeclaration, "convertResource", MODEL_RESOURCE, to, "convertValueSet"); - - classOrInterfaceDeclaration.getConstructors().forEach(Node::remove); - - System.out.println(); -// classOrInterfaceDeclaration.addMethod(); - - } - - System.out.println(); - } - - public static void modifyConvertResourceCalls(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, - String parameterVersionNo, - String typeVersionNo, - String convertorVersionNumber, - String typeFormat, - String methodName) { - MethodDeclaration oldConvertResource = getConvertResourceMethodForVersion(classOrInterfaceDeclaration, methodName, typeFormat, typeVersionNo); - oldConvertResource.addParameter(String.format(VERSION_CONVERTOR, convertorVersionNumber), ADVISOR_VARIABLE); - - MethodDeclaration newConvertResource = classOrInterfaceDeclaration.addMethod(methodName); - newConvertResource.setModifier(Modifier.Keyword.PUBLIC, true); - newConvertResource.setModifier(Modifier.Keyword.STATIC, true); - newConvertResource.setType(convertPath(typeFormat, typeVersionNo)); - newConvertResource.setThrownExceptions(oldConvertResource.getThrownExceptions()); - newConvertResource.addParameter(convertPath(typeFormat, parameterVersionNo), "src"); - newConvertResource.setBody(new BlockStmt().addStatement("return " + methodName + "(src, null);")); - } - - public static void addAdvisorToMethodCalls(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, - String parentMethodName, - String modelType, - String version, - String subMethodCall) { - - Optional methodDeclaration = classOrInterfaceDeclaration.getMethods().stream() - .filter(md -> md.getNameAsString().equals(parentMethodName)) - .filter(md -> md.getType().toString().equals(convertPath(modelType, version))) - .findAny(); - - methodDeclaration.ifPresent(declaration -> declaration.accept(new ModifierVisitor() { - @Override - public Visitable visit(MethodCallExpr n, Void arg) { - super.visit(n, arg); - if (n.getNameAsString().contains(subMethodCall)) { - n.addArgument("advisor"); - } - return n; - } - }, null)); - - } - - public static MethodDeclaration getConvertResourceMethodForVersion(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, - String methodName, - String modelType, - String version) { - Optional methodDeclaration = classOrInterfaceDeclaration.getMethods().stream() - .filter(md -> md.getNameAsString().equals(methodName)) - .filter(md -> md.getType().toString().equals(convertPath(modelType, version))) - .findAny(); - - if (methodDeclaration.isPresent()) { - return methodDeclaration.get(); - } else { - System.out.println("Cannot find method " + methodName + " that returns type " + convertPath(modelType, version)); - System.exit(0); - } - return null; - } - - public static void modifySourceFile(CompilationUnit compilationUnit, - ClassOrInterfaceDeclaration classOrInterfaceDeclaration, - String srcFilePathWithExtension, - HashMap> generatedTopLevelMethodMap, - HashMap> generatedStaticFieldMappings, - String version) { - - - List listOfParsableMethodCalls = getListOfParsableTypes(classOrInterfaceDeclaration).stream() - .map(methodCallExpr -> methodCallExpr.getName().toString()) - .sorted(Comparator.comparing(Function.identity())) - .distinct() - .collect(Collectors.toList()); - - modifyMainFile(compilationUnit, - classOrInterfaceDeclaration, - generatedTopLevelMethodMap.get(COMMON_FILENAME), - generatedTopLevelMethodMap.keySet().stream() - .filter(key -> !key.equals(COMMON_FILENAME)) - .map(generatedTopLevelMethodMap::get) - .flatMap(Collection::stream) - .collect(Collectors.toList()), - listOfParsableMethodCalls, - generatedStaticFieldMappings.keySet().stream() - .filter(key -> !key.equals(COMMON_FILENAME)) - .map(generatedStaticFieldMappings::get) - .flatMap(Collection::stream) - .collect(Collectors.toList()), - generatedStaticFieldMappings.keySet().stream() - .filter(key -> key.equals(COMMON_FILENAME)) - .map(generatedStaticFieldMappings::get) - .flatMap(Collection::stream) - .collect(Collectors.toList()), - version); - - deleteFile(srcFilePathWithExtension); - - try { - writeStringToFile(compilationUnit.toString(), srcFilePathWithExtension); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static void modifyMainFile(CompilationUnit compilationUnit, - ClassOrInterfaceDeclaration classOrInterfaceDeclaration, - List methodsToExpose, - List methodsToDelete, - List methodsToAddStaticAccess, - List fieldsToDelete, - List fieldsToExpose, - String versionCode) { - - compilationUnit.getAllContainedComments().stream() - .filter(Comment::isLineComment) - .forEach(Comment::remove); - - compilationUnit.accept(new MethodDeleter(methodsToDelete), null); - compilationUnit.accept(new MethodExposer(methodsToExpose), null); - - compilationUnit.addImport("org.hl7.fhir.convertors." + String.format(DEST_DIRECTORY_FORMAT, versionCode), false, true); - - fieldsToDelete.forEach(classOrInterfaceDeclaration::remove); - classOrInterfaceDeclaration.getFields().stream() - .filter(NodeWithStaticModifier::isStatic) - .filter(fieldsToExpose::contains) - .forEach(fd -> { - fd.setModifier(Modifier.Keyword.PRIVATE, false); - fd.setModifier(Modifier.Keyword.PUBLIC, true); - }); - - List listOfClassMethods = getListOfClassMethods(KEYWORD_GOD_METHOD, classOrInterfaceDeclaration); - listOfClassMethods.forEach(md -> { - md.accept(new MethodStaticCallAdder(methodsToAddStaticAccess, versionCode), null); - }); - - //Deal with the old, non static access convertors (1-3, 1-4, 1-5) - compilationUnit.accept(new ModifierVisitor() { - @Override - public MethodDeclaration visit(MethodDeclaration md, Void arg) { - super.visit(md, arg); - - md.setModifier(Modifier.Keyword.PRIVATE, false); - md.setModifier(Modifier.Keyword.STATIC, true); - md.setModifier(Modifier.Keyword.PUBLIC, true); - - return md; - } - }, null); - - classOrInterfaceDeclaration.accept(new ModifierVisitor() { - @Override - public ClassOrInterfaceDeclaration visit(ClassOrInterfaceDeclaration n, Void arg) { - super.visit(n, arg); - if (!n.getNameAsString().equals(String.format(SRC_FILE_FORMAT, versionCode))) { - n.setModifier(Modifier.Keyword.PRIVATE, false); - n.setModifier(Modifier.Keyword.STATIC, true); - n.setModifier(Modifier.Keyword.PUBLIC, true); - n.accept(new ModifierVisitor() { - @Override - public FieldDeclaration visit(FieldDeclaration md, Void arg) { - super.visit(md, arg); - md.setModifier(Modifier.Keyword.PRIVATE, false); - md.setModifier(Modifier.Keyword.STATIC, false); - md.setModifier(Modifier.Keyword.PUBLIC, true); - return md; - } - }, null); - } - return n; - } - }, null); - - if (versionCode.contains("10")) dealWithV2ExceptionCasesPostProcessing(classOrInterfaceDeclaration, versionCode); - - } - - public static void createJavaFiles(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, - HashMap> generatedTopLevelMethodMap, - HashMap> generatedStaticFieldMappings, - String filename, - String packageDeclaration, - NodeList imports, - String outputDirectoryPath, - List externalClassNames, - String version) { - System.out.println("==================== Create Java Files ====================\n"); - - generatedTopLevelMethodMap.keySet().stream() - .filter(s -> !s.equals(COMMON_FILENAME)) - .forEach(s -> { - String generatedCode = generateFileContents(classOrInterfaceDeclaration, - filename, - s + version, - packageDeclaration, - imports, - generatedStaticFieldMappings.get(s), - generatedStaticFieldMappings.get(COMMON_FILENAME), - generatedTopLevelMethodMap.get(s).stream() - .sorted(Comparator.comparing(methodDeclaration -> methodDeclaration.getName().toString())) - .collect(Collectors.toList()), - externalClassNames, - version); - - try { - String filePath = outputDirectoryPath + s + version + ".java"; - System.out.println("Attempting to write file -> " + filePath); - writeStringToFile(generatedCode, filePath); - } catch (IOException e) { - e.printStackTrace(); - } - }); - } - - public static void writeStringToFile(String string, String filepath) throws IOException { - BufferedWriter writer = new BufferedWriter(new FileWriter(filepath)); - writer.write(string); - writer.close(); - } - - public static String generateFileContents(ClassOrInterfaceDeclaration oldInterfaceDec, - String commonMethodClassName, - String className, - String packageDeclaration, - NodeList imports, - List fieldDeclarations, - List externalFieldDeclarations, - List methods, - List externalClassNames, - String version) { - - CompilationUnit cu = new CompilationUnit(); - - - cu.setPackageDeclaration(packageDeclaration); - cu.setImports(imports); - cu.addImport("org.hl7.fhir.convertors." + String.format(SRC_FILE_FORMAT, version)); - cu.addImport("org.hl7.fhir.convertors.VersionConvertorConstants"); - if (version.contains("10")) - cu.addImport(String.format(VERSION_CONVERTOR_IMPORT, version.substring(version.indexOf('_') + 1, version.indexOf('_') + 2))); - - ClassOrInterfaceDeclaration generatedClass = cu.addClass(className); - if (fieldDeclarations != null) { - fieldDeclarations.forEach(generatedClass::addMember); - } - - methods.forEach(method -> { - - MethodDeclaration methodDeclaration = generatedClass.addMethod(method.getNameAsString()); - - if (method.getBody().isPresent()) { - BlockStmt blockStmt = method.getBody().get(); - if (externalFieldDeclarations != null) { - blockStmt.accept(new VarAccessChanger(externalFieldDeclarations.stream() - .map(fd -> fd.getVariable(0).getNameAsString()) - .collect(Collectors.toList()), String.format(SRC_FILE_FORMAT, version)), null); - } - List allCalledMethods = getAllCalledMethods(oldInterfaceDec, method); - - allCalledMethods.stream() - .filter(md -> !methods.contains(md)) - .map(NodeWithSimpleName::getNameAsString) - .distinct() - .forEach(methodName -> { - List methodCallExprs = new ArrayList<>(); - blockStmt.accept(new MethodCallVisitor(methodName, true), methodCallExprs); - methodCallExprs.stream() - .distinct() - .forEach(methodCallExpr -> { - methodCallExpr.setName(commonMethodClassName + "." + methodCallExpr.getNameAsString()); - }); - }); - methodDeclaration.setBody(blockStmt); - - } - - methodDeclaration.setParameters(method.getParameters()); - methodDeclaration.setModifiers(method.getModifiers()); - methodDeclaration.addModifier(Modifier.Keyword.STATIC); - methodDeclaration.setModifier(Modifier.Keyword.PRIVATE, false); - methodDeclaration.setModifier(Modifier.Keyword.PUBLIC, true); - methodDeclaration.setThrownExceptions(method.getThrownExceptions()); - methodDeclaration.setType(method.getType()); - methodDeclaration.setTypeParameters(method.getTypeParameters()); - }); - - - generatedClass.walk(node -> { - String identifier = ""; - if (node instanceof NodeWithIdentifier) - if (externalClassNames.contains(((NodeWithIdentifier) node).getIdentifier())) { - ((NodeWithIdentifier) node).setIdentifier(String.format(SRC_FILE_FORMAT, version) + "." + ((NodeWithIdentifier) node).getIdentifier()); - } - }); - - return cu.toString(); - } - - public static Predicate distinctByKey(Function keyExtractor) { - Set seen = ConcurrentHashMap.newKeySet(); - return t -> seen.add(keyExtractor.apply(t)); - } - - private static void recursiveSearchAndAdd(ClassOrInterfaceDeclaration cd, - HashMap methodDeclarationMap, - HashMap fieldDeclarationMap, - List globalStaticFields, - MethodDeclaration key, - String value) { - if (methodDeclarationMap.containsKey(key) && (methodDeclarationMap.get(key).equals(COMMON_FILENAME) || methodDeclarationMap.get(key).equals(value))) - return; - if (key.getName().toString().equals("convertResource")) return; - - addMethodDeclarationToMap(methodDeclarationMap, value, key); - searchAndSortMethodFields(key, value, fieldDeclarationMap, globalStaticFields); - - getAllCalledMethods(cd, key).forEach(md -> { - recursiveSearchAndAdd(cd, methodDeclarationMap, fieldDeclarationMap, globalStaticFields, md, value); - }); - - } - - private static void searchAndSortMethodFields(MethodDeclaration md, - String classKey, - HashMap fieldToClassMap, - List fieldDeclarations) { - - List collector = new ArrayList<>(); - md.accept(new MethodFieldVisitor(), collector); - - md.accept(new VoidVisitorAdapter() { - @Override - public void visit(VarType n, Void arg) { - super.visit(n, arg); - } - }, null); - - List staticFieldLabels = fieldDeclarations.stream() - .map(fd -> fd.getVariable(0).getName().asString()) - .collect(Collectors.toList()); - - collector.stream() - .filter(ne -> staticFieldLabels.contains(ne.getNameAsString())) - .map(ne -> fieldDeclarations.stream() - .filter(fd -> fd.getVariable(0).getName().asString().equals(ne.getNameAsString())) - .findFirst() - .get()) - .forEach(fd -> { - if (!fieldToClassMap.containsKey(fd)) { - fieldToClassMap.put(fd, classKey); - } else if (!fieldToClassMap.get(fd).equals(classKey)) { - fieldToClassMap.put(fd, COMMON_FILENAME); - } - }); - } - - - private static void createDirectory(String path) { - File file = new File(path); - //Creating the directory - boolean bool = file.mkdir(); - if (bool) { - System.out.println("Directory created successfully"); - } else { - System.out.println("Sorry couldn’t create specified directory"); - } - } - - /** - * Attempts to delete the file at the given path.) - * - * @param path - */ - public static void deleteFile(String path) { - File file = new File(path); - if (file.delete()) { - System.out.println("File <" + path + "> deleted successfully"); - } else { - System.out.println("Failed to delete the file <" + path + ">"); - } - } - - /** - * Finds the god method in the given convertor, and parses out all the method calls that method makes. - * - * @param classOrInterfaceDeclaration - * @return - */ - protected static List getListOfParsableTypes(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) { - List listOfClassMethods = getListOfClassMethods(KEYWORD_GOD_METHOD, classOrInterfaceDeclaration); - List calledMethods = new ArrayList<>(); - listOfClassMethods.forEach(md -> md.accept(new MethodCallVisitor(KEYWORD_CONVERT), calledMethods)); - return calledMethods; - } - - /** - * Pulls all internal conversion method calls out of the passed in method and maps those calls to the corresponding - * {@link MethodDeclaration} and returns those as a list. - * - * @param classOrInterfaceDeclaration - * @param method - * @return List of all {@link MethodDeclaration} - */ - public static List getAllCalledMethods(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, MethodDeclaration method) { - List result = new ArrayList<>(); - - List methodCallExprs = new ArrayList<>(); - method.accept(new VoidVisitorAdapter>() { - @Override - public void visit(MethodCallExpr methodCallExpr, List collector) { - collector.add(methodCallExpr); - super.visit(methodCallExpr, collector); - } - }, methodCallExprs); - - Set methodExpressionNames = methodCallExprs.stream() - .filter(methodCallExpr -> !methodCallExpr.getScope().isPresent()) - .map(me -> me.getName().toString()) - .collect(Collectors.toSet()); - - classOrInterfaceDeclaration.getMethods().stream() - .filter(e -> methodExpressionNames.contains(e.getName().toString())) - .collect(Collectors.toCollection(() -> result)); - - return result; - } - - /** - * Searches the passed in {@link ClassOrInterfaceDeclaration} for any method declaration matching any of the method - * names in the passed in List. - * - * @param classOrInterfaceDeclaration {@link ClassOrInterfaceDeclaration} to search - * @param methodNames {@link List} of method names - * @return {@link List } containing any of the keywords - */ - protected static List getTopLevelMethods(ClassOrInterfaceDeclaration classOrInterfaceDeclaration, List methodNames) { - List toReturn = new ArrayList<>(); - methodNames.stream() - .map(s -> getListOfClassMethods(s, classOrInterfaceDeclaration)) - .flatMap(List::stream) - .collect(Collectors.toCollection(() -> toReturn)); - return toReturn; - } - - /** - * Searched the generated declaration map for the matching {@link MethodDeclaration}, if it already exists within the - * map and is not currently pointing the class label we pass in, it will mark it with the {@link Parser#COMMON_FILENAME} - * - * @param className {@link String} class label we want to associate the method with - * @param methodDeclaration {@link MethodDeclaration} - */ - protected static void addMethodDeclarationToMap(HashMap map, - String className, MethodDeclaration methodDeclaration) { - if (!map.containsKey(methodDeclaration)) { - map.put(methodDeclaration, className); - } else if (!map.get(methodDeclaration).equals(className)) { - map.put(methodDeclaration, COMMON_FILENAME); - } - } - - /** - * Returns a list of all java files within the passed in directory path, without extension. - * - * @param path {@link String} filepath - * @return {@link List < String >} of all filenames - */ - protected static List listAllJavaFilesInDirectory(String path) { - List result = new ArrayList<>(); - - try (Stream walk = Files.walk(Paths.get(path))) { - walk.map(Path::toString) - .filter(f -> f.endsWith(".java")) - .map(Parser::pullFileNameFromPath) - .collect(Collectors.toCollection(() -> result)); - } catch (IOException e) { - e.printStackTrace(); - } - - return result; - } - - /** - * Takes the passed in file path and extracts the filename without extension. - * - * @param path - * @return - */ - protected static String pullFileNameFromPath(String path) { - int lastSlashIndex = path.lastIndexOf('/'); - int lastPeriodIndex = path.lastIndexOf('.'); - return path.substring(lastSlashIndex + 1, lastPeriodIndex); - } - - /** - * The parser works by listing method calls within the individual resource conversion methods as - * {@link MethodCallExpr}. To extract the information we need to refactor the code, - * such as method body, references, signature, etc, we rely on the javaparser {@link TypeSolver} to parse the code - * library and convert the expressions to concrete {@link MethodDeclaration}. - *

- * NB. The more source files in the directory you pass in (this will search recursively), the longer the - * MethodDeclaration lookups will take. Be smart, choose S-Mart. - * - * @param rootProjectDirectory - * @param projectDirectory {@link String} path to the directory that contains the souce files we want to be available for - */ - public static void initializeResolver(String rootProjectDirectory, String projectDirectory) throws IOException { - System.out.println("Initializing resolver against the following root directory:\n" + rootProjectDirectory); - System.out.println("Project codebase located here:\n" + projectDirectory); - - TypeSolver myTypeSolver = new CombinedTypeSolver( - new ReflectionTypeSolver(), - new JavaParserTypeSolver(new File(rootProjectDirectory + "/org.hl7.fhir.convertors/src/main/java/")), - new JavaParserTypeSolver(new File(rootProjectDirectory + "/org.hl7.fhir.utilities/src/main/java/")), - new JavaParserTypeSolver(new File(rootProjectDirectory + "/org.hl7.fhir.dstu2/src/main/java/")), - new JavaParserTypeSolver(new File(rootProjectDirectory + "/org.hl7.fhir.dstu3/src/main/java/")), - new JavaParserTypeSolver(new File(rootProjectDirectory + "/org.hl7.fhir.dstu2016may/src/main/java/")), - new JavaParserTypeSolver(new File(rootProjectDirectory + "/org.hl7.fhir.r4/src/main/java/")), - new JavaParserTypeSolver(new File(rootProjectDirectory + "/org.hl7.fhir.r5/src/main/java/")), - new JarTypeSolver("/Users/markiantorno/.m2/repository/ca/uhn/hapi/fhir/hapi-fhir-structures-r4/4.1.0/hapi-fhir-structures-r4-4.1.0.jar"), - new JarTypeSolver("/Users/markiantorno/.m2/repository/ca/uhn/hapi/fhir/hapi-fhir-base/4.1.0/hapi-fhir-base-4.1.0.jar") - ); - - JavaSymbolSolver symbolSolver = new JavaSymbolSolver(myTypeSolver); - StaticJavaParser.getConfiguration().setSymbolResolver(symbolSolver); - } - - /** - * Initializes the parser and runs it against the file located at the passed in path. - * - * @param path {@link String} path to the file. - * @return {@link Optional } - */ - public static Optional initializeParser(String path) { - System.out.println("Initializing parser, and parsing the following file:\n" + path); - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(path)); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return Optional.ofNullable(compilationUnit); - } - - /** - * Loads a class using the {@link CompilationUnit} passed in and returns the resulting declaration for parsing. This - * class must exist within the directory parsed originally in {@link #initializeParser(String)} - * - * @param cu {@link CompilationUnit} - * @param classname {@link String} The name of the class to load. - * @return {@link Optional } for the named class. - */ - protected static Optional loadClass(CompilationUnit cu, String classname) { - return cu.getClassByName(classname); - } - - /** - * Takes a given {@link MethodCallExpr} and uses the initialized {@link JavaSymbolSolver} to search the source code - * for the appropriate {@link MethodDeclaration}. - * - * @param methodCallExpr {@link MethodCallExpr} - * @return An {@link Optional}, containing the corresponding {@link MethodDeclaration} - */ - protected static Optional resolveMethodDeclaration(MethodCallExpr methodCallExpr) { - MethodDeclaration wrappedDeclaration = null; - ResolvedMethodDeclaration correspondingDeclaration = methodCallExpr.resolve(); - - if (correspondingDeclaration instanceof JavaParserMethodDeclaration) { - JavaParserMethodDeclaration declaration = (JavaParserMethodDeclaration) correspondingDeclaration; - Node wrappedNode = declaration.getWrappedNode(); - wrappedDeclaration = (MethodDeclaration) wrappedNode; - System.out.println(); - } - - return Optional.ofNullable(wrappedDeclaration); - } - - /** - * Takes the content {@link String} passed in, and writes it to a java file with the provided name, in the provided - * directory location. - * - * @param filename Name of the file, including extension, ex: "Book.java" - * @param directory Path to directory to create the file - * @param content {@link String} content of the file - * @throws IOException - */ - public static void writeJavaCodeToFile(String filename, String directory, String content) throws IOException { - BufferedWriter writer = new BufferedWriter(new FileWriter(directory + filename)); - writer.write(content); - writer.close(); - } - - /** - * Returns the list of class methods. - * - * @param classOrInterfaceDeclaration {@link ClassOrInterfaceDeclaration} - * @return {@link List} of all {@link MethodDeclaration} - */ - protected static List getListOfClassMethods(ClassOrInterfaceDeclaration classOrInterfaceDeclaration) { - return getListOfClassMethods("", classOrInterfaceDeclaration); - } - - /** - * Returns the list of class methods containing the passed in method name. - * - * @param methodName {@link String} method name to search for - * @param classOrInterfaceDeclaration {@link ClassOrInterfaceDeclaration} - * @return {@link List} of all matching {@link MethodDeclaration} - */ - protected static List getListOfClassMethods(String methodName, ClassOrInterfaceDeclaration classOrInterfaceDeclaration) { - List result = new ArrayList<>(); - classOrInterfaceDeclaration.getMethods().stream() - .filter(method -> method.getName().toString().equals(methodName)) - .collect(Collectors.toCollection(() -> result)); - return result; - } - - private static List generateCommentReportData(String filepath) throws FileNotFoundException { - - CompilationUnit cu = StaticJavaParser.parse(new File(filepath)); - - return cu.getAllContainedComments().stream() - .filter(Comment::isOrphan) - .filter(Comment::isLineComment) - .map(p -> new CommentReportEntry(filepath.substring(filepath.lastIndexOf('/') + 1), - p.getClass().getSimpleName(), p.getContent(), p.getRange().get().begin.line, - !p.getCommentedNode().isPresent())) - .collect(Collectors.toList()); - } - - /** - * Class that visits all method calls within a given method and returns the results as a list. - */ - public static class MethodCallVisitor extends VoidVisitorAdapter> { - - private final String keyword; - private final boolean strict; - - public MethodCallVisitor(String keywords) { - super(); - this.keyword = keywords; - this.strict = false; - } - - public MethodCallVisitor(String keywords, boolean strict) { - super(); - this.keyword = keywords; - this.strict = strict; - } - - @Override - public void visit(MethodCallExpr methodCallExpr, List collector) { - if (strict) { - if (methodCallExpr.getName().asString().equals(keyword)) { - collector.add(methodCallExpr); - } - } else { - if (methodCallExpr.getName().asString().contains(keyword)) { - collector.add(methodCallExpr); - } - } - super.visit(methodCallExpr, collector); - } - } - - /** - * Class that visits all method calls within a given method and returns the results as a list. - */ - public static class MethodFieldVisitor extends VoidVisitorAdapter> { - - public MethodFieldVisitor() { - super(); - } - - @Override - public void visit(NameExpr fieldAccessExpr, List collector) { - super.visit(fieldAccessExpr, collector); - collector.add(fieldAccessExpr); - } - } - - /** - * Class that visits all method calls within a given method and returns the results as a list. - */ - public static class VarAccessChanger extends ModifierVisitor { - - private final List varsToAccessInMainFile; - private final String parentClassName; - - public VarAccessChanger(List varsToAccessInMainFile, String parentClassName) { - super(); - this.varsToAccessInMainFile = varsToAccessInMainFile; - this.parentClassName = parentClassName; - } - - @Override - public NameExpr visit(NameExpr nameExpr, Void arg) { - super.visit(nameExpr, arg); - if (varsToAccessInMainFile.contains(nameExpr.getNameAsString())) { - nameExpr.setName(parentClassName + "." + nameExpr.getNameAsString()); - } - return nameExpr; - } - } - - /** - * Class that visits all methods and deletes them if they are in the list of passed in MethodDeclarations - */ - public static class MethodDeleter extends ModifierVisitor { - - private List toDelete; - - public MethodDeleter(List toDelete) { - this.toDelete = toDelete; - } - - @Override - public MethodDeclaration visit(MethodDeclaration md, Void arg) { - super.visit(md, arg); - if (toDelete.contains(md)) { - return null; - } - return md; - } - } - - /** - * Class that visits all methods and deletes them if they are in the list of passed in MethodDeclarations - */ - public static class MethodExposer extends ModifierVisitor { - - private List toModify; - - public MethodExposer(List toModify) { - this.toModify = toModify; - } - - @Override - public MethodDeclaration visit(MethodDeclaration md, Void arg) { - super.visit(md, arg); - if (toModify.contains(md)) { - md.setModifier(Modifier.Keyword.PRIVATE, false); - md.setModifier(Modifier.Keyword.STATIC, true); - md.setModifier(Modifier.Keyword.PUBLIC, true); - } - return md; - } - } - - /** - * Class that visits all calls in calls and changes the access to an external class if it matches one of the passed - * in labels. - */ - public static class MethodStaticCallAdder extends ModifierVisitor { - - private List methodNames; - private String versionCode; - - public MethodStaticCallAdder(List methodNames, String versionCode) { - this.methodNames = methodNames; - this.versionCode = versionCode; - } - - @Override - public MethodCallExpr visit(MethodCallExpr methodCallExpr, Void arg) { - super.visit(methodCallExpr, arg); - if (methodNames.contains(methodCallExpr.getNameAsString())) { - //eg. convertPatient -> Patient30_50.convertPatient - methodCallExpr.setName(methodCallExpr.getNameAsString().replace(KEYWORD_CONVERT, "") - + versionCode + "." + methodCallExpr.getNameAsString()); - } - return methodCallExpr; - } - } - - private static class CommentReportEntry { - public String filename; - public String type; - public String text; - public int lineNumber; - public boolean isOrphan; - - CommentReportEntry(String filename, String type, String text, int lineNumber, - boolean isOrphan) { - this.filename = filename; - this.type = type; - this.text = text; - this.lineNumber = lineNumber; - this.isOrphan = isOrphan; - } - - @Override - public String toString() { - return filename + " | " + lineNumber + " | " + type + " | " + text.replaceAll("\\n", "").trim(); - } - } - - // ------------- Version String Manipulation Stuff - - public static final String MODEL_IMPORT_PATH = "org.hl7.fhir.%1$s.model.%2$s"; - public static final String MODEL_ABSOLUTE_PATH = "/org.hl7.fhir.%1$s/src/main/java/org/hl7/fhir/%1$s/model/%2$s.java"; - public static final String MODEL_PATH_WITHOUT_IMPORT = "/org.hl7.fhir.%1$s/src/main/java/"; - - public static String getVersionString(String version) { - switch (version) { - case ("10"): - return "dstu2"; - case ("14"): - return "dstu2016may"; - case ("30"): - return "dstu3"; - case ("40"): - return "r4"; - case ("50"): - return "r5"; - default: - throw new IllegalArgumentException("Passed in version " + version + ", no such mapping exists..."); - } - } - - public static String getModelAbsolutePathFromVersion(String convertorClassName) { - String projectDirectory = new File("").getAbsolutePath(); - String version = getFromVersion(convertorClassName); - return projectDirectory + String.format(MODEL_ABSOLUTE_PATH, getVersionString(version), extractName(convertorClassName)); - } - - public static String getModelAbsolutePathToVersion(String convertorClassName) { - String projectDirectory = new File("").getAbsolutePath(); - String version = getToVersion(convertorClassName); - return projectDirectory + String.format(MODEL_ABSOLUTE_PATH, getVersionString(version), extractName(convertorClassName)); - } - - public static String importStatementToAbsolutePath(String importStatement) { - String projectDirectory = new File("").getAbsolutePath(); - - String placeholder = null; - if (importStatement.contains("dstu2016may")) { - placeholder = "dstu2016may"; - } else if (importStatement.contains("dstu2")) { - placeholder = "dstu2"; - } else if (importStatement.contains("dstu3")) { - placeholder = "dstu3"; - } else if (importStatement.contains("r4")) { - placeholder = "r4"; - } else if (importStatement.contains("r5")) { - placeholder = "r5"; - } - - return projectDirectory + String.format(MODEL_PATH_WITHOUT_IMPORT, placeholder) + importStatement.replace('.', '/') + ".java"; - } - - private static String extractName(String convertorClassName) { - return convertorClassName.substring(0, convertorClassName.length() - 5); - } - - public static String getModelImportToVersion(String convertorClassName) { - String version = getToVersion(convertorClassName); - return String.format(MODEL_IMPORT_PATH, getVersionString(version), extractName(convertorClassName)); - } - - public static String getModelImportFromVersion(String convertorClassName) { - String version = getFromVersion(convertorClassName); - return String.format(MODEL_IMPORT_PATH, getVersionString(version), extractName(convertorClassName)); - } - - public static String getFromVersion(String className) { - String version = className.substring(className.length() - 5); - return version.substring(0, version.indexOf('_')); - } - - public static String getToVersion(String className) { - String version = className.substring(className.length() - 5); - return version.substring(version.indexOf('_') + 1, version.indexOf('_') + 3); - } - - public static String getLowerVersionAbsPathFromAbsPath(String type1Path, String type2Path, String version) { - String lowVersionString = getVersionString(version.substring(0, version.indexOf('_'))); - if (type1Path.contains(lowVersionString)) { - return type1Path; - } else { - return type2Path; - } - } - - public static String getDirectoryOfOppositeModel(String importStatement, String version) { - String lowVersionString = getVersionString(version.substring(0, version.indexOf('_'))); - String highVersionString = getVersionString(version.substring(version.indexOf('_') + 1, version.indexOf('_') + 3)); - - if (importStatement.contains(lowVersionString)) { - String temp = String.format(MODEL_IMPORT_PATH, highVersionString, ""); - return temp.substring(0, temp.lastIndexOf("model.") + "model.".length()); - } else { - String temp = String.format(MODEL_IMPORT_PATH, lowVersionString, ""); - return temp.substring(0, temp.lastIndexOf("model.") + "model.".length()); - } - } - - public static String getLowerVersionAbsPathFromImportStatement(String type1ImportStatement, String type2ImportStatement, String version) { - String type1Path = importStatementToAbsolutePath(type1ImportStatement); - String type2Path = importStatementToAbsolutePath(type2ImportStatement); - return getLowerVersionAbsPathFromAbsPath(type1Path, type2Path, version); - } - - public static String getHigherVersionAbsPath(String type1ImportStatement, String type2ImportStatement, String version) { - String type1Path = importStatementToAbsolutePath(type1ImportStatement); - String type2Path = importStatementToAbsolutePath(type2ImportStatement); - - String lowVersionString = getVersionString(version.substring(0, version.indexOf('_'))); - if (type1Path.contains(lowVersionString)) { - return type2Path; - } else { - return type1Path; - } - } -} - diff --git a/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/parser/ParserTest.java b/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/parser/ParserTest.java deleted file mode 100644 index 5a38c98da..000000000 --- a/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/parser/ParserTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.hl7.fhir.convertors.parser; - -import org.junit.Test; - -import static org.junit.Assert.*; - -public class ParserTest { - - @Test - public void parseAllTheCodes() { - } -} \ No newline at end of file