Extensions in generated profiles working again
This commit is contained in:
parent
d6e3750657
commit
55524e4e8a
|
@ -330,12 +330,12 @@ public abstract class BaseStructureParser {
|
|||
String base = "/home/t3903uhn/workspace/uhn-fhir-service/";
|
||||
TinderStructuresMojo m = new TinderStructuresMojo();
|
||||
m.setPackageName("ca.uhn.sailfhirmodel");
|
||||
m.setResourceProfileFiles(new ArrayList<String>());
|
||||
m.getResourceProfileFiles().add(base + "src/main/resources/profile/patient.xml");
|
||||
m.getResourceProfileFiles().add(base + "src/main/resources/profile/organization.xml");
|
||||
m.setResourceValueSetFiles(new ArrayList<String>());
|
||||
m.getResourceValueSetFiles().add(base + "src/main/resources/valueset/valueset-cgta-patientidpool.xml");
|
||||
m.getResourceValueSetFiles().add(base + "src/main/resources/valueset/valueset-cgta-provideridpool.xml");
|
||||
// m.setResourceProfileFiles(new ArrayList<String>());
|
||||
// m.getResourceProfileFiles().add(base + "src/main/resources/profile/patient.xml");
|
||||
// m.getResourceProfileFiles().add(base + "src/main/resources/profile/organization.xml");
|
||||
// m.setResourceValueSetFiles(new ArrayList<String>());
|
||||
// m.getResourceValueSetFiles().add(base + "src/main/resources/valueset/valueset-cgta-patientidpool.xml");
|
||||
// m.getResourceValueSetFiles().add(base + "src/main/resources/valueset/valueset-cgta-provideridpool.xml");
|
||||
m.setTargetDirectory(base + "target/generated-sources/tinder");
|
||||
m.setBuildDatatypes(true);
|
||||
m.execute();
|
||||
|
|
|
@ -0,0 +1,312 @@
|
|||
|
||||
package ca.uhn.fhir.tinder;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.capitalize;
|
||||
import static org.apache.commons.lang.StringUtils.isBlank;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile.ExtensionDefn;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile.Structure;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile.StructureElement;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile.StructureElementDefinition;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile.StructureElementDefinitionType;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile.StructureSearchParam;
|
||||
import ca.uhn.fhir.model.dstu.valueset.DataTypeEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.SlicingRulesEnum;
|
||||
import ca.uhn.fhir.tinder.model.AnyChild;
|
||||
import ca.uhn.fhir.tinder.model.BaseElement;
|
||||
import ca.uhn.fhir.tinder.model.BaseRootType;
|
||||
import ca.uhn.fhir.tinder.model.Child;
|
||||
import ca.uhn.fhir.tinder.model.Extension;
|
||||
import ca.uhn.fhir.tinder.model.Resource;
|
||||
import ca.uhn.fhir.tinder.model.ResourceBlock;
|
||||
import ca.uhn.fhir.tinder.model.SearchParameter;
|
||||
import ca.uhn.fhir.tinder.model.SimpleChild;
|
||||
import ca.uhn.fhir.tinder.model.Slicing;
|
||||
|
||||
public class CopyOfProfileParser extends BaseStructureParser {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(CopyOfProfileParser.class);
|
||||
|
||||
private ExtensionDefn findExtension(Profile theProfile, String theCode) {
|
||||
for (ExtensionDefn next : theProfile.getExtensionDefn()) {
|
||||
if (theCode.equals(next.getCode().getValue())) {
|
||||
return next;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getFilenameSuffix() {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTemplate() {
|
||||
return "/vm/resource.vm";
|
||||
}
|
||||
|
||||
public void parseBaseResources(List<String> theBaseResourceNames) throws MojoFailureException {
|
||||
FhirContext fhirContext = new FhirContext(Profile.class);
|
||||
|
||||
for (String nextFileName : theBaseResourceNames) {
|
||||
ourLog.info("Parsing file: {}", nextFileName);
|
||||
|
||||
Profile profile;
|
||||
try {
|
||||
profile = (Profile) fhirContext.newXmlParser().parseResource(IOUtils.toString(new FileReader(nextFileName)));
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to load or parse file: " + nextFileName, e);
|
||||
}
|
||||
|
||||
try {
|
||||
parseSingleProfile(profile, "");
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to process file: " + nextFileName, e);
|
||||
}
|
||||
}
|
||||
|
||||
// for (int i = 0; i < theBaseResourceNames.size(); i++) {
|
||||
// theBaseResourceNames.set(i,
|
||||
// theBaseResourceNames.get(i).toLowerCase());
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
//
|
||||
// Bundle bundle =
|
||||
// fhirContext.newXmlParser().parseBundle(IOUtils.toString(getClass().getResourceAsStream("/prof/allprofiles.xml")));
|
||||
// TreeSet<String> allProfiles = new TreeSet<String>();
|
||||
// for (BundleEntry nextResource : bundle.getEntries() ) {
|
||||
// Profile nextProfile = (Profile) nextResource.getResource();
|
||||
// allProfiles.add(nextProfile.getName().getValue());
|
||||
// if
|
||||
// (theBaseResourceNames.contains(nextProfile.getName().getValue().toLowerCase())){
|
||||
// parseSingleProfile(nextProfile,
|
||||
// bundle.getLinkBase().getValueNotNull());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// ourLog.info("Base profiles found: {}", allProfiles);
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// throw new MojoFailureException("Failed to load base resources", e);
|
||||
// }
|
||||
}
|
||||
|
||||
public BaseRootType parseSingleProfile(Profile theProfile, String theUrlTOThisProfile) throws Exception {
|
||||
BaseRootType retVal = null;
|
||||
for (Structure nextStructure : theProfile.getStructure()) {
|
||||
|
||||
int elemIdx = 0;
|
||||
boolean extensionsSliced = false;
|
||||
SlicingRulesEnum extensionsSlicingIsOpen = SlicingRulesEnum.OPEN;
|
||||
|
||||
Map<String, BaseElement> elements = new HashMap<String, BaseElement>();
|
||||
for (StructureElement next : nextStructure.getElement()) {
|
||||
|
||||
BaseElement elem;
|
||||
if (elemIdx == 0) {
|
||||
retVal = new Resource();
|
||||
retVal.setProfile(theProfile.getIdentifier().getValue());
|
||||
if (retVal.getProfile() == null) {
|
||||
retVal.setProfile(theUrlTOThisProfile);
|
||||
}
|
||||
|
||||
for (StructureSearchParam nextParam : nextStructure.getSearchParam()) {
|
||||
SearchParameter param = new SearchParameter();
|
||||
param.setName(nextParam.getName().getValue());
|
||||
param.setPath(nextParam.getXpath().getValue());
|
||||
param.setType(nextParam.getType().getValue());
|
||||
param.setDescription(nextParam.getDocumentation().getValue());
|
||||
retVal.getSearchParameters().add(param);
|
||||
}
|
||||
|
||||
addResource(retVal);
|
||||
elem = retVal;
|
||||
// below StringUtils.isBlank(type) || type.startsWith("=")
|
||||
} else {
|
||||
if (next.getDefinition().getType().size() > 0 && next.getDefinition().getType().get(0).getCode().getValue().equals("Extension")) {
|
||||
if (!next.getSlicing().isEmpty()) {
|
||||
if (!"url".equals(next.getSlicing().getDiscriminator().getValue())) {
|
||||
throw new ConfigurationException("Invalid extension slicing discriminator (must be 'url'): " + next.getSlicing().getDiscriminator().getValue());
|
||||
}
|
||||
extensionsSliced = true;
|
||||
if (StringUtils.isNotBlank(next.getSlicing().getRules().getValueAsString())) {
|
||||
extensionsSlicingIsOpen = next.getSlicing().getRules().getValueAsEnum();
|
||||
if (extensionsSlicingIsOpen == null) {
|
||||
throw new ConfigurationException("Invalid extension slicing rules: " + next.getSlicing().getRules().getValueAsString());
|
||||
}
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
if (!extensionsSliced) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (next.getDefinition().getType().size() != 1) {
|
||||
throw new ConfigurationException("Extension definition '" + next.getName().getValue() + "' has multiple type blocks. This is not supported.");
|
||||
}
|
||||
String extUrl = next.getDefinition().getType().get(0).getProfile().getValueAsString();
|
||||
elem = new Extension(next.getName().getValue(), extUrl, "CodeDt");
|
||||
}
|
||||
} else {
|
||||
if (next.getDefinition().getType().isEmpty()) {
|
||||
elem = new ResourceBlock();
|
||||
// } else if (type.startsWith("@")) {
|
||||
// elem = new ResourceBlockCopy();
|
||||
} else if (next.getDefinition().getType().get(0).getCode().getValue().equals("*")) {
|
||||
elem = new AnyChild();
|
||||
} else {
|
||||
elem = new SimpleChild();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elem.setName(next.getPath().getValue());
|
||||
elem.setElementNameAndDeriveParentElementName(next.getPath().getValue());
|
||||
|
||||
boolean allResourceReferences = next.getDefinition().getType().size() > 0;
|
||||
for (StructureElementDefinitionType nextType : next.getDefinition().getType()) {
|
||||
if (nextType.getCode().getValueAsEnum() != DataTypeEnum.RESOURCEREFERENCE) {
|
||||
allResourceReferences = false;
|
||||
}
|
||||
}
|
||||
elem.setResourceRef(allResourceReferences);
|
||||
|
||||
StructureElementDefinition definition = next.getDefinition();
|
||||
|
||||
BaseElement parentElement = elements.get(elem.getElementParentName());
|
||||
Slicing childIsSliced = parentElement != null ? parentElement.getChildElementNameToSlicing().get(elem.getName()) : null;
|
||||
|
||||
if (next.getSlicing().getDiscriminator().getValue() != null) {
|
||||
Slicing slicing = new Slicing();
|
||||
slicing.setDiscriminator(next.getSlicing().getDiscriminator().getValue());
|
||||
if (parentElement.getChildElementNameToSlicing().get(elem.getName()) != null) {
|
||||
throw new ConfigurationException("Found multiple slicing definitions for path: " + next.getPath().getValue());
|
||||
}
|
||||
parentElement.getChildElementNameToSlicing().put(elem.getName(), slicing);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Profiles come with a number of standard elements which are generally ignored because they are boilerplate, unless the definition is somehow changing their behaviour (e.g. through
|
||||
* slices)
|
||||
*/
|
||||
if (next.getPath().getValue().endsWith(".contained")) {
|
||||
continue;
|
||||
}
|
||||
if (next.getPath().getValue().endsWith(".text")) {
|
||||
continue;
|
||||
}
|
||||
if (next.getPath().getValue().endsWith(".extension")) {
|
||||
if (childIsSliced != null) {
|
||||
if (!"url".equals(childIsSliced.getDiscriminator())) {
|
||||
throw new ConfigurationException("Extensions must be sliced on 'url' discriminator. Found: " + next.getSlicing().getDiscriminator().getValue());
|
||||
}
|
||||
if (next.getDefinition().getType().size() != 1 || next.getDefinition().getType().get(0).getCode().getValueAsEnum() != DataTypeEnum.EXTENSION) {
|
||||
throw new ConfigurationException("Extension slices must have a single type with a code of 'Extension'");
|
||||
}
|
||||
String name = next.getName().getValue();
|
||||
if (StringUtils.isBlank(name)) {
|
||||
throw new ConfigurationException("Extension slices must have a 'name' defined, none found at path: " + next.getPath());
|
||||
}
|
||||
elem.setName(name);
|
||||
elem.setElementName(name);
|
||||
String profile = next.getDefinition().getType().get(0).getProfile().getValueAsString();
|
||||
if (isBlank(profile)) {
|
||||
throw new ConfigurationException("Extension slice for " + next.getPath().getValue() + " has no profile specified in its type");
|
||||
}
|
||||
if (profile.startsWith("#")) {
|
||||
Profile.ExtensionDefn extension = findExtension(theProfile, profile.substring(1));
|
||||
if (extension == null) {
|
||||
throw new ConfigurationException("Unknown local extension reference: " + profile);
|
||||
}
|
||||
ourLog.info("Element at path {} is using extension {}", next.getPath(), profile);
|
||||
definition = extension.getDefinition();
|
||||
String extensionUrl = theUrlTOThisProfile + profile;
|
||||
elem.setExtensionUrl(extensionUrl);
|
||||
} else {
|
||||
// TODO: implement this
|
||||
throw new ConfigurationException("Extensions specified outside of the given profile are not yet supported");
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (next.getPath().getValue().endsWith(".modifierExtension")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (StructureElementDefinitionType nextType : definition.getType()) {
|
||||
if (nextType.getCode().getValueAsEnum() == DataTypeEnum.RESOURCEREFERENCE) {
|
||||
if (nextType.getProfile().getValueAsString().startsWith("http://hl7.org/fhir/profiles/")) {
|
||||
elem.getType().add(capitalize(nextType.getProfile().getValueAsString().substring("http://hl7.org/fhir/profiles/".length())));
|
||||
} else {
|
||||
// TODO: implement this.. we need to be able to
|
||||
// reference other profiles
|
||||
throw new ConfigurationException("Profile type not yet supported");
|
||||
}
|
||||
} else {
|
||||
elem.getType().add(capitalize(nextType.getCode().getValue()) + "Dt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
elem.setBinding(definition.getBinding().getName().getValue());
|
||||
elem.setShortName(definition.getShort().getValue());
|
||||
elem.setDefinition(definition.getFormal().getValue());
|
||||
elem.setRequirement(definition.getRequirements().getValue());
|
||||
elem.setCardMin(definition.getMin().getValueAsString());
|
||||
elem.setCardMax(definition.getMax().getValue());
|
||||
|
||||
if (elem instanceof Child) {
|
||||
Child child = (Child) elem;
|
||||
elements.put(elem.getName(), elem);
|
||||
if (parentElement == null) {
|
||||
throw new Exception("Can't find element " + elem.getElementParentName() + " - Valid values are: " + elements.keySet());
|
||||
}
|
||||
parentElement.addChild(child);
|
||||
|
||||
/*
|
||||
* Find simple setters
|
||||
*/
|
||||
scanForSimpleSetters(child);
|
||||
} else {
|
||||
BaseRootType res = (BaseRootType) elem;
|
||||
elements.put(res.getName(), res);
|
||||
}
|
||||
|
||||
elemIdx++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String str = IOUtils.toString(Profile.class.getResourceAsStream("/tmp.txt"));
|
||||
str = IOUtils.toString(new FileReader("../hapi-tinder-test/src/test/resources/profile/organization.xml"));
|
||||
Profile prof = new FhirContext(Profile.class).newXmlParser().parseResource(Profile.class, str);
|
||||
|
||||
CopyOfProfileParser pp = new CopyOfProfileParser();
|
||||
pp.parseSingleProfile(prof, "http://foo");
|
||||
pp.markResourcesForImports();
|
||||
pp.writeAll(new File("target/gen/test/resource"), "test");
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@ import static org.apache.commons.lang.StringUtils.capitalize;
|
|||
import static org.apache.commons.lang.StringUtils.isBlank;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
|
@ -24,16 +25,16 @@ import ca.uhn.fhir.model.dstu.resource.Profile.StructureElementDefinition;
|
|||
import ca.uhn.fhir.model.dstu.resource.Profile.StructureElementDefinitionType;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile.StructureSearchParam;
|
||||
import ca.uhn.fhir.model.dstu.valueset.DataTypeEnum;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.tinder.model.AnyChild;
|
||||
import ca.uhn.fhir.tinder.model.BaseElement;
|
||||
import ca.uhn.fhir.tinder.model.Child;
|
||||
import ca.uhn.fhir.tinder.model.BaseRootType;
|
||||
import ca.uhn.fhir.tinder.model.Child;
|
||||
import ca.uhn.fhir.tinder.model.Resource;
|
||||
import ca.uhn.fhir.tinder.model.ResourceBlock;
|
||||
import ca.uhn.fhir.tinder.model.SearchParameter;
|
||||
import ca.uhn.fhir.tinder.model.SimpleChild;
|
||||
import ca.uhn.fhir.tinder.model.Slicing;
|
||||
import ca.uhn.fhir.tinder.model.UndeclaredExtensionChild;
|
||||
|
||||
public class ProfileParser extends BaseStructureParser {
|
||||
|
||||
|
@ -58,7 +59,25 @@ public class ProfileParser extends BaseStructureParser {
|
|||
return "/vm/resource.vm";
|
||||
}
|
||||
|
||||
public void parseBaseResources(List<String> theBaseResourceNames) throws MojoFailureException {
|
||||
public void parseSingleProfile(File theProfile, String theHttpUrl) throws MojoFailureException {
|
||||
String profileString;
|
||||
try {
|
||||
profileString = IOUtils.toString(new FileReader(theProfile));
|
||||
} catch (IOException e) {
|
||||
throw new MojoFailureException("Failed to load: " + theProfile, e);
|
||||
}
|
||||
|
||||
FhirContext ctx = new FhirContext(Profile.class);
|
||||
Profile profile = ctx.newXmlParser().parseResource(Profile.class, profileString);
|
||||
try {
|
||||
parseSingleProfile(profile, theHttpUrl);
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to parse profile", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void parseBaseResources(List<String> theBaseResourceNames, String theHttpUrl) throws MojoFailureException {
|
||||
FhirContext fhirContext = new FhirContext(Profile.class);
|
||||
|
||||
for (String nextFileName : theBaseResourceNames) {
|
||||
|
@ -72,7 +91,7 @@ public class ProfileParser extends BaseStructureParser {
|
|||
}
|
||||
|
||||
try {
|
||||
parseSingleProfile(profile, "");
|
||||
parseSingleProfile(profile, theHttpUrl);
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to process file: " + nextFileName, e);
|
||||
}
|
||||
|
@ -133,20 +152,20 @@ public class ProfileParser extends BaseStructureParser {
|
|||
addResource(retVal);
|
||||
elem = retVal;
|
||||
// below StringUtils.isBlank(type) || type.startsWith("=")
|
||||
} else if (next.getDefinition().getType().isEmpty()) {
|
||||
elem = new ResourceBlock();
|
||||
// } else if (type.startsWith("@")) {
|
||||
// elem = new ResourceBlockCopy();
|
||||
} else if (next.getDefinition().getType().get(0).getCode().getValue().equals("*")) {
|
||||
elem = new AnyChild();
|
||||
} else if (next.getDefinition().getType().get(0).getCode().getValue().equals("Extension")) {
|
||||
elem = new UndeclaredExtensionChild();
|
||||
} else {
|
||||
elem = new SimpleChild();
|
||||
}
|
||||
if (next.getDefinition().getType().isEmpty()) {
|
||||
elem = new ResourceBlock();
|
||||
// } else if (type.startsWith("@")) {
|
||||
// elem = new ResourceBlockCopy();
|
||||
} else if (next.getDefinition().getType().get(0).getCode().getValue().equals("*")) {
|
||||
elem = new AnyChild();
|
||||
// } else if (next.getDefinition().getType().get(0).getCode().getValue().equals("Extension")) {
|
||||
// elem = new UndeclaredExtensionChild();
|
||||
} else {
|
||||
elem = new SimpleChild();
|
||||
}
|
||||
|
||||
elem.setName(next.getPath().getValue());
|
||||
elem.setElementNameAndDeriveParentElementName(next.getPath().getValue());
|
||||
}
|
||||
|
||||
boolean allResourceReferences = next.getDefinition().getType().size() > 0;
|
||||
for (StructureElementDefinitionType nextType : next.getDefinition().getType()) {
|
||||
|
@ -154,13 +173,12 @@ public class ProfileParser extends BaseStructureParser {
|
|||
allResourceReferences = false;
|
||||
}
|
||||
}
|
||||
elem.setResourceRef(allResourceReferences);
|
||||
|
||||
populateNewElement(next, elem, allResourceReferences);
|
||||
|
||||
StructureElementDefinition definition = next.getDefinition();
|
||||
|
||||
BaseElement parentElement = elements.get(elem.getElementParentName());
|
||||
Slicing childIsSliced = parentElement != null ? parentElement.getChildElementNameToSlicing().get(elem.getName()) : null;
|
||||
|
||||
if (next.getSlicing().getDiscriminator().getValue() != null) {
|
||||
Slicing slicing = new Slicing();
|
||||
slicing.setDiscriminator(next.getSlicing().getDiscriminator().getValue());
|
||||
|
@ -171,6 +189,8 @@ public class ProfileParser extends BaseStructureParser {
|
|||
continue;
|
||||
}
|
||||
|
||||
Slicing childIsSliced = parentElement != null ? parentElement.getChildElementNameToSlicing().get(elem.getName()) : null;
|
||||
|
||||
/*
|
||||
* Profiles come with a number of standard elements which are generally ignored because they are boilerplate, unless the definition is somehow changing their behaviour (e.g. through
|
||||
* slices)
|
||||
|
@ -189,12 +209,17 @@ public class ProfileParser extends BaseStructureParser {
|
|||
if (next.getDefinition().getType().size() != 1 || next.getDefinition().getType().get(0).getCode().getValueAsEnum() != DataTypeEnum.EXTENSION) {
|
||||
throw new ConfigurationException("Extension slices must have a single type with a code of 'Extension'");
|
||||
}
|
||||
|
||||
String name = next.getName().getValue();
|
||||
if (StringUtils.isBlank(name)) {
|
||||
throw new ConfigurationException("Extension slices must have a 'name' defined, none found at path: " + next.getPath());
|
||||
}
|
||||
elem.setName(name);
|
||||
elem.setElementName(name);
|
||||
|
||||
// elem = new Extension();
|
||||
// populateNewElement(next, elem, allResourceReferences);
|
||||
|
||||
String profile = next.getDefinition().getType().get(0).getProfile().getValueAsString();
|
||||
if (isBlank(profile)) {
|
||||
throw new ConfigurationException("Extension slice for " + next.getPath().getValue() + " has no profile specified in its type");
|
||||
|
@ -267,15 +292,27 @@ public class ProfileParser extends BaseStructureParser {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private void populateNewElement(StructureElement next, BaseElement elem, boolean allResourceReferences) {
|
||||
elem.setName(next.getPath().getValue());
|
||||
elem.setElementNameAndDeriveParentElementName(next.getPath().getValue());
|
||||
elem.setResourceRef(allResourceReferences);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String str = IOUtils.toString(Profile.class.getResourceAsStream("/tmp.txt"));
|
||||
Profile prof = new FhirContext(Profile.class).newXmlParser().parseResource(Profile.class, str);
|
||||
|
||||
IParser parser = new FhirContext(Profile.class).newXmlParser();
|
||||
ProfileParser pp = new ProfileParser();
|
||||
pp.parseSingleProfile(prof, "http://foo");
|
||||
pp.markResourcesForImports();
|
||||
pp.writeAll(new File("target/gen"), "test");
|
||||
|
||||
String str = IOUtils.toString(new FileReader("../hapi-tinder-test/src/test/resources/profile/organization.xml"));
|
||||
Profile prof = parser.parseResource(Profile.class, str);
|
||||
pp.parseSingleProfile(prof, "http://foo");
|
||||
|
||||
str = IOUtils.toString(new FileReader("../hapi-tinder-test/src/test/resources/profile/patient.xml"));
|
||||
prof = parser.parseResource(Profile.class, str);
|
||||
pp.parseSingleProfile(prof, "http://foo");
|
||||
|
||||
pp.markResourcesForImports();
|
||||
pp.writeAll(new File("target/gen/test/resource"), "test");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -34,14 +34,37 @@ public class TinderStructuresMojo extends AbstractMojo {
|
|||
private String packageName;
|
||||
|
||||
@Parameter(required = false)
|
||||
private List<String> resourceProfileFiles;
|
||||
private List<ProfileFileDefinition> resourceProfileFiles;
|
||||
|
||||
@Parameter(required = false)
|
||||
private List<String> resourceValueSetFiles;
|
||||
private List<ValueSetFileDefinition> resourceValueSetFiles;
|
||||
|
||||
@Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
|
||||
private String targetDirectory;
|
||||
|
||||
public static class ProfileFileDefinition
|
||||
{
|
||||
@Parameter(required = true)
|
||||
private String profileFile;
|
||||
|
||||
@Parameter(required = true)
|
||||
private String profileSourceUrl;
|
||||
}
|
||||
|
||||
public static class ValueSetFileDefinition
|
||||
{
|
||||
@Parameter(required = true)
|
||||
private String valueSetFile;
|
||||
|
||||
public String getValueSetFile() {
|
||||
return valueSetFile;
|
||||
}
|
||||
|
||||
public void setValueSetFile(String theValueSetFile) {
|
||||
valueSetFile = theValueSetFile;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
if (StringUtils.isBlank(packageName)) {
|
||||
|
@ -105,7 +128,9 @@ public class TinderStructuresMojo extends AbstractMojo {
|
|||
if (resourceProfileFiles != null) {
|
||||
ourLog.info("Loading profiles...");
|
||||
ProfileParser pp = new ProfileParser();
|
||||
pp.parseBaseResources(resourceProfileFiles);
|
||||
for (ProfileFileDefinition next : resourceProfileFiles) {
|
||||
pp.parseSingleProfile(new File(next.profileFile), next.profileSourceUrl);
|
||||
}
|
||||
|
||||
pp.bindValueSets(vsp);
|
||||
pp.markResourcesForImports();
|
||||
|
@ -134,11 +159,11 @@ public class TinderStructuresMojo extends AbstractMojo {
|
|||
return packageName;
|
||||
}
|
||||
|
||||
public List<String> getResourceProfileFiles() {
|
||||
public List<ProfileFileDefinition> getResourceProfileFiles() {
|
||||
return resourceProfileFiles;
|
||||
}
|
||||
|
||||
public List<String> getResourceValueSetFiles() {
|
||||
public List<ValueSetFileDefinition> getResourceValueSetFiles() {
|
||||
return resourceValueSetFiles;
|
||||
}
|
||||
|
||||
|
@ -162,11 +187,11 @@ public class TinderStructuresMojo extends AbstractMojo {
|
|||
packageName = thePackageName;
|
||||
}
|
||||
|
||||
public void setResourceProfileFiles(List<String> theResourceProfileFiles) {
|
||||
public void setResourceProfileFiles(List<ProfileFileDefinition> theResourceProfileFiles) {
|
||||
resourceProfileFiles = theResourceProfileFiles;
|
||||
}
|
||||
|
||||
public void setResourceValueSetFiles(List<String> theResourceValueSetFiles) {
|
||||
public void setResourceValueSetFiles(List<ValueSetFileDefinition> theResourceValueSetFiles) {
|
||||
resourceValueSetFiles = theResourceValueSetFiles;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,12 +30,13 @@ import ca.uhn.fhir.model.dstu.resource.ValueSet.Define;
|
|||
import ca.uhn.fhir.model.dstu.resource.ValueSet.DefineConcept;
|
||||
import ca.uhn.fhir.model.primitive.CodeDt;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.tinder.TinderStructuresMojo.ValueSetFileDefinition;
|
||||
import ca.uhn.fhir.tinder.model.ValueSetTm;
|
||||
|
||||
public class ValueSetGenerator {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValueSetGenerator.class);
|
||||
private List<String> myResourceValueSetFiles;
|
||||
private List<ValueSetFileDefinition> myResourceValueSetFiles;
|
||||
private Set<ValueSetTm> myMarkedValueSets = new HashSet<ValueSetTm>();
|
||||
|
||||
private Map<String, ValueSetTm> myValueSets = new HashMap<String, ValueSetTm>();
|
||||
|
@ -68,8 +69,8 @@ public class ValueSetGenerator {
|
|||
}
|
||||
|
||||
if (myResourceValueSetFiles != null) {
|
||||
for (String next : myResourceValueSetFiles) {
|
||||
File file = new File(next);
|
||||
for (ValueSetFileDefinition next : myResourceValueSetFiles) {
|
||||
File file = new File(next.getValueSetFile());
|
||||
ourLog.info("Parsing ValueSet file: {}" + file.getName());
|
||||
vs = IOUtils.toString(new FileReader(file));
|
||||
ValueSet nextVs = (ValueSet) newXmlParser.parseResource(vs);
|
||||
|
@ -138,8 +139,8 @@ public class ValueSetGenerator {
|
|||
return vs;
|
||||
}
|
||||
|
||||
public void setResourceValueSetFiles(List<String> theString) {
|
||||
myResourceValueSetFiles = theString;
|
||||
public void setResourceValueSetFiles(List<ValueSetFileDefinition> theResourceValueSetFiles) {
|
||||
myResourceValueSetFiles = theResourceValueSetFiles;
|
||||
}
|
||||
|
||||
public void write(Collection<ValueSetTm> theValueSets, File theOutputDirectory, String thePackageBase) throws IOException {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
@Child(name="${child.elementNameSimplified}", order=${foreach.index}, min=${child.cardMin}, max=${child.cardMaxForChildAnnotation}, type={
|
||||
#foreach ($nextType in ${child.referenceTypesForMultiple})
|
||||
#if ( ${child.resourceRef} && ${nextType} != "IResource" )
|
||||
${packageBase}.resource.${nextType}.class,
|
||||
${nextType}.class,
|
||||
#else
|
||||
${nextType}.class,
|
||||
#end
|
||||
|
|
|
@ -41,6 +41,16 @@
|
|||
<ordered value="false"/>
|
||||
<rules value="open"/>
|
||||
</slicing>
|
||||
<definition>
|
||||
<short value="Extensions" />
|
||||
<formal value="Extensions" />
|
||||
<min value="0" />
|
||||
<max value="*" />
|
||||
<type>
|
||||
<code value="Extension" />
|
||||
</type>
|
||||
<isModifier value="false" />
|
||||
</definition>
|
||||
</element>
|
||||
<element>
|
||||
<path value="Organization.extension" />
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
<classpath>
|
||||
<classpathentry kind="src" path="target/generated-sources/tinder"/>
|
||||
<classpathentry kind="src" path="src/test/resources"/>
|
||||
<classpathentry kind="src" path="src/test/java"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar" sourcepath="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2-sources.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar" sourcepath="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-sources.jar"/>
|
||||
|
@ -37,5 +38,10 @@
|
|||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.17/log4j-1.2.17.jar"/>
|
||||
<classpathentry kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.11/junit-4.11-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -21,6 +21,14 @@
|
|||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.11</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -75,13 +83,24 @@
|
|||
</goals>
|
||||
<configuration>
|
||||
<package>ca.uhn.test.customstructs</package>
|
||||
<profileHttpBase>http://foo</profileHttpBase>
|
||||
<resourceProfileFiles>
|
||||
<resourceProfileFile>src/test/resources/profile/patient.xml</resourceProfileFile>
|
||||
<resourceProfileFile>src/test/resources/profile/organization.xml</resourceProfileFile>
|
||||
<resourceProfileFile>
|
||||
<profileFile>${project.basedir}/src/test/resources/profile/patient.xml</profileFile>
|
||||
<profileSourceUrl>http://foo1</profileSourceUrl>
|
||||
</resourceProfileFile>
|
||||
<resourceProfileFile>
|
||||
<profileFile>${project.basedir}/src/test/resources/profile/organization.xml</profileFile>
|
||||
<profileSourceUrl>http://foo1</profileSourceUrl>
|
||||
</resourceProfileFile>
|
||||
</resourceProfileFiles>
|
||||
<resourceValueSetFiles>
|
||||
<resourceValueSetFile>src/test/resources/valueset/valueset-cgta-patientidpool.xml</resourceValueSetFile>
|
||||
<resourceValueSetFile>src/test/resources/valueset/valueset-cgta-provideridpool.xml</resourceValueSetFile>
|
||||
<resourceValueSetFile>
|
||||
<valueSetFile>${project.basedir}/src/test/resources/valueset/valueset-cgta-patientidpool.xml</valueSetFile>
|
||||
</resourceValueSetFile>
|
||||
<resourceValueSetFile>
|
||||
<valueSetFile>${project.basedir}/src/test/resources/valueset/valueset-cgta-provideridpool.xml</valueSetFile>
|
||||
</resourceValueSetFile>
|
||||
</resourceValueSetFiles>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
package test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.test.customstructs.resource.Organization;
|
||||
import ca.uhn.test.customstructs.valueset.ConnectingGTAProviderIDNamespacesEnum;
|
||||
|
||||
public class TestCustomStructures {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TestCustomStructures.class);
|
||||
|
||||
@Test
|
||||
public void testExtension() throws DataFormatException, IOException {
|
||||
|
||||
Organization org = new Organization();
|
||||
org.addProviderIdPool(ConnectingGTAProviderIDNamespacesEnum.UNIVERSITY_HEALTH_NETWORK_PROVIDER_IDS);
|
||||
|
||||
FhirContext ctx = new FhirContext(Organization.class);
|
||||
String str = ctx.newXmlParser().encodeResourceToString(org);
|
||||
|
||||
ourLog.info(str);
|
||||
|
||||
assertTrue(str.contains("<extension url=\"http://foo1#providerIdPool\"><valueCode value=\"urn:oid:1.3.6.1.4.1.12201.1\"/></extension>"));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,16 @@
|
|||
<ordered value="false"/>
|
||||
<rules value="open"/>
|
||||
</slicing>
|
||||
<definition>
|
||||
<short value="Extensions" />
|
||||
<formal value="Extensions" />
|
||||
<min value="0" />
|
||||
<max value="*" />
|
||||
<type>
|
||||
<code value="Extension" />
|
||||
</type>
|
||||
<isModifier value="false" />
|
||||
</definition>
|
||||
</element>
|
||||
<element>
|
||||
<path value="Organization.extension" />
|
||||
|
|
3
pom.xml
3
pom.xml
|
@ -23,7 +23,8 @@
|
|||
<modules>
|
||||
<module>hapi-fhir-base</module>
|
||||
<module>hapi-tinder-plugin</module>
|
||||
<!-- <module>hapi-tinder-test</module> <module>hapi-fhir-structures-dstu</module> -->
|
||||
<module>hapi-tinder-test</module>
|
||||
<!-- <module>hapi-fhir-structures-dstu</module> -->
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
Loading…
Reference in New Issue