diff --git a/hapi-tinder-plugin/.gitignore b/hapi-tinder-plugin/.gitignore index 80308d6c7b5..6a6c8a46784 100644 --- a/hapi-tinder-plugin/.gitignore +++ b/hapi-tinder-plugin/.gitignore @@ -99,6 +99,7 @@ tmp/ *.swp *~.nib local.properties +.settings/ .loadpath # Eclipse Core @@ -114,6 +115,7 @@ local.properties .cproject # JDT-specific (Eclipse Java Development Tools) +.classpath # PDT-specific .buildpath diff --git a/hapi-tinder-plugin/pom.xml b/hapi-tinder-plugin/pom.xml index 6ca54b53533..49da9e1bfd1 100644 --- a/hapi-tinder-plugin/pom.xml +++ b/hapi-tinder-plugin/pom.xml @@ -117,6 +117,13 @@ 3.2 provided + + + + org.apache.ant + ant + 1.7.0 + diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderGenericMultiFileMojo.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderGenericMultiFileMojo.java new file mode 100644 index 00000000000..5806d64abbd --- /dev/null +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderGenericMultiFileMojo.java @@ -0,0 +1,158 @@ +package ca.uhn.fhir.tinder; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.TreeSet; + +import org.apache.http.ParseException; +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 ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet; + +@Mojo(name = "generate-multi-files", defaultPhase = LifecyclePhase.GENERATE_SOURCES) +public class TinderGenericMultiFileMojo extends AbstractMojo { + + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderGenericMultiFileMojo.class); + + // one of these two is required + @Parameter(required = false) + private String template; + @Parameter(required = false) + private File templateFile; + + @Parameter(required = true, defaultValue = "ResourceProvider") + private String filenameSuffix; + + @Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder") + private File targetDirectory; + + @Parameter(required = true) + private String packageBase; + + @Parameter(required = false) + private List baseResourceNames; + + @Parameter(required = false) + private List 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; + if ("dstu".equals(version)) { + fhirContext = FhirContext.forDstu1(); + } else if ("dstu2".equals(version)) { + fhirContext = FhirContext.forDstu2(); + } else if ("dstu3".equals(version)) { + fhirContext = FhirContext.forDstu3(); + } else { + throw new MojoFailureException("Unknown version configured: " + version); + } + + if (baseResourceNames == null || baseResourceNames.isEmpty()) { + baseResourceNames = new ArrayList(); + + 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 keys = new TreeSet(); + for(Object next : p.keySet()) { + keys.add((String) next); + } + for (String next : keys) { + if (next.startsWith("resource.")) { + baseResourceNames.add(next.substring("resource.".length()).toLowerCase()); + } + } + } + + 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 packageDirectoryBase = new File(targetDirectory, packageBase.replace(".", File.separatorChar + "")); + packageDirectoryBase.mkdirs(); + + ResourceGeneratorUsingSpreadsheet gen = new ResourceGeneratorUsingSpreadsheet(version, baseDir); + gen.setBaseResourceNames(baseResourceNames); + + try { + gen.parse(); + + gen.setFilenameSuffix(filenameSuffix); + gen.setTemplate(template); + gen.setTemplateFile(templateFile); + gen.writeAll(packageDirectoryBase, null,packageBase); + + } catch (Exception e) { + throw new MojoFailureException("Failed to generate files", e); + } + + myProject.addCompileSourceRoot(targetDirectory.getAbsolutePath()); + + } + + 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); + + TinderGenericMultiFileMojo mojo = new TinderGenericMultiFileMojo(); + mojo.myProject = new MavenProject(); + mojo.version = "dstu2"; + mojo.packageBase = "ca.uhn.test"; + mojo.template = "/vm/jpa_resource_provider.vm"; + mojo.targetDirectory = new File("target/generated/valuesets"); + mojo.execute(); + } + +} diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderGenericSingleFileMojo.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderGenericSingleFileMojo.java new file mode 100644 index 00000000000..4075e36a95b --- /dev/null +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/TinderGenericSingleFileMojo.java @@ -0,0 +1,226 @@ +package ca.uhn.fhir.tinder; + +import java.io.File; +import java.io.FileInputStream; +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.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.FileSet; +import org.apache.maven.model.PatternSet; +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.tinder.parser.BaseStructureSpreadsheetParser; +import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet; + +@Mojo(name = "generate-single-file", defaultPhase = LifecyclePhase.GENERATE_SOURCES) +public class TinderGenericSingleFileMojo extends AbstractMojo { + + private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderGenericSingleFileMojo.class); + + // one of these two is required + @Parameter(required = false) + private String template; + @Parameter(required = false) + private File templateFile; + + @Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder") + private File targetDirectory; + + @Parameter(required = false) + private String targetFolder; + + @Parameter(required = false) + private String targetPackage; + + @Parameter(required = true) + private String targetFile; + + @Parameter(required = true) + private String packageBase; + + @Parameter(required = false) + private List baseResourceNames; + + @Parameter(required = false) + private List 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; + if ("dstu".equals(version)) { + fhirContext = FhirContext.forDstu1(); + } else if ("dstu2".equals(version)) { + fhirContext = FhirContext.forDstu2(); + } else if ("dstu3".equals(version)) { + fhirContext = FhirContext.forDstu3(); + } else { + throw new MojoFailureException("Unknown version configured: " + version); + } + + if (baseResourceNames == null || baseResourceNames.isEmpty()) { + baseResourceNames = new ArrayList(); + + 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 keys = new TreeSet(); + for(Object next : p.keySet()) { + keys.add((String) next); + } + for (String next : keys) { + if (next.startsWith("resource.")) { + baseResourceNames.add(next.substring("resource.".length()).toLowerCase()); + } + } + } + + 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); + + ResourceGeneratorUsingSpreadsheet gen = new ResourceGeneratorUsingSpreadsheet(version, baseDir); + gen.setBaseResourceNames(baseResourceNames); + + try { + gen.parse(); + + VelocityContext ctx = new VelocityContext(); + ctx.put("resources", gen.getResources()); + ctx.put("packageBase", packageBase); + ctx.put("targetPackage", targetPackage); + ctx.put("version", version); + 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); + + InputStream templateIs = null; + if (templateFile != null) { + templateIs = new FileInputStream(templateFile); + } else { + templateIs = ResourceGeneratorUsingSpreadsheet.class.getResourceAsStream(template); + } + InputStreamReader templateReader = new InputStreamReader(templateIs); + + File target = targetDirectory; + if (targetFolder != null) { + targetFolder = targetFolder.replace('\\', '/'); + targetFolder = targetFolder.replace('/', File.separatorChar); + target = new File(targetDirectory, targetFolder); + } else if (targetPackage != null) { + target = new File(targetDirectory, targetPackage.replace('.', File.separatorChar)); + } + target.mkdirs(); + File f = new File(target, targetFile); + OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(f, false), "UTF-8"); + + v.evaluate(ctx, w, "", templateReader); + w.close(); + + if (targetFile.endsWith(".java")) { + myProject.addCompileSourceRoot(targetDirectory.getAbsolutePath()); + } else { + Resource resource = new Resource(); + resource.setDirectory(targetDirectory.getAbsolutePath()); + String resName = targetFile; + if (targetFolder != null) { + resName = targetFolder+File.separator+targetFile; + } + resource.addInclude(resName); + myProject.addResource(resource); + } + + } catch (Exception e) { + throw new MojoFailureException("Failed to generate file", 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); + + TinderGenericSingleFileMojo mojo = new TinderGenericSingleFileMojo(); + mojo.myProject = new MavenProject(); + mojo.template = "/vm/jpa_spring_beans.vm"; + mojo.version = "dstu2"; + mojo.packageBase = "ca.uhn.test"; + mojo.targetDirectory = new File("target/generated/valuesets"); + mojo.targetFile = "tmp_beans.xml"; + mojo.execute(); + } + +} diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ant/TinderGeneratorTask.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ant/TinderGeneratorTask.java new file mode 100644 index 00000000000..437a5ccfb8b --- /dev/null +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ant/TinderGeneratorTask.java @@ -0,0 +1,356 @@ +/** + * SOA Software, Inc. Copyright (C) 2000-2012, All rights reserved + * + * This software is the confidential and proprietary information of SOA Software, Inc. + * and is subject to copyright protection under laws of the United States of America and + * other countries. The use of this software should be in accordance with the license + * agreement terms you entered into with SOA Software, Inc. + * + * $Id$ + */ + +package ca.uhn.fhir.tinder.ant; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; +import java.util.TreeSet; +import java.util.Map.Entry; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; +import java.util.zip.ZipOutputStream; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBElement; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; +import javax.xml.namespace.QName; + +import org.apache.commons.lang.WordUtils; +import org.apache.maven.model.Resource; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.EnumeratedAttribute; +import org.apache.tools.ant.util.FileUtils; +import org.apache.velocity.VelocityContext; +import org.apache.velocity.app.VelocityEngine; +import org.apache.velocity.tools.generic.EscapeTool; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import ca.uhn.fhir.context.FhirContext; +import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet; + +/** + * + * @author Copyright (c) 2012, SOA Software, Inc. All rights reserved. + * @since 6.0 + */ +public class TinderGeneratorTask extends Task { + + // Parameter(required = true) + private String version; + + // Parameter(required = true) + private String template; + private String templateFile; + private File templateFileFile; + + // Parameter(required = true, defaultValue = "${project.build.directory}/..") + private String projectHome; + + // Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder") + private String targetDir; + private File targetDirectoryFile; + + private String targetPackage; + + // Parameter(required = true, defaultValue = "${project.build.directory}/generated-resources/tinder") + private String targetFile; + + // Parameter(required = true) + private String packageBase; + + private String targetClassSuffix; + + // Parameter(required = false) + private List baseResourceNames; + + // Parameter(required = false) + private List excludeResourceNames; + + private boolean verbose; + + private FhirContext fhirContext; // set from version in validateAttributes + + /** + * + */ + public TinderGeneratorTask () { + super(); + } + + @Override + public void execute () throws BuildException { + validateAttributes(); + + try { + + if (baseResourceNames == null || baseResourceNames.isEmpty()) { + baseResourceNames = new ArrayList(); + + log("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 BuildException("Failed to load version property file", e); + } + + if (verbose) { + log("Property file contains: "+p); + } + + for(Object next : p.keySet()) { + if (((String)next).startsWith("resource.")) { + baseResourceNames.add(((String)next).substring("resource.".length()).toLowerCase()); + } + } + } else { + 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++) { + baseResourceNames.remove(excludeResourceNames.get(i).toLowerCase()); + } + } + + log("Including the following resources: "+baseResourceNames); + + ResourceGeneratorUsingSpreadsheet gen = new ResourceGeneratorUsingSpreadsheet(version, projectHome); + gen.setBaseResourceNames(baseResourceNames); + + try { + gen.parse(); + +// gen.setFilenameSuffix("ResourceProvider"); +// gen.setTemplate("/vm/jpa_daos.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 BuildException("Failed to parse FHIR metadata", e); + } + + try { + VelocityContext ctx = new VelocityContext(); + ctx.put("resources", gen.getResources()); + ctx.put("packageBase", packageBase); + ctx.put("targetPackage", targetPackage); + ctx.put("version", version); + ctx.put("esc", new EscapeTool()); + + 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); + + targetDirectoryFile.mkdirs(); + + if (targetFile != null) { + InputStream templateIs = null; + if (templateFileFile != null) { + templateIs = new FileInputStream(templateFileFile); + } else { + templateIs = ResourceGeneratorUsingSpreadsheet.class.getResourceAsStream(template); + } + InputStreamReader templateReader = new InputStreamReader(templateIs); + + File target = null; + if (targetPackage != null) { + target = new File(targetDir, targetPackage.replace('.', File.separatorChar)); + } else { + target = new File(targetDir); + } + target.mkdirs(); + File f = new File(target, targetFile); + OutputStreamWriter w = new OutputStreamWriter(new FileOutputStream(f, false), "UTF-8"); + + v.evaluate(ctx, w, "", templateReader); + w.close(); + + } else { + File packageDirectoryBase = new File(targetDir, packageBase.replace(".", File.separatorChar + "")); + packageDirectoryBase.mkdirs(); + + gen.setFilenameSuffix(targetClassSuffix); + gen.setTemplate(template); + gen.setTemplateFile(templateFileFile); + gen.writeAll(packageDirectoryBase, null,packageBase); + + } + + } catch (Exception e) { + log("Caught exception: "+e.getClass().getName()+" ["+e.getMessage()+"]", 1); + e.printStackTrace(); + throw new BuildException("Failed to generate file(s)", e); + } + + cleanup(); + + } catch (Exception e) { + if (e instanceof BuildException) { + throw (BuildException)e; + } + log("Caught exception: "+e.getClass().getName()+" ["+e.getMessage()+"]", 1); + e.printStackTrace(); + throw new BuildException("Error processing "+getTaskName()+" task.", e); + } + } + + protected void validateAttributes () throws BuildException { + if (null == version) { + throw new BuildException("The "+this.getTaskName()+" task requires \"version\" attribute."); + } + if ("dstu".equals(version)) { + fhirContext = FhirContext.forDstu1(); + } else if ("dstu2".equals(version)) { + fhirContext = FhirContext.forDstu2(); + } else if ("dstu3".equals(version)) { + fhirContext = FhirContext.forDstu3(); + } else { + throw new BuildException("Unknown version configured: " + version); + } + + if (null == template) { + if (null == templateFile) { + throw new BuildException("The "+this.getTaskName()+" task requires \"template\" or \"templateFile\" attribute."); + } + templateFileFile = new File(templateFile); + if (!templateFileFile.exists()) { + throw new BuildException("The Velocity template file ["+templateFileFile.getAbsolutePath()+"] does not exist."); + } + if (!templateFileFile.canRead()) { + throw new BuildException("The Velocity template file ["+templateFileFile.getAbsolutePath()+"] cannot be read."); + } + if (!templateFileFile.isFile()) { + throw new BuildException("The Velocity template file ["+templateFileFile.getAbsolutePath()+"] is not a file."); + } + } + + if (null == projectHome) { + throw new BuildException("The "+this.getTaskName()+" task requires \"projectHome\" attribute."); + } + + if (null == targetDir) { + throw new BuildException("The "+this.getTaskName()+" task requires \"targetDirectory\" attribute."); + } + targetDirectoryFile = new File(targetDir); + + if (targetFile != null || (packageBase != null && targetClassSuffix != null)) { + // this is good + } else { + throw new BuildException("The "+this.getTaskName()+" task requires either the \"targetFile\" attribute or both the \"packageBase\" and \"targetClassSuffix\" attributes."); + + } + } + + protected void cleanup () { + } + + + public void setBaseResourceNames(String names) { + if (null == this.baseResourceNames) { + this.baseResourceNames = new ArrayList(); + } + if (names != null) { + List work = new ArrayList(); + String[] tokens = names.split(","); + for (String token : tokens) { + work.add(token.trim()); + } + this.baseResourceNames.addAll(work); + } + } + public void setExcludeResourceNames(String names) { + if (null == this.excludeResourceNames) { + this.excludeResourceNames = new ArrayList(); + } + if (names != null) { + List work = new ArrayList(); + String[] tokens = names.split(","); + for (String token : tokens) { + work.add(token.trim()); + } + this.excludeResourceNames.addAll(work); + } + } + public void setTemplate(String template) { + this.template = template; + } + public void setTemplateFile(String template) { + this.templateFile = template; + } + public void setProjectHome(String projectHome) { + this.projectHome = projectHome; + } + public void setTargetDir(String targetDirectory) { + this.targetDir = targetDirectory; + } + public void setTargetFile(String targetFile) { + this.targetFile = targetFile; + } + public void setTargetPackage(String targetPackage) { + this.targetPackage = targetPackage; + } + public void setPackageBase(String packageBase) { + this.packageBase = packageBase; + } + public void setTargetClassSuffix(String targetClassSuffix) { + this.targetClassSuffix = targetClassSuffix; + } + public static class Version extends EnumeratedAttribute { + public String[] getValues() { + return new String[] {"dstu", "dstu2", "dstu3"}; + } + } + public void setVersion(Version version) { + this.version = version.getValue(); + } + + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } +} diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java index 992b8828a56..85a10ba5fd3 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/BaseStructureParser.java @@ -4,6 +4,7 @@ import static org.apache.commons.lang.StringUtils.defaultString; import static org.apache.commons.lang.StringUtils.isNotBlank; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -172,6 +173,8 @@ public abstract class BaseStructureParser { } protected abstract String getTemplate(); + + protected abstract File getTemplateFile(); protected boolean isSpreadsheet(String theFileName) { return true; @@ -480,7 +483,10 @@ public abstract class BaseStructureParser { v.setProperty("cp.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); v.setProperty("runtime.references.strict", Boolean.TRUE); - InputStream templateIs = ResourceGeneratorUsingSpreadsheet.class.getResourceAsStream(getTemplate()); + InputStream templateIs = + getTemplateFile() != null + ? new FileInputStream(getTemplateFile()) + : ResourceGeneratorUsingSpreadsheet.class.getResourceAsStream(getTemplate()); InputStreamReader templateReader = new InputStreamReader(templateIs); v.evaluate(ctx, w, "", templateReader); @@ -524,7 +530,14 @@ public abstract class BaseStructureParser { // File f = new File(theOutputDirectory, (next.getDeclaringClassNameComplete()) /*+ getFilenameSuffix()*/ + // ".java"); String elementName = Resource.correctName(next.getElementName()); - File f = new File(theOutputDirectory, elementName + getFilenameSuffix() + ".java"); + String fwork = getFilenameSuffix(); + // TODO -- how to generate multiple non-Java files?? + if (fwork.endsWith(".java")) { + fwork = elementName + fwork; + } else { + fwork = elementName + fwork + ".java"; + } + File f = new File(theOutputDirectory, fwork); try { write(next, f, thePackageBase); } catch (IOException e) { diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java index 8045985edd5..2eb1b7c035f 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/DatatypeGeneratorUsingSpreadsheet.java @@ -40,6 +40,11 @@ public class DatatypeGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP protected String getTemplate() { return "dstu".equals(getVersion()) ? "/vm/dt_composite_dstu.vm" : "/vm/dt_composite.vm"; } + + @Override + protected File getTemplateFile() { + return null; + } @Override protected String getFilenameSuffix() { diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ProfileParser.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ProfileParser.java index f9b9e6ac313..b30c49f7493 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ProfileParser.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ProfileParser.java @@ -62,6 +62,11 @@ public class ProfileParser extends BaseStructureParser { protected String getTemplate() { return "dstu".equals(getVersion()) ? "/vm/resource_dstu.vm" : "/vm/resource.vm"; } + + @Override + protected File getTemplateFile() { + return null; + } public void parseSingleProfile(File theProfile, String theHttpUrl) throws MojoFailureException { String profileString; diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingSpreadsheet.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingSpreadsheet.java index 9ed90614419..c73d8f45e54 100644 --- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingSpreadsheet.java +++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/parser/ResourceGeneratorUsingSpreadsheet.java @@ -1,5 +1,6 @@ package ca.uhn.fhir.tinder.parser; +import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; @@ -16,6 +17,7 @@ public class ResourceGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP private List myInputStreamNames; private ArrayList myInputStreams; private String myTemplate = null; + private File myTemplateFile = null; public ResourceGeneratorUsingSpreadsheet(String theVersion, String theBaseDir) { super(theVersion, theBaseDir); @@ -74,6 +76,10 @@ public class ResourceGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP myTemplate = theTemplate; } + public void setTemplateFile (File theTemplateFile) { + myTemplateFile = theTemplateFile; + } + @Override protected BaseRootType createRootType() { return new Resource(); @@ -100,6 +106,11 @@ public class ResourceGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP } } + @Override + protected File getTemplateFile() { + return myTemplateFile; + } + @Override protected boolean isSpreadsheet(String theFileName) { return theFileName.endsWith("spreadsheet.xml"); diff --git a/hapi-tinder-test/pom.xml b/hapi-tinder-test/pom.xml index b80db214a1e..6d25430a0c4 100644 --- a/hapi-tinder-test/pom.xml +++ b/hapi-tinder-test/pom.xml @@ -97,7 +97,42 @@ true - @@ -108,6 +143,101 @@ + + maven-antrun-plugin + + + testTinderTask + generate-sources + + run + + + + + + + + + + + + + + + + ca.uhn.hapi.fhir + hapi-fhir-base + 1.5-SNAPSHOT + + + ca.uhn.hapi.fhir + hapi-tinder-plugin + 1.5-SNAPSHOT + + + ca.uhn.hapi.fhir + hapi-fhir-structures-dstu2 + 1.5-SNAPSHOT + + + + org.apache.maven.plugins maven-deploy-plugin @@ -139,6 +269,32 @@ + + + ca.uhn.hapi.fhir + hapi-tinder-plugin + [0.4-SNAPSHOT,) + + generate-multi-files + + + + + + + + + ca.uhn.hapi.fhir + hapi-tinder-plugin + [0.4-SNAPSHOT,) + + generate-single-file + + + + + + diff --git a/hapi-tinder-test/src/main/java/test/ResourceTest.java b/hapi-tinder-test/src/main/java/test/ResourceTest.java new file mode 100644 index 00000000000..a95ad15e298 --- /dev/null +++ b/hapi-tinder-test/src/main/java/test/ResourceTest.java @@ -0,0 +1,5 @@ +package test; + +public interface ResourceTest { + String getResourceName(); +} diff --git a/hapi-tinder-test/src/test/java/test/TestAntTask.java b/hapi-tinder-test/src/test/java/test/TestAntTask.java new file mode 100644 index 00000000000..fd81a49dda7 --- /dev/null +++ b/hapi-tinder-test/src/test/java/test/TestAntTask.java @@ -0,0 +1,23 @@ +package test; + +import java.util.List; + +import org.junit.Test; + +import ca.uhn.test.ant.single.TestConfigDstu2; +import ca.uhn.test.ant.multi.*; +import test.ResourceTest; + +public class TestAntTask { + + @Test + public void testGeneratedListReferencingGenerics() { + // This won't compile if tinder didn't generate the right names... + TestConfigDstu2 config = new TestConfigDstu2(); + List generics = config.testProvidersDstu2(); + for (ResourceTest generic : generics) { + String name = generic.getResourceName(); + } + } + +} diff --git a/hapi-tinder-test/src/test/java/test/TestGenerics.java b/hapi-tinder-test/src/test/java/test/TestGenerics.java new file mode 100644 index 00000000000..00b5d5946df --- /dev/null +++ b/hapi-tinder-test/src/test/java/test/TestGenerics.java @@ -0,0 +1,23 @@ +package test; + +import java.util.List; + +import org.junit.Test; + +import ca.uhn.test.generic.single.TestConfigDstu1; +import ca.uhn.test.generic.multi.*; +import test.ResourceTest; + +public class TestGenerics { + + @Test + public void testGeneratedListReferencingGenerics() { + // This won't compile if tinder didn't generate the right names... + TestConfigDstu1 config = new TestConfigDstu1(); + List generics = config.testProvidersDstu1(); + for (ResourceTest generic : generics) { + String name = generic.getResourceName(); + } + } + +} diff --git a/hapi-tinder-test/src/test/resources/templates/resource_test.vm b/hapi-tinder-test/src/test/resources/templates/resource_test.vm new file mode 100644 index 00000000000..dd59ce12fa9 --- /dev/null +++ b/hapi-tinder-test/src/test/resources/templates/resource_test.vm @@ -0,0 +1,13 @@ + +package ${packageBase}; + +import java.util.*; +import test.ResourceTest; + +public class ${className}ResourceTest implements ResourceTest { + + public String getResourceName() { + return "${className}"; + } + +} diff --git a/hapi-tinder-test/src/test/resources/templates/resource_test_beans_java.vm b/hapi-tinder-test/src/test/resources/templates/resource_test_beans_java.vm new file mode 100644 index 00000000000..825c3209821 --- /dev/null +++ b/hapi-tinder-test/src/test/resources/templates/resource_test_beans_java.vm @@ -0,0 +1,26 @@ +package ${targetPackage}; + +import java.util.ArrayList; +import java.util.List; +import test.ResourceTest; + +public class TestConfig${versionCapitalized} { + + public List testProviders${versionCapitalized}() { + List result = new ArrayList(); +#foreach ( $res in $resources ) + result.add(test${res.declaringClassNameComplete}${versionCapitalized}()); +#end + return result; + } + +#foreach ( $res in $resources ) + + public ${packageBase}.${res.declaringClassNameComplete}ResourceTest test${res.declaringClassNameComplete}${versionCapitalized}() { + ${packageBase}.${res.declaringClassNameComplete}ResourceTest result; + result = new ${packageBase}.${res.declaringClassNameComplete}ResourceTest(); + return result; + } +#end + +}