enhance generic Ant and Mojo tasks to support R4 and generate from

resource model structures as well as spreadsheets
This commit is contained in:
bdenton 2018-11-07 16:55:23 -08:00
parent 004b31f5de
commit 1ac2ccf363
5 changed files with 1930 additions and 1817 deletions

View File

@ -21,7 +21,9 @@ package ca.uhn.fhir.tinder;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.tinder.parser.BaseStructureParser;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingModel;
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet;
import java.io.IOException;
@ -45,6 +47,9 @@ public abstract class AbstractGenerator {
} else if ("dstu3".equals(context.getVersion())) {
fhirContext = FhirContext.forDstu3();
packageSuffix = ".dstu3";
} else if ("r4".equals(context.getVersion())) {
fhirContext = FhirContext.forR4();
packageSuffix = ".r4";
} else {
throw new FailureException("Unknown version configured: " + context.getVersion());
}
@ -139,26 +144,45 @@ public abstract class AbstractGenerator {
/*
* Load the requested resources
*/
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet(context.getVersion(), context.getBaseDir());
context.setResourceGenerator(rp);
logInfo("Loading Resources...");
try {
rp.setBaseResourceNames(includeResources);
rp.parse();
rp.markResourcesForImports();
switch (context.getResourceSource()) {
case SPREADSHEET: {
logInfo("... resource definitions from spreadsheets");
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet(context.getVersion(), context.getBaseDir());
context.setResourceGenerator(rp);
rp.setBaseResourceNames(includeResources);
rp.parse();
rp.markResourcesForImports();
rp.bindValueSets(vsp);
rp.getLocalImports().putAll(datatypeLocalImports);
datatypeLocalImports.putAll(rp.getLocalImports());
rp.combineContentMaps(dtp);
dtp.combineContentMaps(rp);
break;
}
case MODEL: {
logInfo("... resource definitions from model structures");
ResourceGeneratorUsingModel rp = new ResourceGeneratorUsingModel(context.getVersion(), context.getBaseDir());
context.setResourceGenerator(rp);
rp.setBaseResourceNames(includeResources);
rp.parse();
break;
}
}
} catch (Exception e) {
throw new FailureException("Failed to load resources", e);
}
rp.bindValueSets(vsp);
rp.getLocalImports().putAll(datatypeLocalImports);
datatypeLocalImports.putAll(rp.getLocalImports());
rp.combineContentMaps(dtp);
dtp.combineContentMaps(rp);
}
public class FailureException extends Exception {
public static class FailureException extends Exception {
public FailureException(String message, Throwable cause) {
super(message, cause);
@ -173,7 +197,7 @@ public abstract class AbstractGenerator {
}
public class ExecutionException extends Exception {
public static class ExecutionException extends Exception {
public ExecutionException(String message, Throwable cause) {
super(message, cause);

View File

@ -19,25 +19,34 @@ package ca.uhn.fhir.tinder;
* #L%
*/
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet;
import java.util.List;
import javax.security.auth.login.FailedLoginException;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugins.annotations.Parameter;
import java.util.List;
import ca.uhn.fhir.tinder.AbstractGenerator.FailureException;
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
import ca.uhn.fhir.tinder.parser.BaseStructureParser;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
/**
* @author Bill.Denton
*
*/
public class GeneratorContext {
public enum ResourceSource {SPREADSHEET, MODEL};
public static final ResourceSource DEFAULT_RESOURCE_SOURCE = ResourceSource.SPREADSHEET;
private String version;
private String packageSuffix;
private String baseDir;
private List<String> includeResources;
private List<String> excludeResources;
private ResourceSource resourceSource = DEFAULT_RESOURCE_SOURCE;
private List<ValueSetFileDefinition> valueSetFiles;
private ResourceGeneratorUsingSpreadsheet resourceGenerator = null;
private BaseStructureParser resourceGenerator = null;
private ValueSetGenerator valueSetGenerator = null;
private DatatypeGeneratorUsingSpreadsheet datatypeGenerator = null;
@ -72,6 +81,29 @@ public class GeneratorContext {
this.includeResources = includeResources;
}
public ResourceSource getResourceSource() {
return resourceSource;
}
public void setResourceSource(ResourceSource resourceSource) {
this.resourceSource = resourceSource;
}
public void setResourceSource(String resourceSource) throws FailureException {
resourceSource = StringUtils.stripToNull(resourceSource);
if (null == resourceSource) {
this.resourceSource = DEFAULT_RESOURCE_SOURCE;
} else
if (ResourceSource.SPREADSHEET.name().equalsIgnoreCase(resourceSource)) {
this.resourceSource = ResourceSource.SPREADSHEET;
} else
if (ResourceSource.MODEL.name().equalsIgnoreCase(resourceSource)) {
this.resourceSource = ResourceSource.MODEL;
} else {
throw new FailureException("Unknown resource-source option: " + resourceSource);
}
}
public String getPackageSuffix() {
return packageSuffix;
}
@ -80,11 +112,11 @@ public class GeneratorContext {
this.packageSuffix = packageSuffix;
}
public ResourceGeneratorUsingSpreadsheet getResourceGenerator() {
public BaseStructureParser getResourceGenerator() {
return resourceGenerator;
}
public void setResourceGenerator(ResourceGeneratorUsingSpreadsheet resourceGenerator) {
public void setResourceGenerator(BaseStructureParser resourceGenerator) {
this.resourceGenerator = resourceGenerator;
}

View File

@ -1,11 +1,9 @@
package ca.uhn.fhir.tinder;
import ca.uhn.fhir.tinder.AbstractGenerator.ExecutionException;
import ca.uhn.fhir.tinder.AbstractGenerator.FailureException;
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.TargetType;
import java.io.File;
import java.io.IOException;
import java.util.List;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@ -16,9 +14,12 @@ import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import java.io.File;
import java.io.IOException;
import java.util.List;
import ca.uhn.fhir.tinder.AbstractGenerator.ExecutionException;
import ca.uhn.fhir.tinder.AbstractGenerator.FailureException;
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
import ca.uhn.fhir.tinder.parser.BaseStructureParser;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.TargetType;
/**
* Generate files from FHIR resource/composite metadata using Velocity templates.
@ -40,7 +41,7 @@ import java.util.List;
* <td valign="top">version</td>
* <td valign="top">The FHIR version whose resource metadata
* is to be used to generate the files<br>
* Valid values:&nbsp;<code><b>dstu</b></code>&nbsp;|&nbsp;<code><b>dstu2</b></code>&nbsp;|&nbsp;<code><b>dstu3</b></code></td>
* Valid values:&nbsp;<code><b>dstu2</b></code>&nbsp;|&nbsp;<code><b>dstu3</b></code>&nbsp;|&nbsp;<code><b>r4</b></code></td>
* <td valign="top" align="center">Yes</td>
* </tr>
* <tr>
@ -53,7 +54,7 @@ import java.util.List;
* <td valign="top">generateResources</td>
* <td valign="top">Should files be generated from FHIR resource metadata?<br>
* Valid values:&nbsp;<code><b>true</b></code>&nbsp;|&nbsp;<code><b>false</b></code></td>
* <td valign="top" align="center" rowspan="4">One of these four options must be specified</td>
* <td valign="top" align="center" rowspan="4">One of these four options must be specified as <code><b>true</b></code></td>
* </tr>
* <tr>
* <td valign="top">generateDataTypes</td>
@ -71,6 +72,14 @@ import java.util.List;
* Valid values:&nbsp;<code><b>true</b></code>&nbsp;|&nbsp;<code><b>false</b></code></td>
* </tr>
* <tr>
* <td valign="top">resourceSource</td>
* <td valign="top">Which source of resource definitions should be processed? Valid values are:<br>
* <ul>
* <li><code><b>spreadsheet</b></code>&nbsp;&nbsp;to cause resources to be generated based on the FHIR spreadsheets</li>
* <li><code><b>model</b></code>&nbsp;&nbsp;to cause resources to be generated based on the model structure classes</li></ul></td>
* <td valign="top" align="center">No. Defaults to: <code><b>spreadsheet</b></code></td>
* </tr>
* <tr>
* <td colspan="3" />
* </tr>
* <tr>
@ -246,6 +255,9 @@ public class TinderGenericMultiFileMojo extends AbstractMojo {
@Parameter(required = false)
private List<String> excludeResources;
@Parameter(required = false)
private String resourceSource;
@Parameter(required = false)
private List<ValueSetFileDefinition> valueSetFiles;
@ -256,14 +268,15 @@ public class TinderGenericMultiFileMojo extends AbstractMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
GeneratorContext context = new GeneratorContext();
context.setVersion(version);
context.setBaseDir(baseDir);
context.setIncludeResources(includeResources);
context.setExcludeResources(excludeResources);
context.setValueSetFiles(valueSetFiles);
Generator generator = new Generator();
try {
context.setVersion(version);
context.setBaseDir(baseDir);
context.setIncludeResources(includeResources);
context.setExcludeResources(excludeResources);
context.setResourceSource(resourceSource);
context.setValueSetFiles(valueSetFiles);
generator.prepare(context);
} catch (ExecutionException e) {
throw new MojoExecutionException(e.getMessage(), e.getCause());
@ -308,7 +321,7 @@ public class TinderGenericMultiFileMojo extends AbstractMojo {
/*
* Write resources if selected
*/
ResourceGeneratorUsingSpreadsheet rp = context.getResourceGenerator();
BaseStructureParser rp = context.getResourceGenerator();
if (generateResources && rp != null) {
ourLog.info("Writing Resources...");
rp.setFilenamePrefix(filenamePrefix);

View File

@ -1,12 +1,14 @@
package ca.uhn.fhir.tinder;
import ca.uhn.fhir.tinder.AbstractGenerator.ExecutionException;
import ca.uhn.fhir.tinder.AbstractGenerator.FailureException;
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
import ca.uhn.fhir.tinder.parser.BaseStructureSpreadsheetParser;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.TargetType;
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.List;
import org.apache.commons.lang.WordUtils;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
@ -21,8 +23,13 @@ import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.tools.generic.EscapeTool;
import java.io.*;
import java.util.List;
import ca.uhn.fhir.tinder.AbstractGenerator.ExecutionException;
import ca.uhn.fhir.tinder.AbstractGenerator.FailureException;
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
import ca.uhn.fhir.tinder.parser.BaseStructureParser;
import ca.uhn.fhir.tinder.parser.BaseStructureSpreadsheetParser;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.TargetType;
/**
* Generate a single file based on resource or composite type metadata.
@ -44,7 +51,7 @@ import java.util.List;
* <td valign="top">version</td>
* <td valign="top">The FHIR version whose resource metadata
* is to be used to generate the files<br>
* Valid values:&nbsp;<code><b>dstu</b></code>&nbsp;|&nbsp;<code><b>dstu2</b></code>&nbsp;|&nbsp;<code><b>dstu3</b></code></td>
* Valid values:&nbsp;<code><b>dstu2</b></code>&nbsp;|&nbsp;<code><b>dstu3</b></code>&nbsp;|&nbsp;<code><b>r4</b></code></td>
* <td valign="top" align="center">Yes</td>
* </tr>
* <tr>
@ -57,7 +64,7 @@ import java.util.List;
* <td valign="top">generateResources</td>
* <td valign="top">Should files be generated from FHIR resource metadata?<br>
* Valid values:&nbsp;<code><b>true</b></code>&nbsp;|&nbsp;<code><b>false</b></code></td>
* <td valign="top" align="center" rowspan="2">One of these two options must be specified</td>
* <td valign="top" align="center" rowspan="2">One of these two options must be specified as <code><b>true</b></code></td>
* </tr>
* <tr>
* <td valign="top">generateDataTypes</td>
@ -65,6 +72,14 @@ import java.util.List;
* Valid values:&nbsp;<code><b>true</b></code>&nbsp;|&nbsp;<code><b>false</b></code></td>
* </tr>
* <tr>
* <td valign="top">resourceSource</td>
* <td valign="top">Which source of resource definitions should be processed? Valid values are:<br>
* <ul>
* <li><code><b>spreadsheet</b></code>&nbsp;&nbsp;to cause resources to be generated based on the FHIR spreadsheets</li>
* <li><code><b>model</b></code>&nbsp;&nbsp;to cause resources to be generated based on the model structure classes</li></ul></td>
* <td valign="top" align="center">No. Defaults to: <code><b>spreadsheet</b></code></td>
* </tr>
* <tr>
* <td colspan="3" />
* </tr>
* <tr>
@ -233,6 +248,9 @@ public class TinderGenericSingleFileMojo extends AbstractMojo {
@Parameter(required = false)
private List<String> excludeResources;
@Parameter(required = false)
private String resourceSource;
@Parameter(required = false)
private List<ValueSetFileDefinition> valueSetFiles;
@ -243,14 +261,15 @@ public class TinderGenericSingleFileMojo extends AbstractMojo {
public void execute() throws MojoExecutionException, MojoFailureException {
GeneratorContext context = new GeneratorContext();
context.setVersion(version);
context.setBaseDir(baseDir);
context.setIncludeResources(includeResources);
context.setExcludeResources(excludeResources);
context.setValueSetFiles(valueSetFiles);
Generator generator = new Generator();
try {
context.setVersion(version);
context.setBaseDir(baseDir);
context.setIncludeResources(includeResources);
context.setExcludeResources(excludeResources);
context.setResourceSource(resourceSource);
context.setValueSetFiles(valueSetFiles);
generator.prepare(context);
} catch (ExecutionException e) {
throw new MojoExecutionException(e.getMessage(), e.getCause());
@ -351,7 +370,7 @@ public class TinderGenericSingleFileMojo extends AbstractMojo {
/*
* Write resources if selected
*/
ResourceGeneratorUsingSpreadsheet rp = context.getResourceGenerator();
BaseStructureParser rp = context.getResourceGenerator();
if (generateResources && rp != null) {
ourLog.info("Writing Resources...");
ctx.put("resources", rp.getResources());

View File

@ -19,6 +19,23 @@ package ca.uhn.fhir.tinder.ant;
* #L%
*/
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.apache.commons.lang.WordUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
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.AbstractGenerator;
import ca.uhn.fhir.tinder.AbstractGenerator.ExecutionException;
@ -27,21 +44,10 @@ import ca.uhn.fhir.tinder.GeneratorContext;
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
import ca.uhn.fhir.tinder.ValueSetGenerator;
import ca.uhn.fhir.tinder.VelocityHelper;
import ca.uhn.fhir.tinder.parser.BaseStructureParser;
import ca.uhn.fhir.tinder.parser.BaseStructureSpreadsheetParser;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.TargetType;
import org.apache.commons.lang.WordUtils;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.tools.generic.EscapeTool;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
/**
/**
@ -64,7 +70,7 @@ import java.util.StringTokenizer;
* <td valign="top">version</td>
* <td valign="top">The FHIR version whose resource metadata
* is to be used to generate the files<br>
* Valid values:&nbsp;<code><b>dstu</b></code>&nbsp;|&nbsp;<code><b>dstu2</b></code>&nbsp;|&nbsp;<code><b>dstu3</b></code></td>
* Valid values:&nbsp;<code><b>dstu2</b></code>&nbsp;|&nbsp;<code><b>dstu3</b></code>&nbsp;|&nbsp;<code><b>r4</b></code></td>
* <td valign="top" align="center">Yes</td>
* </tr>
* <tr>
@ -77,7 +83,7 @@ import java.util.StringTokenizer;
* <td valign="top">generateResources</td>
* <td valign="top">Should files be generated from FHIR resource metadata?<br>
* Valid values:&nbsp;<code><b>true</b></code>&nbsp;|&nbsp;<code><b>false</b></code></td>
* <td valign="top" align="center" rowspan="4">At least one of these four options must be specified</td>
* <td valign="top" align="center" rowspan="4">At least one of these four options must be specified as <code><b>true</b></code></td>
* </tr>
* <tr>
* <td valign="top">generateDataTypes</td>
@ -97,6 +103,14 @@ import java.util.StringTokenizer;
* Valid values:&nbsp;<code><b>true</b></code>&nbsp;|&nbsp;<code><b>false</b></code></td>
* </tr>
* <tr>
* <td valign="top">resourceSource</td>
* <td valign="top">Which source of resource definitions should be processed? Valid values are:<br>
* <ul>
* <li><code><b>spreadsheet</b></code>&nbsp;&nbsp;to cause resources to be generated based on the FHIR spreadsheets</li>
* <li><code><b>model</b></code>&nbsp;&nbsp;to cause resources to be generated based on the model structure classes</li></ul></td>
* <td valign="top" align="center">No. Defaults to: <code><b>spreadsheet</b></code></td>
* </tr>
* <tr>
* <td colspan="3" />
* </tr>
* <tr>
@ -281,6 +295,8 @@ public class TinderGeneratorTask extends Task {
private List<String> excludeResources;
private String resourceSource;
private List<ValueSetFileDefinition> valueSetFiles;
private boolean verbose;
@ -303,14 +319,15 @@ public class TinderGeneratorTask extends Task {
GeneratorContext context = new GeneratorContext();
context.setVersion(version);
context.setBaseDir(projectHome);
context.setIncludeResources(includeResources);
context.setExcludeResources(excludeResources);
context.setValueSetFiles(valueSetFiles);
Generator generator = new Generator();
try {
context.setVersion(version);
context.setBaseDir(projectHome);
context.setIncludeResources(includeResources);
context.setExcludeResources(excludeResources);
context.setResourceSource(resourceSource);
context.setValueSetFiles(valueSetFiles);
generator.prepare(context);
} catch (ExecutionException e) {
throw new BuildException(e.getMessage(), e.getCause());
@ -413,7 +430,7 @@ public class TinderGeneratorTask extends Task {
/*
* Write resources if selected
*/
ResourceGeneratorUsingSpreadsheet rp = context.getResourceGenerator();
BaseStructureParser rp = context.getResourceGenerator();
if (generateResources && rp != null) {
log("Writing Resources...");
ctx.put("resources", rp.getResources());
@ -436,7 +453,7 @@ public class TinderGeneratorTask extends Task {
/*
* Write resources if selected
*/
ResourceGeneratorUsingSpreadsheet rp = context.getResourceGenerator();
BaseStructureParser rp = context.getResourceGenerator();
if (generateResources && rp != null) {
log("Writing Resources...");
rp.setFilenamePrefix(filenamePrefix);
@ -550,6 +567,14 @@ public class TinderGeneratorTask extends Task {
this.projectHome = projectHome;
}
public String getResourceSource() {
return resourceSource;
}
public void setResourceSource(String resourceSource) {
this.resourceSource = resourceSource;
}
public void setTargetFile(String targetFile) {
this.targetFile = targetFile;
}