package ca.uhn.fhir.tinder; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Properties; import java.util.TreeSet; import org.apache.commons.lang.WordUtils; import org.apache.http.ParseException; import org.apache.maven.model.Resource; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Component; import org.apache.maven.plugins.annotations.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; import org.apache.velocity.VelocityContext; import org.apache.velocity.app.VelocityEngine; import org.apache.velocity.tools.generic.EscapeTool; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.tinder.parser.BaseStructureSpreadsheetParser; import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingModel; import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet; @Mojo(name = "generate-jparest-server", defaultPhase = LifecyclePhase.GENERATE_SOURCES) public class TinderJpaRestServerMojo extends AbstractMojo { private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderJpaRestServerMojo.class); @Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder") private File targetDirectory; @Parameter(required = true, defaultValue = "${project.build.directory}/generated-resources/tinder") private File targetResourceDirectory; @Parameter(required = true, defaultValue = "hapi-jpaserver-springbeans.xml") private String targetResourceSpringBeansFile; @Parameter(required = true) private String packageBase; @Parameter(required = true) private String configPackageBase; @Parameter(required = false) private List<String> baseResourceNames; @Parameter(required = false) private List<String> excludeResourceNames; @Parameter(required = true, defaultValue = "${project.build.directory}/..") private String baseDir; @Parameter(required = true) private String version; @Component private MavenProject myProject; @Override public void execute() throws MojoExecutionException, MojoFailureException { FhirContext fhirContext; String packageSuffix = ""; if ("dstu".equals(version)) { fhirContext = FhirContext.forDstu1(); } else if ("dstu2".equals(version)) { fhirContext = FhirContext.forDstu2(); } else if ("dstu3".equals(version)) { fhirContext = FhirContext.forDstu3(); packageSuffix = ".dstu3"; } else { throw new MojoFailureException("Unknown version configured: " + version); } if (baseResourceNames == null || baseResourceNames.isEmpty()) { baseResourceNames = new ArrayList<String>(); ourLog.info("No resource names supplied, going to use all resources from version: {}",fhirContext.getVersion().getVersion()); Properties p = new Properties(); try { p.load(fhirContext.getVersion().getFhirVersionPropertiesFile()); } catch (IOException e) { throw new MojoFailureException("Failed to load version property file", e); } ourLog.debug("Property file contains: {}",p); TreeSet<String> keys = new TreeSet<String>(); for(Object next : p.keySet()) { keys.add((String) next); } for (String next : keys) { if (next.startsWith("resource.")) { baseResourceNames.add(next.substring("resource.".length()).toLowerCase()); } } /* * No spreadsheet existed for Binary in DSTU1 so we don't generate it.. this * is something we could work around, but at this point why bother since it's * only an issue for DSTU1 */ if (fhirContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) { baseResourceNames.remove("binary"); } if (fhirContext.getVersion().getVersion() == FhirVersionEnum.DSTU3) { baseResourceNames.remove("conformance"); } } for (int i = 0; i < baseResourceNames.size(); i++) { baseResourceNames.set(i, baseResourceNames.get(i).toLowerCase()); } if (excludeResourceNames != null) { for (int i = 0; i < excludeResourceNames.size(); i++) { excludeResourceNames.set(i, excludeResourceNames.get(i).toLowerCase()); } baseResourceNames.removeAll(excludeResourceNames); } ourLog.info("Including the following resources: {}", baseResourceNames); File configPackageDirectoryBase = new File(targetDirectory, configPackageBase.replace(".", File.separatorChar + "")); configPackageDirectoryBase.mkdirs(); File packageDirectoryBase = new File(targetDirectory, packageBase.replace(".", File.separatorChar + "")); packageDirectoryBase.mkdirs(); ResourceGeneratorUsingModel gen = new ResourceGeneratorUsingModel(version, baseDir); gen.setBaseResourceNames(baseResourceNames); try { gen.parse(); gen.setFilenameSuffix("ResourceProvider"); gen.setTemplate("/vm/jpa_resource_provider.vm"); gen.writeAll(packageDirectoryBase, null,packageBase); // gen.setFilenameSuffix("ResourceTable"); // gen.setTemplate("/vm/jpa_resource_table.vm"); // gen.writeAll(directoryBase, packageBase); } catch (Exception e) { throw new MojoFailureException("Failed to generate server", e); } myProject.addCompileSourceRoot(targetDirectory.getAbsolutePath()); try { VelocityContext ctx = new VelocityContext(); ctx.put("resources", gen.getResources()); ctx.put("packageBase", packageBase); ctx.put("configPackageBase", configPackageBase); ctx.put("version", version); ctx.put("package_suffix", packageSuffix); ctx.put("esc", new EscapeTool()); if (BaseStructureSpreadsheetParser.determineVersionEnum(version).isRi()) { ctx.put("resourcePackage", "org.hl7.fhir." + version + ".model"); } else { ctx.put("resourcePackage", "ca.uhn.fhir.model." + version + ".resource"); } String capitalize = WordUtils.capitalize(version); if ("Dstu".equals(capitalize)) { capitalize="Dstu1"; } ctx.put("versionCapitalized", capitalize); VelocityEngine v = new VelocityEngine(); v.setProperty("resource.loader", "cp"); v.setProperty("cp.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); v.setProperty("runtime.references.strict", Boolean.TRUE); /* * Spring XML */ InputStream templateIs = ResourceGeneratorUsingSpreadsheet.class.getResourceAsStream("/vm/jpa_spring_beans.vm"); InputStreamReader templateReader = new InputStreamReader(templateIs); targetResourceDirectory.mkdirs(); File f = new File(targetResourceDirectory, targetResourceSpringBeansFile); OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(f, false), "UTF-8"); v.evaluate(ctx, w, "", templateReader); w.close(); Resource resource = new Resource(); resource.setDirectory(targetResourceDirectory.getAbsolutePath()); resource.addInclude(targetResourceSpringBeansFile); myProject.addResource(resource); /* * Spring Java */ templateIs = ResourceGeneratorUsingSpreadsheet.class.getResourceAsStream("/vm/jpa_spring_beans_java.vm"); templateReader = new InputStreamReader(templateIs); f = new File(configPackageDirectoryBase, "BaseJavaConfig" + capitalize + ".java"); w = new OutputStreamWriter(new FileOutputStream(f, false), "UTF-8"); v.evaluate(ctx, w, "", templateReader); w.close(); } catch (Exception e) { throw new MojoFailureException("Failed to generate server", e); } } public static void main(String[] args) throws ParseException, IOException, MojoFailureException, MojoExecutionException { // PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS); // HttpClientBuilder builder = HttpClientBuilder.create(); // builder.setConnectionManager(connectionManager); // CloseableHttpClient client = builder.build(); // // HttpGet get = new HttpGet("http://fhir.healthintersections.com.au/open/metadata"); // CloseableHttpResponse response = client.execute(get); // // String metadataString = EntityUtils.toString(response.getEntity()); // // ourLog.info("Metadata String: {}", metadataString); // String metadataString = IOUtils.toString(new FileInputStream("src/test/resources/healthintersections-metadata.xml")); // Conformance conformance = new FhirContext(Conformance.class).newXmlParser().parseResource(Conformance.class, metadataString); TinderJpaRestServerMojo mojo = new TinderJpaRestServerMojo(); mojo.myProject = new MavenProject(); mojo.version = "dstu2"; mojo.packageBase = "ca.uhn.test"; mojo.configPackageBase = "ca.uhn.test"; mojo.baseResourceNames = new ArrayList<String>(Arrays.asList( // "observation" // "communicationrequest" "binary" )); mojo.targetDirectory = new File("target/generated/valuesets"); mojo.targetResourceDirectory = new File("target/generated/valuesets"); mojo.targetResourceSpringBeansFile = "tmp_beans.xml"; mojo.execute(); } }