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
+
+}