diff --git a/org.hl7.fhir.convertors/pom.xml b/org.hl7.fhir.convertors/pom.xml index 93357577d..5c649e4d0 100644 --- a/org.hl7.fhir.convertors/pom.xml +++ b/org.hl7.fhir.convertors/pom.xml @@ -59,35 +59,6 @@ true - - - com.github.javaparser - javaparser-symbol-solver-core - 3.15.9 - - - - - com.google.guava - guava - 28.2-jre - - - - - com.google.code.gson - gson - 2.8.6 - - - - - org.junit.jupiter - junit-jupiter - RELEASE - test - - diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserElement.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserElement.java deleted file mode 100644 index 96ec7179e..000000000 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserElement.java +++ /dev/null @@ -1,538 +0,0 @@ -package org.hl7.fhir.convertors.parser; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import com.github.javaparser.StaticJavaParser; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; -import com.github.javaparser.ast.stmt.BlockStmt; -import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.stmt.IfStmt; -import com.github.javaparser.ast.stmt.Statement; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.Type; -import com.github.javaparser.ast.visitor.ModifierVisitor; -import com.github.javaparser.ast.visitor.Visitable; -import com.github.javaparser.symbolsolver.JavaSymbolSolver; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -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; - -public class ParserElement { - - public static final String ELEMENT = "Element"; - - 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", "Canonical", "Code", - "Enumeration", "Date", "DateType", "Decimal", "Id", "Instant", "Integer", "Integer64", - "Markdown", "Oid", "PositiveInt", "String", "Time", "UnsignedInt", "Uri", "Url", - "Uuid", "XhtmlNode"); - private static final List VERSION_FILES2 = Arrays.asList("30_40", "30_50", "40_50"); - private static String MODEL_BASE_PATH = "/Users/markiantorno/Documents/Development/fhir/org.hl7.fhir.core/org.hl7.fhir.%1$s/src/main/java/"; - - public static void main(String[] args) { - VERSION_FILES.forEach(version -> { - //String version = "10_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", BASE_TYPES, version); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - }); - }); - -// VERSION_FILES2.forEach(version -> { -// -// try { -// modifyElementNotField("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv10_50/", "DiagnosticReport10_50", ".java", BASE_TYPES, "10_50"); -// } catch (FileNotFoundException e) { -// e.printStackTrace(); -// } -// -// }); - - } - - public static HashMap> masterList = new HashMap<>(); - - public static void modifyElementNotField(String srcdirectory, String filename, String extension, List listOfPrimitiveTypes, String version) throws FileNotFoundException { - String projectDirectory = new File("").getAbsolutePath(); - String filePathWithExtension = projectDirectory + srcdirectory + filename + extension; - CompilationUnit compilationUnit = getCompilationUnit(filePathWithExtension); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = initializeTypeSovlerAndParser(compilationUnit, - projectDirectory, srcdirectory, filename); - - List methods = classOrInterfaceDeclaration.getMethods(); - for (MethodDeclaration md : methods) { - if (!masterList.containsKey(md)) { - masterList.put(md, new HashMap<>()); - } - - if (!md.getNameAsString().contains("convert")) continue; - - Optional src = md.getParameters().stream() - .filter(p -> p.getName().toString().equals("src")) - .findAny(); - if (!src.isPresent()) { - continue; - } - - Type toType = md.getType(); - Type fromType = src.get().getType(); - - final ClassOrInterfaceDeclaration toClass = resolveClassRefFromType(toType); - final ClassOrInterfaceDeclaration fromClass = resolveClassRefFromType(fromType); - if ((toClass != null) && (fromClass != null)) { - md.accept(new ModifierVisitor() { - @Override - public Visitable visit(ExpressionStmt n, Void arg) { - super.visit(n, arg); - if (n.toString().contains("src.get") && (n.toString().contains("tgt.add") || n.toString().contains("tgt.set"))) { - try { - if (canModifyElement(n, fromClass, toClass)) { - String s = generateNewIfStatement(n, fromClass, toClass, version); - if (masterList.get(md).containsKey(n)) throw new IllegalStateException(); - masterList.get(md).put(n, s); - } else { - String s = generateOldIfStatement(n, fromClass); - masterList.get(md).put(n, s); - } - System.gc(); - } catch (Exception e) { - System.out.println(e.getMessage()); - } - } - return n; - } - }, null); - } else { - //System.out.println("At least one class dec null..."); - } - } - - for (MethodDeclaration md : methods) { - md.accept(new ModifierVisitor() { - @Override - public Visitable visit(MethodDeclaration n, Void arg) { - super.visit(n, arg); - - String bodyString = n.getBody().get().toString(); - - HashMap map = masterList.get(md); - for (ExpressionStmt e : map.keySet()) { - if (!bodyString.contains(e.toString())) { - throw new IllegalStateException("Cannot find expression in method block..."); - } else { - bodyString = bodyString.replace(e.toString(), map.get(e)); - } - } - BlockStmt blockStmt = StaticJavaParser.parseBlock(bodyString); - n.removeBody(); - n.setBody(blockStmt); - return n; - } - }, null); - } - - deleteFile(filePathWithExtension); - - try { - writeStringToFile(compilationUnit.toString(), filePathWithExtension); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - private static boolean methodWithNameExists(String methodName, ClassOrInterfaceDeclaration classType) { - return methodWithNameExists(methodName, classType, new HashSet<>()); - } - - private static boolean methodWithNameExists(String methodName, ClassOrInterfaceDeclaration classType, Set visited) { - if (classType == null) return false; - - List collect = classType.getMethods().stream() - .map(NodeWithSimpleName::getNameAsString) - .collect(Collectors.toList()); - - if (collect.contains(methodName)) { - return true; - } else if (classType.getExtendedTypes().isEmpty()) { - return false; - } else { - - System.out.println("searching class :: " + classType.getNameAsString() + ", for method name :: " + methodName); - ClassOrInterfaceType extendedType = classType.getExtendedTypes(0); - if (extendedType.getNameAsString().contains("PrimitiveType") || extendedType.getNameAsString().contains("BackboneElement")) { - return false; - } - String qualifiedName = ((ReferenceTypeImpl) extendedType.resolve()).getQualifiedName(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(qualifiedName); - if (visited.contains(classOrInterfaceDeclaration.getNameAsString())) { - return false; - } else { - visited.add(classOrInterfaceDeclaration.getNameAsString()); - return methodWithNameExists(methodName, classOrInterfaceDeclaration, visited); - } - } - } - - private static Type getReturnType(String methodName, ClassOrInterfaceDeclaration classType) { - Optional first = classType.getMethods().stream() - .filter(md -> md.getNameAsString().equals(methodName)) - .findFirst(); - if (first.isPresent()) { - return first.get().getType(); - } else if (!classType.getExtendedTypes().isEmpty()) { - String qualifiedName = ((ReferenceTypeImpl) classType.getExtendedTypes(0).resolve()).getQualifiedName(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(qualifiedName); - return getReturnType(methodName, classOrInterfaceDeclaration); - } else { - throw new IllegalArgumentException("Method requested, " + methodName + " doesn't exist in class type " + classType.getNameAsString()); - } - } - - private static Type getParameterType(String methodName, ClassOrInterfaceDeclaration classType) { - Optional first = classType.getMethods().stream() - .filter(md -> md.getNameAsString().equals(methodName)) - .findFirst(); - if (!first.isPresent()) { - if (!classType.getExtendedTypes().isEmpty()) { - System.out.println("Method Name :: " + methodName); - System.out.println("Class :: " + classType.getNameAsString()); - String qualifiedName = ((ReferenceTypeImpl) classType.getExtendedTypes(0).resolve()).getQualifiedName(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(qualifiedName); - return getParameterType(methodName, classOrInterfaceDeclaration); - } else { - throw new IllegalArgumentException("Method requested, " + methodName + " doesn't exist in class type " + classType.getNameAsString()); - } - } else if (first.get().getParameters().isEmpty()) { - throw new IllegalArgumentException("Method requested, " + methodName + " doesn't have parameters"); - } else { - return first.get().getParameter(0).getType(); - } - } - - public static final String OLD_CONDITION_STATEMENT_TEMPLATE = "src.has%1$s()"; - public static final String NEW_CONDITION_STATEMENT_TEMPLATE = "src.has%1$sElement()"; - public static final String NEW_EXPR_STATEMENT_TEMPLATE = "tgt.set%1$sElement(convert%3$s(src.get%4$sElement()));"; - public static final String NEW_EXPR_STATEMENT_TEMPLATE_SUBFILE = "tgt.set%1$sElement(VersionConvertor_%2$s.convert%3$s(src.get%4$sElement()));"; - - private static Statement modifyElementAccess(ExpressionStmt n, ClassOrInterfaceDeclaration fromType, ClassOrInterfaceDeclaration toType, String version) throws Exception { - if (!canModifyElement(n, fromType, toType)) throw new IllegalArgumentException("Cannot modify passed in elements."); - - MethodCallExpr methodCallExpr = (MethodCallExpr) n.getChildNodes().get(0); - String setMethodName = methodCallExpr.getNameAsString(); - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - - String paramTypeString = getParameterType(setMethodName + ELEMENT, toType).toString(); - String returnTypeName = getReturnType(getMethodName + ELEMENT, fromType).toString(); - - String expString = String.format(NEW_EXPR_STATEMENT_TEMPLATE, - setMethodName.replace("set", ""), - version, - returnTypeName.replace("Type", ""), - getMethodName.replace("get", "")); - return StaticJavaParser.parseStatement(expString); - } - - private static String generateNewIfStatement(ExpressionStmt n, ClassOrInterfaceDeclaration fromType, ClassOrInterfaceDeclaration toType, String version) { - if (!canModifyElement(n, fromType, toType)) throw new IllegalArgumentException("Cannot modify passed in elements."); - - MethodCallExpr methodCallExpr = (MethodCallExpr) n.getChildNodes().get(0); - String setMethodName = methodCallExpr.getNameAsString(); - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - - String paramTypeString = getParameterType(setMethodName + ELEMENT, toType).toString(); - String returnTypeName = getReturnType(getMethodName + ELEMENT, fromType).toString(); - - String condition = String.format(NEW_CONDITION_STATEMENT_TEMPLATE, getMethodName.replaceFirst("get", "")); - - String expString = String.format(NEW_EXPR_STATEMENT_TEMPLATE_SUBFILE, - setMethodName.replaceFirst("set", ""), - version, - returnTypeName.replace("Type", ""), - getMethodName.replaceFirst("get", "")); - - if (n.getParentNode().get() instanceof IfStmt) { - return expString; - } else { - IfStmt ifStmt = new IfStmt(); - ifStmt.setCondition(StaticJavaParser.parseExpression(condition)); - ifStmt.setThenStmt(StaticJavaParser.parseStatement(expString)); - return ifStmt.toString(); - } - } - - private static String generateOldIfStatement(ExpressionStmt n, ClassOrInterfaceDeclaration fromType) { - if (n.getParentNode().get() instanceof IfStmt) { - return n.toString(); - } - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - if (((MethodCallExpr) n.getExpression()).getArgument(0) instanceof MethodCallExpr) { - try { - getMethodName = ((MethodCallExpr) ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getArgument(0)).getNameAsString(); - } catch (Exception e) { - getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - } - } - - getMethodName = getMethodName.replace("FirstRep", ""); - - if (methodWithNameExists("has" + getMethodName.replaceFirst("get", ""), fromType)) { - String condition = String.format(OLD_CONDITION_STATEMENT_TEMPLATE, getMethodName.replaceFirst("get", "")); - - IfStmt ifStmt = new IfStmt(); - ifStmt.setCondition(StaticJavaParser.parseExpression(condition)); - ifStmt.setThenStmt(n); - - return ifStmt.toString(); - } else { - return n.toString(); - } - } - - private static boolean canModifyElement(ExpressionStmt n, ClassOrInterfaceDeclaration fromClass, ClassOrInterfaceDeclaration toClass) { - MethodCallExpr methodCallExpr = (MethodCallExpr) n.getChildNodes().get(0); - String setMethodName = methodCallExpr.getNameAsString(); - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - System.out.println("Can modify element: n :: " + n.toString() + ", fromClass :: " + fromClass.getNameAsString() + ", toClass :: " + toClass.getNameAsString()); - return !getMethodName.contains("convert") && - methodWithNameExists(setMethodName + ELEMENT, toClass) - && methodWithNameExists(getMethodName + ELEMENT, fromClass) - && methodWithNameExists("has" + getMethodName.replace("get", "") + ELEMENT, fromClass) - && (getParameterType(setMethodName + ELEMENT, toClass).toString().equals(getReturnType(getMethodName + ELEMENT, fromClass).toString())); - } - - public static ClassOrInterfaceDeclaration resolveClassRefFromType(Type type) { - if (!(type instanceof ClassOrInterfaceType)) { - return null; //throw new IllegalStateException("Type " + type.toString() + " is not instanceof ClassOrInterfaceType"); - } - - Optional optionalScope = ((ClassOrInterfaceType) type).getScope(); - try { - if (optionalScope.isPresent()) { - ClassOrInterfaceType classOrInterfaceType = optionalScope.get(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(classOrInterfaceType.toString() + "." + ((ClassOrInterfaceType) type).getNameAsString()); - - if (classOrInterfaceDeclaration == null || !classOrInterfaceType.getNameAsString().equals("model")) { - classOrInterfaceDeclaration = qualifiedPathToClassInterface(classOrInterfaceType.toString()); - Optional any = classOrInterfaceDeclaration.getChildNodes().stream() - .filter(node -> node instanceof ClassOrInterfaceDeclaration) - .map(node -> (ClassOrInterfaceDeclaration) node) - .filter(c -> c.getNameAsString().equals(((ClassOrInterfaceType) type).getNameAsString())) - .findAny(); - if (any.isPresent()) { - return any.get(); - } else { - return null; - } - } - return classOrInterfaceDeclaration; - } - }catch (NullPointerException e) { - System.out.println(); - } - return null; - } - - public static ClassOrInterfaceDeclaration qualifiedPathToClassInterface(String qualifiedPath) { - String baseDir = importStatementToAbsoluteBasePath(qualifiedPath); - String plainName = qualifiedPath.substring(qualifiedPath.lastIndexOf('.') + 1); - String toReturn = baseDir + qualifiedPath.replace(".", "/") + ".java"; - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(toReturn)); - } catch (FileNotFoundException e) { - return null; - } - Optional optionalClass = compilationUnit.getClassByName(plainName); - return optionalClass.orElse(null); - } - - public static String importStatementToAbsoluteBasePath(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 String.format(MODEL_BASE_PATH, placeholder); - } - - /** - * 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(ParserElement::pullFileNameFromPath) - .collect(Collectors.toCollection(() -> result)); - } catch (IOException e) { - e.printStackTrace(); - } - return result; - } - - 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(); - } - - /** - * 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) { - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(path)); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return Optional.ofNullable(compilationUnit); - } - - private static ClassOrInterfaceDeclaration initializeTypeSovlerAndParser(CompilationUnit compilationUnit, - String projectDirectory, - String codeDirectory, - String filename) { - try { - initializeResolver(projectDirectory, codeDirectory); - } catch (IOException e) { - System.out.println("Error initializing typesolver, exiting process..."); - e.printStackTrace(); - System.exit(0); - } - Optional classOrInterfaceDeclaration = loadClass(compilationUnit, filename); - if (!classOrInterfaceDeclaration.isPresent()) { - System.out.println("\nNo class or interface declaration loaded during parsing...aborting."); - System.exit(0); - } - return classOrInterfaceDeclaration.get(); - } - - /** - * 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 { - 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); - } - - /** - * 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); - } - - /** - * 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); - } - - /** - * 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 + ">"); - } - } - - public static void writeStringToFile(String string, String filepath) throws IOException { - BufferedWriter writer = new BufferedWriter(new FileWriter(filepath)); - writer.write(string); - writer.close(); - } - -} diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserEnumeration.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserEnumeration.java deleted file mode 100644 index 0df8f315e..000000000 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserEnumeration.java +++ /dev/null @@ -1,425 +0,0 @@ -package org.hl7.fhir.convertors.parser; - -import com.github.javaparser.StaticJavaParser; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.EnumDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; -import com.github.javaparser.ast.stmt.*; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.Type; -import com.github.javaparser.ast.visitor.ModifierVisitor; -import com.github.javaparser.ast.visitor.Visitable; -import com.github.javaparser.ast.visitor.VoidVisitor; -import com.github.javaparser.ast.visitor.VoidVisitorAdapter; -import com.github.javaparser.symbolsolver.JavaSymbolSolver; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -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.convertors.VersionConvertor_10_30; -import org.hl7.fhir.convertors.VersionConvertor_30_50; -import org.hl7.fhir.dstu3.model.MedicationRequest; -import org.hl7.fhir.exceptions.FHIRException; -import org.hl7.fhir.r5.model.Enumerations; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class ParserEnumeration { - - public static final String ELEMENT = "Element"; - - 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 String MODEL_BASE_PATH = "/Users/markiantorno/Documents/Development/fhir/org.hl7.fhir.core/org.hl7.fhir.%1$s/src/main/java/"; - - public static HashMap> masterList = new HashMap<>(); - - public static final Set methodNames = new HashSet<>(); - - /* - * %1$s - dstu version src, example r5 - * %2$s - dstu version tgt, example dstu3 - * %3$s - src enum name, with enclosing class, if applicable, eg Account.AccountStatus - * %4$s - tgt enum name, with enclosing class, if applicable, eg Account.AccountStatus - * %5$s - version string, eg 10_30 - * %6$s - method name, eg convertAccountStatus - * %7$s - new switch statement body - */ - public static final String ENUM_TEMPLATE = "static public org.hl7.fhir.%2$s.model.Enumeration %6$s(org.hl7.fhir.%1$s.model.Enumeration src) throws FHIRException { " + - "if (src == null || src.isEmpty()) " + - "return null; " + - "org.hl7.fhir.%2$s.model.Enumeration tgt = new org.hl7.fhir.%2$s.model.Enumeration<>(new org.hl7.fhir.%2$s.model.%4$sEnumFactory()); " + - "VersionConvertor_%5$s.copyElement(src, tgt); " + - "%7$s" + - "return tgt;" + - "}"; - - /* - * %1$s - dstu version tgt, example dstu3 - * %2$s - tgt enum name, with enclosing class, if applicable, eg Account.AccountStatus - * %3$s - ENUM label, eg ACTIVE - */ - public static final String SWITCH_STATEMENT_TEMPLATE = "tgt.setValue(org.hl7.fhir.%1$s.model.%2$s.%3$s);"; - public static final String SWITCH_BREAK = " break;"; - - public static void main(String[] args) { - VERSION_FILES.forEach(version -> { - //String version = "10_30"; - //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 { - modifyEnumMethods("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/", "VersionConvertor_" + version, ".java", version); - modifyExpressionsCallingEnums("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/", "VersionConvertor_" + version, ".java", version); - methodNames.clear(); - } catch (Exception e) { - e.printStackTrace(); - } - //}); - }); - -// VERSION_FILES2.forEach(version -> { -// -// try { -// modifyEnumMethods("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv" + "10_30" + "/", "Account10_30", ".java", "10_30"); -// modifyExpressionsCallingEnums("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv" + "10_30" + "/", "Account10_30", ".java", "10_30"); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// -// }); - - } - - public static void modifyExpressionsCallingEnums(String srcdirectory, String filename, String extension, String version) { - String projectDirectory = new File("").getAbsolutePath(); - String filePathWithExtension = projectDirectory + srcdirectory + filename + extension; - CompilationUnit compilationUnit = getCompilationUnit(filePathWithExtension); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = initializeTypeSovlerAndParser(compilationUnit, - projectDirectory, srcdirectory, filename); - - List methods = classOrInterfaceDeclaration.getMethods(); - for (MethodDeclaration md : methods) { - md.accept(new ModifierVisitor() { - @Override - public Visitable visit(ExpressionStmt exp, Void arg) { - super.visit(exp, arg); - Optional methodNameOpt = methodNames.stream() - .filter(s -> exp.toString().contains(s + "(")) - .findFirst(); - if (methodNameOpt.isPresent()) { - try { - String outerName = ((MethodCallExpr) exp.getExpression()).getNameAsString(); - String innerName = ((MethodCallExpr) ((MethodCallExpr) ((MethodCallExpr) exp.getExpression()).getArgument(0)).getArgument(0)).getNameAsString(); - ((MethodCallExpr) exp.getExpression()).setName(outerName + ELEMENT); - ((MethodCallExpr) ((MethodCallExpr) ((MethodCallExpr) exp.getExpression()).getArgument(0)).getArgument(0)).setName(innerName + ELEMENT); - } catch (Exception e) { - System.out.println(e.getMessage()); - } - } - return exp; - } - }, null); - } - - try { - writeStringToFile(compilationUnit.toString(), filePathWithExtension); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static void modifyEnumMethods(String srcdirectory, String filename, String extension, String version) { - String projectDirectory = new File("").getAbsolutePath(); - String filePathWithExtension = projectDirectory + srcdirectory + filename + extension; - CompilationUnit compilationUnit = getCompilationUnit(filePathWithExtension); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = initializeTypeSovlerAndParser(compilationUnit, - projectDirectory, srcdirectory, filename); - - classOrInterfaceDeclaration.accept(new ModifierVisitor() { - @Override - public Visitable visit(MethodDeclaration md, Void arg) { - super.visit(md, arg); - Optional src = md.getParameters().stream() - .filter(p -> p.getName().toString().equals("src")) - .findAny(); - - if ((md.getNameAsString().contains("convert")) && (src.isPresent()) && (md.getParameters().size() == 1)) { - - Type tgtType = md.getType(); - Type srcType = src.get().getType(); - - final EnumDeclaration toEnum = resolveEnumRefFromType(tgtType); - final EnumDeclaration fromEnum = resolveEnumRefFromType(srcType); - - if (toEnum != null && fromEnum != null) { - System.out.println("toEnum :: " + toEnum.getNameAsString()); - System.out.println("fromEnum :: " + fromEnum.getNameAsString()); - - String dstuVersionSrc = getVersionIdString(srcType.toString()); - String dstuVersionTgt = getVersionIdString(tgtType.toString()); - String classNameSrc = srcType.toString().substring(srcType.toString().indexOf("model.") + "model.".length()); - String classNameTgt = tgtType.toString().substring(tgtType.toString().indexOf("model.") + "model.".length()); - String methodName = md.getNameAsString(); - - methodNames.add(methodName); - - final String[] switchStatement = {"PARSING SWITCH DIDN'T WORK"}; - - md.accept(new VoidVisitorAdapter() { - @Override - public void visit(SwitchStmt n, Void arg) { - System.out.println(); - n.setSelector(StaticJavaParser.parseExpression("src.getValue()")); - for (SwitchEntry switchEntry : n.getEntries()) { - String enumLabel = switchEntry.getStatement(0).toString(); - enumLabel = enumLabel.substring(enumLabel.lastIndexOf('.') + 1, enumLabel.indexOf(';')); - - String switchStatement = String.format(SWITCH_STATEMENT_TEMPLATE, dstuVersionTgt, classNameTgt, enumLabel); - Statement statement = StaticJavaParser.parseStatement(switchStatement); - Statement breakStatement = StaticJavaParser.parseStatement(SWITCH_BREAK); - switchEntry.setStatement(0, statement); - switchEntry.addStatement(breakStatement); - } - switchStatement[0] = n.toString(); - } - }, null); - - String newMethodBody = String.format(ENUM_TEMPLATE, dstuVersionSrc, dstuVersionTgt, classNameSrc, classNameTgt, version, methodName, switchStatement[0]); - md = StaticJavaParser.parseMethodDeclaration(newMethodBody); - } - } - return md; - } - }, null); - - try { - writeStringToFile(compilationUnit.toString(), filePathWithExtension); - } catch (IOException e) { - e.printStackTrace(); - } - methodNames.forEach(System.out::println); - } - - public static EnumDeclaration resolveEnumRefFromType(Type type) { - if (!(type instanceof ClassOrInterfaceType)) { - return null; //throw new IllegalStateException("Type " + type.toString() + " is not instanceof ClassOrInterfaceType"); - } - - Optional optionalScope = ((ClassOrInterfaceType) type).getScope(); - try { - if (optionalScope.isPresent()) { - ClassOrInterfaceType classOrInterfaceType = optionalScope.get(); - EnumDeclaration classOrInterfaceDeclaration = qualifiedPathToEnum(classOrInterfaceType.toString() + "." + ((ClassOrInterfaceType) type).getNameAsString(), - ((ClassOrInterfaceType) type).getNameAsString()); - - if (classOrInterfaceDeclaration == null || !classOrInterfaceType.getNameAsString().equals("model")) { - classOrInterfaceDeclaration = qualifiedPathToEnum(classOrInterfaceType.toString(), ((ClassOrInterfaceType) type).getNameAsString()); - } - return classOrInterfaceDeclaration; - } - } catch (NullPointerException e) { - System.out.println(); - } - return null; - } - - public static EnumDeclaration qualifiedPathToEnum(String qualifiedPath, String enumName) { - String baseDir = importStatementToAbsoluteBasePath(qualifiedPath); - String plainName = qualifiedPath.substring(qualifiedPath.lastIndexOf('.') + 1); - String toReturn = baseDir + qualifiedPath.replace(".", "/") + ".java"; - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(toReturn)); - } catch (FileNotFoundException e) { - return null; - } - Optional classByName = compilationUnit.getClassByName(plainName); - if (classByName.isPresent()) { - Optional first = classByName.get().getChildNodes() - .stream() - .filter(node -> node instanceof EnumDeclaration) - .map(node -> (EnumDeclaration) node) - .filter(e -> e.getNameAsString().equals(enumName)) - .findFirst(); - return first.orElse(null); - } else { - return null; - } - } - - public static String getVersionIdString(String importStatement) { - - 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 placeholder; - } - - public static String importStatementToAbsoluteBasePath(String importStatement) { - String placeholder = getVersionIdString(importStatement); - return String.format(MODEL_BASE_PATH, placeholder); - } - - /** - * 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(ParserEnumeration::pullFileNameFromPath) - .collect(Collectors.toCollection(() -> result)); - } catch (IOException e) { - e.printStackTrace(); - } - return result; - } - - 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(); - } - - /** - * 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) { - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(path)); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return Optional.ofNullable(compilationUnit); - } - - private static ClassOrInterfaceDeclaration initializeTypeSovlerAndParser(CompilationUnit compilationUnit, - String projectDirectory, - String codeDirectory, - String filename) { - try { - initializeResolver(projectDirectory, codeDirectory); - } catch (IOException e) { - System.out.println("Error initializing typesolver, exiting process..."); - e.printStackTrace(); - System.exit(0); - } - Optional classOrInterfaceDeclaration = loadClass(compilationUnit, filename); - if (!classOrInterfaceDeclaration.isPresent()) { - System.out.println("\nNo class or interface declaration loaded during parsing...aborting."); - System.exit(0); - } - return classOrInterfaceDeclaration.get(); - } - - /** - * 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 { - 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); - } - - /** - * 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); - } - - /** - * 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); - } - - /** - * 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 + ">"); - } - } - - public static void writeStringToFile(String string, String filepath) throws IOException { - BufferedWriter writer = new BufferedWriter(new FileWriter(filepath)); - writer.write(string); - writer.close(); - } - -} diff --git a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserEnumerationBackup.java b/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserEnumerationBackup.java deleted file mode 100644 index a2eeec192..000000000 --- a/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/parser/ParserEnumerationBackup.java +++ /dev/null @@ -1,567 +0,0 @@ -package org.hl7.fhir.convertors.parser; - -import com.github.javaparser.StaticJavaParser; -import com.github.javaparser.ast.CompilationUnit; -import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; -import com.github.javaparser.ast.body.EnumDeclaration; -import com.github.javaparser.ast.body.MethodDeclaration; -import com.github.javaparser.ast.body.Parameter; -import com.github.javaparser.ast.expr.MethodCallExpr; -import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; -import com.github.javaparser.ast.stmt.ExpressionStmt; -import com.github.javaparser.ast.stmt.IfStmt; -import com.github.javaparser.ast.stmt.Statement; -import com.github.javaparser.ast.type.ClassOrInterfaceType; -import com.github.javaparser.ast.type.Type; -import com.github.javaparser.ast.visitor.ModifierVisitor; -import com.github.javaparser.ast.visitor.Visitable; -import com.github.javaparser.symbolsolver.JavaSymbolSolver; -import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; -import com.github.javaparser.symbolsolver.model.typesystem.ReferenceTypeImpl; -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 java.io.*; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.*; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -public class ParserEnumerationBackup { - - public static final String ELEMENT = "Element"; - - 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 String MODEL_BASE_PATH = "/Users/markiantorno/Documents/Development/fhir/org.hl7.fhir.core/org.hl7.fhir.%1$s/src/main/java/"; - - public static HashMap> masterList = new HashMap<>(); - - /* - * %1$s - dstu version src, example r5 - * %2$s - dstu version tgt, example dstu3 - * %3$s - classname src including nested parents, example Enumerations.RequestPriority - * %4$s - classname tgt including nested parents, example MedicationRequest.MedicationRequestPriority - * %5$s - version conversion file title, eg 30_50 - * %6$s - enumName tgt without nested parents - */ - static public final String ENUM_TEMPLATE = "static public org.hl7.fhir.%2$s.model.%4$s convert%6$s(org.hl7.fhir.%1$s.model.%3$s src) throws FHIRException { " + - "if ((src == null)||(src.isEmpty()) " + - "return null;" + - "org.hl7.fhir.%2$s.model.Enumeration tgtEnum " + - "= new org.hl7.fhir.%2$s.model.Enumeration<>(new org.hl7.fhir.%2$s.model.%4$sEnumFactory());" + - "org.hl7.fhir.%1$s.model.Enumeration srcEnum " + - "= new org.hl7.fhir.%1$s.model.Enumeration<>(new org.hl7.fhir.%1$s.model.%3$sEnumFactory(), src); " + - "VersionConvertor_%5$s.copyElement(srcEnum, tgtEnum); " + - "tgtEnum.setValue(org.hl7.fhir.%2$s.model.%4$s.fromCode(srcEnum.getValueAsString())); " + - "return tgtEnum.getValue();" + - "}"; - - public static void main(String[] args) { - VERSION_FILES.forEach(version -> { - //String version = "10_30"; - 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 { - modifyEnumMethods("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv" + version + "/", name, ".java", version); - } catch (Exception e) { - e.printStackTrace(); - } - }); - }); - -// VERSION_FILES2.forEach(version -> { -// -// try { -// modifyEnumMethods("/org.hl7.fhir.convertors/src/main/java/org/hl7/fhir/convertors/conv30_50/", "MedicationRequest30_50", ".java", "30_50"); -// } catch (Exception e) { -// e.printStackTrace(); -// } -// -// }); - - } - - public static void modifyEnumMethods(String srcdirectory, String filename, String extension, String version) { - String projectDirectory = new File("").getAbsolutePath(); - String filePathWithExtension = projectDirectory + srcdirectory + filename + extension; - CompilationUnit compilationUnit = getCompilationUnit(filePathWithExtension); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = initializeTypeSovlerAndParser(compilationUnit, - projectDirectory, srcdirectory, filename); - - classOrInterfaceDeclaration.accept(new ModifierVisitor() { - @Override - public Visitable visit(MethodDeclaration md, Void arg) { - super.visit(md, arg); - Optional src = md.getParameters().stream() - .filter(p -> p.getName().toString().equals("src")) - .findAny(); - - if ((md.getNameAsString().contains("convert")) && (src.isPresent()) && (md.getParameters().size() == 1)) { - - Type tgtType = md.getType(); - Type srcType = src.get().getType(); - - final EnumDeclaration toEnum = resolveEnumRefFromType(tgtType); - final EnumDeclaration fromEnum = resolveEnumRefFromType(srcType); - - if (toEnum != null && fromEnum != null) { - System.out.println("toEnum :: " + toEnum.getNameAsString()); - System.out.println("fromEnum :: " + fromEnum.getNameAsString()); - - String dstuVersionSrc = getVersionIdString(srcType.toString()); - String dstuVersionTgt = getVersionIdString(tgtType.toString()); - String classNameSrc = srcType.toString().substring(srcType.toString().indexOf("model.") + "model.".length()); - String classNameTgt = tgtType.toString().substring(tgtType.toString().indexOf("model.") + "model.".length()); - String methodName = fromEnum.getNameAsString(); - - String newMethodBody = String.format(ENUM_TEMPLATE, dstuVersionSrc, dstuVersionTgt, classNameSrc, classNameTgt, version, methodName); - md = StaticJavaParser.parseMethodDeclaration(newMethodBody); - } - } - return md; - } - }, null); - - deleteFile(filePathWithExtension); - - try { - writeStringToFile(compilationUnit.toString(), filePathWithExtension); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - private static boolean methodWithNameExists(String methodName, ClassOrInterfaceDeclaration classType) { - return methodWithNameExists(methodName, classType, new HashSet<>()); - } - - private static boolean methodWithNameExists(String methodName, ClassOrInterfaceDeclaration classType, Set visited) { - if (classType == null) return false; - - List collect = classType.getMethods().stream() - .map(NodeWithSimpleName::getNameAsString) - .collect(Collectors.toList()); - - if (collect.contains(methodName)) { - return true; - } else if (classType.getExtendedTypes().isEmpty()) { - return false; - } else { - - System.out.println("searching class :: " + classType.getNameAsString() + ", for method name :: " + methodName); - ClassOrInterfaceType extendedType = classType.getExtendedTypes(0); - if (extendedType.getNameAsString().contains("PrimitiveType") || extendedType.getNameAsString().contains("BackboneElement")) { - return false; - } - String qualifiedName = ((ReferenceTypeImpl) extendedType.resolve()).getQualifiedName(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(qualifiedName); - if (visited.contains(classOrInterfaceDeclaration.getNameAsString())) { - return false; - } else { - visited.add(classOrInterfaceDeclaration.getNameAsString()); - return methodWithNameExists(methodName, classOrInterfaceDeclaration, visited); - } - } - } - - private static Type getReturnType(String methodName, ClassOrInterfaceDeclaration classType) { - Optional first = classType.getMethods().stream() - .filter(md -> md.getNameAsString().equals(methodName)) - .findFirst(); - if (first.isPresent()) { - return first.get().getType(); - } else if (!classType.getExtendedTypes().isEmpty()) { - String qualifiedName = ((ReferenceTypeImpl) classType.getExtendedTypes(0).resolve()).getQualifiedName(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(qualifiedName); - return getReturnType(methodName, classOrInterfaceDeclaration); - } else { - throw new IllegalArgumentException("Method requested, " + methodName + " doesn't exist in class type " + classType.getNameAsString()); - } - } - - private static Type getParameterType(String methodName, ClassOrInterfaceDeclaration classType) { - Optional first = classType.getMethods().stream() - .filter(md -> md.getNameAsString().equals(methodName)) - .findFirst(); - if (!first.isPresent()) { - if (!classType.getExtendedTypes().isEmpty()) { - System.out.println("Method Name :: " + methodName); - System.out.println("Class :: " + classType.getNameAsString()); - String qualifiedName = ((ReferenceTypeImpl) classType.getExtendedTypes(0).resolve()).getQualifiedName(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(qualifiedName); - return getParameterType(methodName, classOrInterfaceDeclaration); - } else { - throw new IllegalArgumentException("Method requested, " + methodName + " doesn't exist in class type " + classType.getNameAsString()); - } - } else if (first.get().getParameters().isEmpty()) { - throw new IllegalArgumentException("Method requested, " + methodName + " doesn't have parameters"); - } else { - return first.get().getParameter(0).getType(); - } - } - - public static final String OLD_CONDITION_STATEMENT_TEMPLATE = "src.has%1$s()"; - public static final String NEW_CONDITION_STATEMENT_TEMPLATE = "src.has%1$sElement()"; - public static final String NEW_EXPR_STATEMENT_TEMPLATE = "tgt.set%1$sElement(convert%3$s(src.get%4$sElement()));"; - public static final String NEW_EXPR_STATEMENT_TEMPLATE_SUBFILE = "tgt.set%1$sElement(VersionConvertor_%2$s.convert%3$s(src.get%4$sElement()));"; - - private static Statement modifyElementAccess(ExpressionStmt n, ClassOrInterfaceDeclaration fromType, ClassOrInterfaceDeclaration toType, String version) throws Exception { - if (!canModifyElement(n, fromType, toType)) - throw new IllegalArgumentException("Cannot modify passed in elements."); - - MethodCallExpr methodCallExpr = (MethodCallExpr) n.getChildNodes().get(0); - String setMethodName = methodCallExpr.getNameAsString(); - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - - String paramTypeString = getParameterType(setMethodName + ELEMENT, toType).toString(); - String returnTypeName = getReturnType(getMethodName + ELEMENT, fromType).toString(); - - String expString = String.format(NEW_EXPR_STATEMENT_TEMPLATE, - setMethodName.replace("set", ""), - version, - returnTypeName.replace("Type", ""), - getMethodName.replace("get", "")); - return StaticJavaParser.parseStatement(expString); - } - - private static String generateNewIfStatement(ExpressionStmt n, ClassOrInterfaceDeclaration fromType, ClassOrInterfaceDeclaration toType, String version) { - if (!canModifyElement(n, fromType, toType)) - throw new IllegalArgumentException("Cannot modify passed in elements."); - - MethodCallExpr methodCallExpr = (MethodCallExpr) n.getChildNodes().get(0); - String setMethodName = methodCallExpr.getNameAsString(); - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - - String paramTypeString = getParameterType(setMethodName + ELEMENT, toType).toString(); - String returnTypeName = getReturnType(getMethodName + ELEMENT, fromType).toString(); - - String condition = String.format(NEW_CONDITION_STATEMENT_TEMPLATE, getMethodName.replaceFirst("get", "")); - - String expString = String.format(NEW_EXPR_STATEMENT_TEMPLATE_SUBFILE, - setMethodName.replaceFirst("set", ""), - version, - returnTypeName.replace("Type", ""), - getMethodName.replaceFirst("get", "")); - - if (n.getParentNode().get() instanceof IfStmt) { - return expString; - } else { - IfStmt ifStmt = new IfStmt(); - ifStmt.setCondition(StaticJavaParser.parseExpression(condition)); - ifStmt.setThenStmt(StaticJavaParser.parseStatement(expString)); - return ifStmt.toString(); - } - } - - private static String generateOldIfStatement(ExpressionStmt n, ClassOrInterfaceDeclaration fromType) { - if (n.getParentNode().get() instanceof IfStmt) { - return n.toString(); - } - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - if (((MethodCallExpr) n.getExpression()).getArgument(0) instanceof MethodCallExpr) { - try { - getMethodName = ((MethodCallExpr) ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getArgument(0)).getNameAsString(); - } catch (Exception e) { - getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - } - } - - getMethodName = getMethodName.replace("FirstRep", ""); - - if (methodWithNameExists("has" + getMethodName.replaceFirst("get", ""), fromType)) { - String condition = String.format(OLD_CONDITION_STATEMENT_TEMPLATE, getMethodName.replaceFirst("get", "")); - - IfStmt ifStmt = new IfStmt(); - ifStmt.setCondition(StaticJavaParser.parseExpression(condition)); - ifStmt.setThenStmt(n); - - return ifStmt.toString(); - } else { - return n.toString(); - } - } - - private static boolean canModifyElement(ExpressionStmt n, ClassOrInterfaceDeclaration fromClass, ClassOrInterfaceDeclaration toClass) { - MethodCallExpr methodCallExpr = (MethodCallExpr) n.getChildNodes().get(0); - String setMethodName = methodCallExpr.getNameAsString(); - String getMethodName = ((MethodCallExpr) ((MethodCallExpr) n.getExpression()).getArgument(0)).getNameAsString(); - System.out.println("Can modify element: n :: " + n.toString() + ", fromClass :: " + fromClass.getNameAsString() + ", toClass :: " + toClass.getNameAsString()); - return !getMethodName.contains("convert") && - methodWithNameExists(setMethodName + ELEMENT, toClass) - && methodWithNameExists(getMethodName + ELEMENT, fromClass) - && methodWithNameExists("has" + getMethodName.replace("get", "") + ELEMENT, fromClass) - && (getParameterType(setMethodName + ELEMENT, toClass).toString().equals(getReturnType(getMethodName + ELEMENT, fromClass).toString())); - } - - public static EnumDeclaration resolveEnumRefFromType(Type type) { - if (!(type instanceof ClassOrInterfaceType)) { - return null; //throw new IllegalStateException("Type " + type.toString() + " is not instanceof ClassOrInterfaceType"); - } - - Optional optionalScope = ((ClassOrInterfaceType) type).getScope(); - try { - if (optionalScope.isPresent()) { - ClassOrInterfaceType classOrInterfaceType = optionalScope.get(); - EnumDeclaration classOrInterfaceDeclaration = qualifiedPathToEnum(classOrInterfaceType.toString() + "." + ((ClassOrInterfaceType) type).getNameAsString(), - ((ClassOrInterfaceType) type).getNameAsString()); - - if (classOrInterfaceDeclaration == null || !classOrInterfaceType.getNameAsString().equals("model")) { - classOrInterfaceDeclaration = qualifiedPathToEnum(classOrInterfaceType.toString(), ((ClassOrInterfaceType) type).getNameAsString()); -// Optional any = classOrInterfaceDeclaration.getChildNodes().stream() -// .filter(node -> node instanceof EnumDeclaration) -// .map(node -> (EnumDeclaration) node) -// .filter(c -> c.getNameAsString().equals(((ClassOrInterfaceType) type).getNameAsString())) -// .findAny(); -// if (any.isPresent()) { -// return any.get(); -// } else { -// return null; -// } - } - return classOrInterfaceDeclaration; - } - } catch (NullPointerException e) { - System.out.println(); - } - return null; - } - - public static EnumDeclaration qualifiedPathToEnum(String qualifiedPath, String enumName) { - String baseDir = importStatementToAbsoluteBasePath(qualifiedPath); - String plainName = qualifiedPath.substring(qualifiedPath.lastIndexOf('.') + 1); - String toReturn = baseDir + qualifiedPath.replace(".", "/") + ".java"; - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(toReturn)); - } catch (FileNotFoundException e) { - return null; - } - Optional classByName = compilationUnit.getClassByName(plainName); - if (classByName.isPresent()) { - Optional first = classByName.get().getChildNodes() - .stream() - .filter(node -> node instanceof EnumDeclaration) - .map(node -> (EnumDeclaration) node) - .filter(e -> e.getNameAsString().equals(enumName)) - .findFirst(); - return first.orElse(null); - } else { - return null; - } - } - - public static ClassOrInterfaceDeclaration resolveClassRefFromType(Type type) { - if (!(type instanceof ClassOrInterfaceType)) { - return null; //throw new IllegalStateException("Type " + type.toString() + " is not instanceof ClassOrInterfaceType"); - } - - Optional optionalScope = ((ClassOrInterfaceType) type).getScope(); - try { - if (optionalScope.isPresent()) { - ClassOrInterfaceType classOrInterfaceType = optionalScope.get(); - ClassOrInterfaceDeclaration classOrInterfaceDeclaration = qualifiedPathToClassInterface(classOrInterfaceType.toString() + "." + ((ClassOrInterfaceType) type).getNameAsString()); - - if (classOrInterfaceDeclaration == null || !classOrInterfaceType.getNameAsString().equals("model")) { - classOrInterfaceDeclaration = qualifiedPathToClassInterface(classOrInterfaceType.toString()); - Optional any = classOrInterfaceDeclaration.getChildNodes().stream() - .filter(node -> node instanceof ClassOrInterfaceDeclaration) - .map(node -> (ClassOrInterfaceDeclaration) node) - .filter(c -> c.getNameAsString().equals(((ClassOrInterfaceType) type).getNameAsString())) - .findAny(); - if (any.isPresent()) { - return any.get(); - } else { - return null; - } - } - return classOrInterfaceDeclaration; - } - } catch (NullPointerException e) { - System.out.println(); - } - return null; - } - - public static ClassOrInterfaceDeclaration qualifiedPathToClassInterface(String qualifiedPath) { - String baseDir = importStatementToAbsoluteBasePath(qualifiedPath); - String plainName = qualifiedPath.substring(qualifiedPath.lastIndexOf('.') + 1); - String toReturn = baseDir + qualifiedPath.replace(".", "/") + ".java"; - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(toReturn)); - } catch (FileNotFoundException e) { - return null; - } - Optional optionalClass = compilationUnit.getClassByName(plainName); - return optionalClass.orElse(null); - } - - public static String getVersionIdString(String importStatement) { - - 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 placeholder; - } - - public static String importStatementToAbsoluteBasePath(String importStatement) { - String placeholder = getVersionIdString(importStatement); - return String.format(MODEL_BASE_PATH, placeholder); - } - - /** - * 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(ParserEnumerationBackup::pullFileNameFromPath) - .collect(Collectors.toCollection(() -> result)); - } catch (IOException e) { - e.printStackTrace(); - } - return result; - } - - 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(); - } - - /** - * 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) { - CompilationUnit compilationUnit = null; - try { - compilationUnit = StaticJavaParser.parse(new File(path)); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - return Optional.ofNullable(compilationUnit); - } - - private static ClassOrInterfaceDeclaration initializeTypeSovlerAndParser(CompilationUnit compilationUnit, - String projectDirectory, - String codeDirectory, - String filename) { - try { - initializeResolver(projectDirectory, codeDirectory); - } catch (IOException e) { - System.out.println("Error initializing typesolver, exiting process..."); - e.printStackTrace(); - System.exit(0); - } - Optional classOrInterfaceDeclaration = loadClass(compilationUnit, filename); - if (!classOrInterfaceDeclaration.isPresent()) { - System.out.println("\nNo class or interface declaration loaded during parsing...aborting."); - System.exit(0); - } - return classOrInterfaceDeclaration.get(); - } - - /** - * 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 { - 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); - } - - /** - * 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); - } - - /** - * 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); - } - - /** - * 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 + ">"); - } - } - - public static void writeStringToFile(String string, String filepath) throws IOException { - BufferedWriter writer = new BufferedWriter(new FileWriter(filepath)); - writer.write(string); - writer.close(); - } - -} diff --git a/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/parser/ParserElementTest.java b/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/parser/ParserElementTest.java deleted file mode 100644 index d899b39e6..000000000 --- a/org.hl7.fhir.convertors/src/test/java/org/hl7/fhir/convertors/parser/ParserElementTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.hl7.fhir.convertors.parser; - -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.*; - -class ParserElementTest { - - @Test - void deleteFile() { - } -} \ No newline at end of file