Lots of fixes and docs to tinder

This commit is contained in:
jamesagnew 2014-03-13 17:33:12 -04:00
parent 01b3b175e9
commit f0214399ca
31 changed files with 2766 additions and 225 deletions

View File

@ -157,7 +157,8 @@ class ModelScanner {
ResourceDef resourceDefinition = theClass.getAnnotation(ResourceDef.class);
if (resourceDefinition != null) {
if (!IResource.class.isAssignableFrom(theClass)) {
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": " + theClass.getCanonicalName());
throw new ConfigurationException("Resource type contains a @" + ResourceDef.class.getSimpleName() + " annotation but does not implement " + IResource.class.getCanonicalName() + ": "
+ theClass.getCanonicalName());
}
@SuppressWarnings("unchecked")
Class<? extends IResource> resClass = (Class<? extends IResource>) theClass;
@ -175,7 +176,8 @@ class ModelScanner {
Class<? extends IPrimitiveDatatype<?>> resClass = (Class<? extends IPrimitiveDatatype<?>>) theClass;
scanPrimitiveDatatype(resClass, datatypeDefinition);
} else {
throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": " + theClass.getCanonicalName());
throw new ConfigurationException("Resource type contains a @" + DatatypeDef.class.getSimpleName() + " annotation but does not implement " + IDatatype.class.getCanonicalName() + ": "
+ theClass.getCanonicalName());
}
}
@ -186,7 +188,8 @@ class ModelScanner {
Class<? extends ICodeEnum> resClass = (Class<? extends ICodeEnum>) theClass;
scanCodeTable(resClass, codeTableDefinition);
} else {
throw new ConfigurationException("Type contains a @" + CodeTableDef.class.getSimpleName() + " annotation but does not implement " + ICodeEnum.class.getCanonicalName() + ": " + theClass.getCanonicalName());
throw new ConfigurationException("Type contains a @" + CodeTableDef.class.getSimpleName() + " annotation but does not implement " + ICodeEnum.class.getCanonicalName() + ": "
+ theClass.getCanonicalName());
}
}
@ -197,7 +200,8 @@ class ModelScanner {
Class<? extends IResourceBlock> blockClass = (Class<? extends IResourceBlock>) theClass;
scanBlock(blockClass, blockDefinition);
} else {
throw new ConfigurationException("Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": " + theClass.getCanonicalName());
throw new ConfigurationException("Type contains a @" + Block.class.getSimpleName() + " annotation but does not implement " + IResourceBlock.class.getCanonicalName() + ": "
+ theClass.getCanonicalName());
}
}
@ -288,8 +292,8 @@ class ModelScanner {
}
@SuppressWarnings("unchecked")
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Set<String> elementNames, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef,
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToExtensionDef) {
private void scanCompositeElementForChildren(Class<? extends ICompositeElement> theClass, BaseRuntimeElementCompositeDefinition<?> theDefinition, Set<String> elementNames,
TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToElementDef, TreeMap<Integer, BaseRuntimeDeclaredChildDefinition> theOrderToExtensionDef) {
int baseElementOrder = theOrderToElementDef.isEmpty() ? 0 : theOrderToElementDef.lastEntry().getKey() + 1;
for (Field next : theClass.getDeclaredFields()) {
@ -314,9 +318,7 @@ class ModelScanner {
}
/*
* Anything that's marked as unknown is given a new ID that is <0 so
* that it doesn't conflict wityh any given IDs and can be figured
* out later
* Anything that's marked as unknown is given a new ID that is <0 so that it doesn't conflict wityh any given IDs and can be figured out later
*/
while (order == Child.ORDER_UNKNOWN && orderMap.containsKey(order)) {
order--;
@ -328,7 +330,8 @@ class ModelScanner {
}
if (orderMap.containsKey(order)) {
throw new ConfigurationException("Detected duplicate field order '" + childAnnotation.order() + "' for element named '" + elementName + "' in type '" + theClass.getCanonicalName() + "'");
throw new ConfigurationException("Detected duplicate field order '" + childAnnotation.order() + "' for element named '" + elementName + "' in type '" + theClass.getCanonicalName()
+ "'");
}
if (elementNames.contains(elementName)) {
@ -352,7 +355,8 @@ class ModelScanner {
* Child is an extension
*/
Class<? extends IElement> et = (Class<? extends IElement>) nextElementType;
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName, extensionAttr.url(), et);
RuntimeChildDeclaredExtensionDefinition def = new RuntimeChildDeclaredExtensionDefinition(next, childAnnotation, descriptionAnnotation, extensionAttr, elementName,
extensionAttr.url(), et);
orderMap.put(order, def);
if (IElement.class.isAssignableFrom(nextElementType)) {
addScanAlso((Class<? extends IElement>) nextElementType);
@ -374,8 +378,7 @@ class ModelScanner {
} else if (IResourceBlock.class.isAssignableFrom(nextElementType)) {
/*
* Child is a resource block (i.e. a sub-tag within a resource)
* TODO: do these have a better name according to HL7?
* Child is a resource block (i.e. a sub-tag within a resource) TODO: do these have a better name according to HL7?
*/
Class<? extends IResourceBlock> blockDef = (Class<? extends IResourceBlock>) nextElementType;
@ -407,7 +410,8 @@ class ModelScanner {
CodeableConceptElement concept = next.getAnnotation(CodeableConceptElement.class);
if (concept != null) {
if (!ICodedDatatype.class.isAssignableFrom(nextDatatype)) {
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName() + " but type is not a subtype of " + ICodedDatatype.class.getName());
throw new ConfigurationException("Field '" + elementName + "' in type '" + theClass.getCanonicalName() + "' is marked as @" + CodeableConceptElement.class.getCanonicalName()
+ " but type is not a subtype of " + ICodedDatatype.class.getName());
} else {
Class<? extends ICodeEnum> type = concept.type();
myScanAlsoCodeTable.add(type);
@ -457,17 +461,21 @@ class ModelScanner {
if (myNameToResourceDefinitions.containsKey(resourceName)) {
if (!myNameToResourceDefinitions.get(resourceName).getImplementingClass().equals(theClass)) {
throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '" + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
}
// throw new ConfigurationException("Detected duplicate element name '" + resourceName + "' in types '" + theClass.getCanonicalName() + "' and '"
// + myNameToResourceDefinitions.get(resourceName).getImplementingClass() + "'");
} else {
return resourceName;
}
}
String resourceId = resourceDefinition.id();
if (isBlank(resourceId)) {
throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource ID: " + theClass.getCanonicalName());
}
// throw new ConfigurationException("Resource type @" + ResourceDef.class.getSimpleName() + " annotation contains no resource ID: " + theClass.getCanonicalName());
} else {
if (myIdToResourceDefinition.containsKey(resourceId)) {
throw new ConfigurationException("The following resource types have the same ID of '" + resourceId + "' - " + theClass.getCanonicalName() + " and " + myIdToResourceDefinition.get(resourceId).getImplementingClass().getCanonicalName());
throw new ConfigurationException("The following resource types have the same ID of '" + resourceId + "' - " + theClass.getCanonicalName() + " and "
+ myIdToResourceDefinition.get(resourceId).getImplementingClass().getCanonicalName());
}
}
RuntimeResourceDefinition resourceDef = new RuntimeResourceDefinition(theClass, resourceDefinition);

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.model.api;
package ca.uhn.fhir.model.dstu.resource;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
@ResourceDef(name="Binary", profile="http://hl7.org/fhir/profiles/Binary", id="binary")

View File

@ -3,7 +3,7 @@ package ca.uhn.fhir.model.primitive;
import ca.uhn.fhir.model.api.IValueSetEnumBinder;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
@DatatypeDef(name = "code")
@DatatypeDef(name = "boundCode") // note: this name is not real, it's a HAPI identifier- we should remove it
public class BoundCodeDt<T extends Enum<?>> extends CodeDt {
private IValueSetEnumBinder<T> myBinder;

View File

@ -32,6 +32,7 @@
<item name="RESTful Server" href="./doc_rest_server.html"/>
<item name="RESTful Client" href="./doc_rest_client.html"/>
<item name="RESTful Operations" href="./doc_rest_operations.html"/>
<item name="Tinder Code Generator" href="./doc_tinder.html"/>
<item name="JavaDocs" href="./apidocs/index.html"/>
</menu>

View File

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
<properties>
<title>Tinder - HAPI FHIR</title>
<author email="jamesagnew@users.sourceforge.net">James Agnew</author>
</properties>
<body>
<section name="Tinder">
<macro name="toc">
</macro>
<p>
According to the FHIR specification, any conformant server
must be able to export a Conformance statement, which
indicates all of the resource types and potential operations
that the server supports.
</p>
<p>
HAPI provides a Maven plugin called "Tinder" which is able to automatically
generate a client based on that conformance statement.
</p>
</section>
<section name="Client Generation">
<p>
The following example shows a simple Maven plugin which
builds a client for the Health Intersections reference
server.
</p>
<source><![CDATA[<plugins>
<plugin>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-tinder-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<goals><goal>generate-structures</goal></goals>
<configuration>
<clientClassName>ca.uhn.hitest.HiTest</clientClassName>
<serverBaseHref>http://fhir.healthintersections.com.au/open</serverBaseHref>
<generateSearchForAllParams>true</generateSearchForAllParams>
</configuration>
</execution>
</executions>
</plugin>
</plugins>]]></source>
<p>
This example will create a class called
<code>ca.uhn.hitest.HiTest</code> which has
methods to invoke the various server operations.
</p>
<p>
It is then possible to use this client as simply as:
</p>
<source><![CDATA[// Instantiate the client
FhirContext ctx = new FhirContext(Patient.class);
IRestfulClientFactory clientFactory = ctx.newRestfulClientFactory();
ClientClass client = clientFactory.newClient(ClientClass.class, "http://fhir.healthintersections.com.au/open");
// Invoke the client
Bundle bundle = client.searchPatientByGender(new StringDt("M"));
System.out.println(bundle.getEntries().size());
// Prints: 50
Patient patientOne = (Patient) bundle.getEntries().get(0).getResource();
System.out.println(patientOne.getName().get(0).getFamily().get(0).getValue());
// Prints: Chalmers]]></source>
</section>
</body>
</document>

View File

@ -53,6 +53,7 @@
<baseResourceName>substance</baseResourceName>
<baseResourceName>valueset</baseResourceName>
</baseResourceNames>
<buildDatatypes>true</buildDatatypes>
</configuration>
</plugin>
</plugins>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="**/*.java" kind="src" path="src/test/resources"/>
<classpathentry kind="src" path="target/gen"/>
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>

View File

@ -97,6 +97,23 @@
<maven_version>3.1.1</maven_version>
</properties>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<reportSets>
<reportSet>
<reports>
<report>report</report>
</reports>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
<build>
<plugins>
<plugin>

View File

@ -1,6 +1,7 @@
package ca.uhn.fhir.tinder;
import static org.apache.commons.lang.StringUtils.*;
import static org.apache.commons.lang.StringUtils.defaultString;
import static org.apache.commons.lang.StringUtils.isNotBlank;
import java.io.File;
import java.io.FileWriter;
@ -10,8 +11,10 @@ import java.io.InputStreamReader;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
@ -24,36 +27,44 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.UndeclaredExtension;
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
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.Composite;
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.SimpleChild;
import ca.uhn.fhir.tinder.model.SimpleSetter.Parameter;
public abstract class BaseStructureParser {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseStructureParser.class);
private ArrayList<Extension> myExtensions;
private List<Resource> myResources = new ArrayList<Resource>();
private TreeSet<String> myImports = new TreeSet<String>();
private Map<String, String> myLocallyDefinedClassNames = new HashMap<String, String>();
private List<BaseRootType> myResources = new ArrayList<BaseRootType>();
public void bindValueSets(ValueSetGenerator theVsp) {
for (Resource next : myResources) {
bindValueSets(next, theVsp);
}
}
public void addResource(Resource theResource) {
public void addResource(BaseRootType theResource) {
myResources.add(theResource);
}
public Map<String, String> getLocalImports() {
return myLocallyDefinedClassNames;
}
private void bindValueSets(BaseElement theResource, ValueSetGenerator theVsp) {
if (isNotBlank(theResource.getBinding())) {
String bindingClass = theVsp.getClassForValueSetIdAndMarkAsNeeded(theResource.getBinding());
if (bindingClass != null) {
ourLog.info("Adding binding ValueSet class: {}", bindingClass);
theResource.setBindingClass(bindingClass);
myImports.add(bindingClass);
myLocallyDefinedClassNames.put(bindingClass, "valueset");
} else {
ourLog.info("No binding found for: {}", theResource.getBinding());
ourLog.info(" * Valid: {}", new TreeSet<String>(theVsp.getValueSets().keySet()));
@ -64,6 +75,86 @@ public abstract class BaseStructureParser {
}
}
public void bindValueSets(ValueSetGenerator theVsp) {
for (BaseRootType next : myResources) {
bindValueSets(next, theVsp);
}
}
private ca.uhn.fhir.model.api.annotation.SimpleSetter.Parameter findAnnotation(Class<?> theBase, Annotation[] theAnnotations,
Class<ca.uhn.fhir.model.api.annotation.SimpleSetter.Parameter> theClass) {
for (Annotation next : theAnnotations) {
if (theClass.equals(next.annotationType())) {
return (ca.uhn.fhir.model.api.annotation.SimpleSetter.Parameter) next;
}
}
throw new IllegalArgumentException(theBase.getCanonicalName() + " has @" + SimpleSetter.class.getCanonicalName() + " constructor with no/invalid parameter annotation");
}
protected abstract String getFilenameSuffix();
public List<BaseRootType> getResources() {
return myResources;
}
protected abstract String getTemplate();
protected boolean isSpreadsheet(String theFileName) {
return true;
}
private void scanForImportsNames(BaseElement theNext) throws MojoFailureException {
for (BaseElement next : theNext.getChildren()) {
ourLog.info("Element Name: {}", next.getName());
if (next instanceof SimpleChild) {
for (String nextType : next.getType()) {
if (((SimpleChild) next).isBoundCode()) {
scanForImportsNames(((SimpleChild) next).getBoundDatatype());
}
if (next.isResourceRef()) {
scanForImportsNames(ResourceReferenceDt.class.getSimpleName());
}
scanForImportsNames(nextType);
}
}
scanForImportsNames(next);
}
}
private void scanForImportsNames(String nextType) throws MojoFailureException {
if ("Any".equals(nextType)) {
myImports.add(IResource.class.getCanonicalName());
return;
}
if ("ExtensionDt".equals(nextType)) {
myImports.add(UndeclaredExtension.class.getCanonicalName());
return;
}
if (myLocallyDefinedClassNames.containsKey(nextType)) {
myImports.add(nextType);
} else {
try {
String type = "ca.uhn.fhir.model.dstu.composite." + nextType;
Class.forName(type);
myImports.add(type);
} catch (ClassNotFoundException e) {
try {
String type = "ca.uhn.fhir.model.dstu.resource." + nextType;
Class.forName(type);
myImports.add(type);
} catch (ClassNotFoundException e1) {
String type = "ca.uhn.fhir.model.primitive." + nextType;
try {
Class.forName(type);
myImports.add(type);
} catch (ClassNotFoundException e2) {
throw new MojoFailureException("Unknown type: " + nextType);
}
}
}
}
}
protected void scanForSimpleSetters(Child theElem) {
Class<?> childDt;
@ -103,51 +194,6 @@ public abstract class BaseStructureParser {
}
}
public List<Resource> getResources() {
return myResources;
}
private ca.uhn.fhir.model.api.annotation.SimpleSetter.Parameter findAnnotation(Class<?> theBase, Annotation[] theAnnotations, Class<ca.uhn.fhir.model.api.annotation.SimpleSetter.Parameter> theClass) {
for (Annotation next : theAnnotations) {
if (theClass.equals(next.annotationType())) {
return (ca.uhn.fhir.model.api.annotation.SimpleSetter.Parameter) next;
}
}
throw new IllegalArgumentException(theBase.getCanonicalName() + " has @" + SimpleSetter.class.getCanonicalName() + " constructor with no/invalid parameter annotation");
}
public void setExtensions(ArrayList<Extension> theExts) {
myExtensions = theExts;
}
public void writeAll(File theOutputDirectory, String thePackageBase) throws MojoFailureException {
if (!theOutputDirectory.exists()) {
theOutputDirectory.mkdirs();
}
if (!theOutputDirectory.isDirectory()) {
throw new MojoFailureException(theOutputDirectory + " is not a directory");
}
for (Resource next : myResources) {
scanForTypeNameConflicts(next);
File f = new File(theOutputDirectory, next.getName() + getFilenameSuffix() + ".java");
try {
write(next, f, thePackageBase);
} catch (IOException e) {
throw new MojoFailureException("Failed to write structure", e);
}
}
}
private void scanForTypeNameConflicts(Resource theNext) {
Set<String> typeNames = new HashSet<String>();
typeNames.add(theNext.getName());
scanForTypeNameConflicts(theNext,typeNames);
}
private void scanForTypeNameConflicts(BaseElement theResourceBlock, Set<String> theTypeNames) {
for (BaseElement nextChild : theResourceBlock.getChildren()) {
if (nextChild instanceof ResourceBlock) {
@ -166,16 +212,34 @@ public abstract class BaseStructureParser {
}
}
protected abstract String getFilenameSuffix();
private void scanForTypeNameConflicts(BaseRootType theNext) {
Set<String> typeNames = new HashSet<String>();
typeNames.add(theNext.getName());
scanForTypeNameConflicts(theNext, typeNames);
}
private void write(Resource theResource, File theFile, String thePackageBase) throws IOException {
public void setExtensions(ArrayList<Extension> theExts) {
myExtensions = theExts;
}
private void write(BaseRootType theResource, File theFile, String thePackageBase) throws IOException {
FileWriter w = new FileWriter(theFile, false);
ourLog.info("Writing file: {}", theFile.getAbsolutePath());
ArrayList<String> imports = new ArrayList<String>();
for (String next : myImports) {
if (next.contains(".")) {
imports.add(next);
} else {
imports.add(thePackageBase + "." + myLocallyDefinedClassNames.get(next) + "." + next);
}
}
VelocityContext ctx = new VelocityContext();
ctx.put("includeDescriptionAnnotations", true);
ctx.put("packageBase", thePackageBase);
ctx.put("imports", imports);
ctx.put("profile", theResource.getProfile());
ctx.put("id", StringUtils.defaultString(theResource.getId()));
ctx.put("className", theResource.getName());
@ -199,8 +263,41 @@ public abstract class BaseStructureParser {
w.close();
}
protected abstract String getTemplate();
public void markResourcesForImports() {
for (BaseRootType next : myResources) {
if (next instanceof Resource) {
myLocallyDefinedClassNames.put(next.getName(), "resource");
} else if (next instanceof Composite) {
myLocallyDefinedClassNames.put(next.getName() + "Dt", "composite");
} else {
throw new IllegalStateException(next.getClass() + "");
}
}
}
public void writeAll(File theOutputDirectory, String thePackageBase) throws MojoFailureException {
if (!theOutputDirectory.exists()) {
theOutputDirectory.mkdirs();
}
if (!theOutputDirectory.isDirectory()) {
throw new MojoFailureException(theOutputDirectory + " is not a directory");
}
for (BaseRootType next : myResources) {
scanForImportsNames(next);
}
for (BaseRootType next : myResources) {
scanForTypeNameConflicts(next);
File f = new File(theOutputDirectory, next.getName() + getFilenameSuffix() + ".java");
try {
write(next, f, thePackageBase);
} catch (IOException e) {
throw new MojoFailureException("Failed to write structure", e);
}
}
}
static String cellValue(Node theRowXml, int theCellIndex) {
NodeList cells = ((Element) theRowXml).getElementsByTagName("Cell");
@ -229,8 +326,19 @@ public abstract class BaseStructureParser {
return null;
}
protected boolean isSpreadsheet(String theFileName) {
return true;
public static void main(String[] args) throws Exception {
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.setTargetDirectory(base + "target/generated-sources/tinder");
m.setBuildDatatypes(true);
m.execute();
}
}

View File

@ -13,10 +13,11 @@ import org.w3c.dom.NodeList;
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.Resource;
import ca.uhn.fhir.tinder.model.BaseRootType;
import ca.uhn.fhir.tinder.model.ResourceBlock;
import ca.uhn.fhir.tinder.model.ResourceBlockCopy;
import ca.uhn.fhir.tinder.model.SearchParameter;
import ca.uhn.fhir.tinder.model.SimpleChild;
import ca.uhn.fhir.tinder.util.XMLUtils;
public abstract class BaseStructureSpreadsheetParser extends BaseStructureParser {
@ -46,7 +47,7 @@ public abstract class BaseStructureSpreadsheetParser extends BaseStructureParser
Element resourceRow = (Element) rows.item(1);
Resource resource = new Resource();
BaseRootType resource = createRootType();
addResource(resource);
parseParameters(file, resource);
@ -83,7 +84,7 @@ public abstract class BaseStructureSpreadsheetParser extends BaseStructureParser
} else if (type.equals("*")) {
elem = new AnyChild();
} else {
elem = new Child();
elem = new SimpleChild();
}
parseBasicElements(nextRow, elem);
@ -110,7 +111,9 @@ public abstract class BaseStructureSpreadsheetParser extends BaseStructureParser
}
private void parseParameters(Document theFile, Resource theResource) {
protected abstract BaseRootType createRootType();
private void parseParameters(Document theFile, BaseRootType theResource) {
NodeList sheets = theFile.getElementsByTagName("Worksheet");
for (int i = 0; i < sheets.getLength(); i++) {
Element sheet = (Element) sheets.item(i);

View File

@ -4,6 +4,10 @@ import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import ca.uhn.fhir.tinder.model.BaseRootType;
import ca.uhn.fhir.tinder.model.Composite;
public class DatatypeGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetParser {
@ -41,5 +45,10 @@ public class DatatypeGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP
return retVal;
}
@Override
protected BaseRootType createRootType() {
return new Composite();
}
}

View File

@ -3,7 +3,9 @@ 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.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -25,9 +27,11 @@ import ca.uhn.fhir.model.dstu.valueset.DataTypeEnum;
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.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;
@ -101,8 +105,8 @@ public class ProfileParser extends BaseStructureParser {
// }
}
public Resource parseSingleProfile(Profile theProfile, String theUrlTOThisProfile) throws Exception {
Resource retVal = null;
public BaseRootType parseSingleProfile(Profile theProfile, String theUrlTOThisProfile) throws Exception {
BaseRootType retVal = null;
for (Structure nextStructure : theProfile.getStructure()) {
int elemIdx = 0;
@ -135,10 +139,10 @@ public class ProfileParser extends BaseStructureParser {
// 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 if (next.getDefinition().getType().get(0).getCode().getValue().equals("Extension")) {
elem = new UndeclaredExtensionChild();
} else {
elem = new Child();
elem = new SimpleChild();
}
elem.setName(next.getPath().getValue());
@ -251,7 +255,7 @@ public class ProfileParser extends BaseStructureParser {
*/
scanForSimpleSetters(child);
} else {
Resource res = (Resource) elem;
BaseRootType res = (BaseRootType) elem;
elements.put(res.getName(), res);
}
@ -264,25 +268,14 @@ public class ProfileParser extends BaseStructureParser {
}
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);
ProfileParser pp = new ProfileParser();
pp.parseSingleProfile(prof, "http://foo");
pp.markResourcesForImports();
pp.writeAll(new File("target/gen"), "test");
// FhirContext fhirContext = new FhirContext(Profile.class);
// XmlParser parser = fhirContext.newXmlParser();
//
// String file = IOUtils.toString(new
// FileReader("src/test/resources/prof/organization.xml"));
// Profile text = (Profile) parser.parseResource(file);
//
// ValueSetGenerator vsp = new ValueSetGenerator();
// vsp.setDirectory("src/test/resources/vs/");
// vsp.parse();
//
// ProfileParser p = new ProfileParser();
// p.parseSingleProfile(text,
// "http://fhir.connectinggta.ca/static/Profile/organization.xml");
// p.bindValueSets(vsp);
// p.writeAll("target/generated/valuesets/ca/uhn/fhir/model/dstu/resource");
//
// vsp.writeMarkedValueSets("target/generated/valuesets/ca/uhn/fhir/model/dstu/valueset");
}
}

View File

@ -9,6 +9,9 @@ import java.util.List;
import org.apache.maven.plugin.MojoFailureException;
import ca.uhn.fhir.tinder.model.BaseRootType;
import ca.uhn.fhir.tinder.model.Resource;
public class ResourceGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetParser {
@ -150,4 +153,9 @@ public class ResourceGeneratorUsingSpreadsheet extends BaseStructureSpreadsheetP
}
}
@Override
protected BaseRootType createRootType() {
return new Resource();
}
}

View File

@ -8,6 +8,7 @@ import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.ParseException;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
@ -26,7 +27,7 @@ import ca.uhn.fhir.model.dstu.resource.Profile;
import ca.uhn.fhir.model.dstu.valueset.RestfulConformanceModeEnum;
import ca.uhn.fhir.rest.client.IRestfulClientFactory;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.tinder.model.Resource;
import ca.uhn.fhir.tinder.model.BaseRootType;
import ca.uhn.fhir.tinder.model.RestResourceTm;
import ca.uhn.fhir.tinder.model.SearchParameter;
@ -86,7 +87,13 @@ public class TinderClientMojo extends AbstractMojo {
throw new MojoFailureException("Conformance mode is not server, found: " + rest.getMode().getValue());
}
ProfileParser pp = new ProfileParser();
int index = 0;
for (RestResource nextResource : rest.getResource()) {
if (StringUtils.isBlank(nextResource.getProfile().getResourceUrl())) {
continue;
}
RestResourceTm nextTmResource = new RestResourceTm(nextResource);
myResources.add(nextTmResource);
@ -98,13 +105,9 @@ public class TinderClientMojo extends AbstractMojo {
throw new MojoFailureException("Failed to load resource profile: " + nextResource.getProfile().getReference().getValue(), e);
}
ProfileParser pp = new ProfileParser();
Resource resourceModel;
BaseRootType resourceModel;
try {
resourceModel = pp.parseSingleProfile(profile, nextResource.getProfile().getResourceUrl());
File resourceDir = new File(myDirectoryBase, "resource");
resourceDir.mkdirs();
pp.writeAll(resourceDir, myPackageBase);
} catch (Exception e) {
throw new MojoFailureException("Failed to load resource profile: " + nextResource.getProfile().getReference().getValue(), e);
}
@ -116,6 +119,11 @@ public class TinderClientMojo extends AbstractMojo {
}
}
File resourceDir = new File(myDirectoryBase, "resource");
resourceDir.mkdirs();
pp.markResourcesForImports();
pp.writeAll(resourceDir, myPackageBase);
try {
write();
} catch (IOException e) {
@ -181,6 +189,7 @@ public class TinderClientMojo extends AbstractMojo {
mojo.clientClassName = "ca.uhn.test.ClientClass";
mojo.targetDirectory = new File("target/gen");
mojo.serverBaseHref = "http://fhir.healthintersections.com.au/open";
mojo.generateSearchForAllParams = true;
mojo.execute();
}

View File

@ -1,7 +1,10 @@
package ca.uhn.fhir.tinder;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.AbstractMojo;
@ -18,24 +21,27 @@ public class TinderStructuresMojo extends AbstractMojo {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderStructuresMojo.class);
@Parameter(alias = "package", required = true)
private String packageName;
@Parameter(alias = "targetDirectory", required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
private String targetDirectory;
@Parameter(alias="resourceValueSetFiles", required = false)
private List<String> resourceValueSetFiles;
@Parameter(alias = "baseResourceNames", required = true)
@Parameter(required = false)
private List<String> baseResourceNames;
@Parameter(alias = "resourceProfileFiles", required = false)
private List<String> resourceProfileFiles;
@Parameter(required = false, defaultValue="false")
private boolean buildDatatypes;
@Component
private MavenProject myProject;
@Parameter(alias = "package", required = true)
private String packageName;
@Parameter(required = false)
private List<String> resourceProfileFiles;
@Parameter(required = false)
private List<String> resourceValueSetFiles;
@Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
private String targetDirectory;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (StringUtils.isBlank(packageName)) {
@ -62,37 +68,57 @@ public class TinderStructuresMojo extends AbstractMojo {
ourLog.info("Loading Datatypes...");
DatatypeGeneratorUsingSpreadsheet dtp = new DatatypeGeneratorUsingSpreadsheet();
Map<String, String> datatypeLocalImports = new HashMap<String, String>();
DatatypeGeneratorUsingSpreadsheet dtp = null;
if (buildDatatypes) {
dtp = new DatatypeGeneratorUsingSpreadsheet();
try {
dtp.parse();
dtp.markResourcesForImports();
} catch (Exception e) {
throw new MojoFailureException("Failed to load datatypes", e);
}
dtp.bindValueSets(vsp);
datatypeLocalImports = dtp.getLocalImports();
}
if (baseResourceNames != null && baseResourceNames.size() > 0) {
ourLog.info("Loading Resources...");
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet();
try {
rp.setBaseResourceNames(baseResourceNames);
rp.parse();
rp.markResourcesForImports();
} catch (Exception e) {
throw new MojoFailureException("Failed to load resources", e);
}
rp.bindValueSets(vsp);
rp.getLocalImports().putAll(datatypeLocalImports);
datatypeLocalImports.putAll(rp.getLocalImports());
ourLog.info("Writing Resources...");
rp.writeAll(new File(directoryBase, "resource"), packageName);
}
if (resourceProfileFiles != null) {
ourLog.info("Loading profiles...");
ProfileParser pp = new ProfileParser();
pp.parseBaseResources(resourceProfileFiles);
pp.bindValueSets(vsp);
pp.markResourcesForImports();
pp.getLocalImports().putAll(datatypeLocalImports);
datatypeLocalImports.putAll(pp.getLocalImports());
pp.writeAll(new File(directoryBase, "resource"), packageName);
}
ourLog.info("Writing Resources...");
rp.writeAll(new File(directoryBase, "resource"), packageName);
if (dtp != null) {
ourLog.info("Writing Composite Datatypes...");
dtp.writeAll(new File(directoryBase, "composite"), packageName);
}
ourLog.info("Writing ValueSet Enums...");
vsp.writeMarkedValueSets(new File(directoryBase, "valueset"), packageName);
@ -100,6 +126,54 @@ public class TinderStructuresMojo extends AbstractMojo {
myProject.addCompileSourceRoot(targetDirectory);
}
public List<String> getBaseResourceNames() {
return baseResourceNames;
}
public String getPackageName() {
return packageName;
}
public List<String> getResourceProfileFiles() {
return resourceProfileFiles;
}
public List<String> getResourceValueSetFiles() {
return resourceValueSetFiles;
}
public String getTargetDirectory() {
return targetDirectory;
}
public boolean isBuildDatatypes() {
return buildDatatypes;
}
public void setBaseResourceNames(List<String> theBaseResourceNames) {
baseResourceNames = theBaseResourceNames;
}
public void setBuildDatatypes(boolean theBuildDatatypes) {
buildDatatypes = theBuildDatatypes;
}
public void setPackageName(String thePackageName) {
packageName = thePackageName;
}
public void setResourceProfileFiles(List<String> theResourceProfileFiles) {
resourceProfileFiles = theResourceProfileFiles;
}
public void setResourceValueSetFiles(List<String> theResourceValueSetFiles) {
resourceValueSetFiles = theResourceValueSetFiles;
}
public void setTargetDirectory(String theTargetDirectory) {
targetDirectory = theTargetDirectory;
}
public static void main(String[] args) throws Exception {
// ValueSetGenerator vsp = new ValueSetGenerator();

View File

@ -0,0 +1,41 @@
package ca.uhn.fhir.tinder.model;
import java.util.ArrayList;
import java.util.List;
public abstract class BaseRootType extends BaseElement {
private String myId;
private String myProfile;
private List<SearchParameter> mySearchParameters;
public String getId() {
return myId;
}
public String getProfile() {
return myProfile;
}
public List<SearchParameter> getSearchParameters() {
if (mySearchParameters == null) {
mySearchParameters = new ArrayList<SearchParameter>();
}
return mySearchParameters;
}
@Override
public String getTypeSuffix() {
return "";
}
public void setId(String theId) {
myId = theId;
}
public void setProfile(String theProfile) {
myProfile = theProfile;
}
}

View File

@ -7,8 +7,9 @@ import java.util.List;
import org.apache.commons.lang3.StringUtils;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
public class Child extends BaseElement {
public abstract class Child extends BaseElement {
private List<SimpleSetter> mySimpleStters = new ArrayList<SimpleSetter>();
@ -69,7 +70,7 @@ public class Child extends BaseElement {
public String getReferenceType() {
String retVal;
if (this.isResourceRef()) {
retVal = "ResourceReferenceDt"; // (ResourceReferenceDt.class.getSimpleName());
retVal = ResourceReferenceDt.class.getSimpleName();
} else if (this.getType().size() == 1 || this instanceof ResourceBlock) {
if (isBoundCode()) {
retVal = "Bound" + getSingleType() + "<" + getBindingClass() + ">";

View File

@ -0,0 +1,5 @@
package ca.uhn.fhir.tinder.model;
public class Composite extends BaseRootType {
}

View File

@ -1,40 +1,5 @@
package ca.uhn.fhir.tinder.model;
import java.util.ArrayList;
import java.util.List;
public class Resource extends BaseElement {
private String myId;
private String myProfile;
private List<SearchParameter> mySearchParameters;
public String getId() {
return myId;
}
public String getProfile() {
return myProfile;
}
public List<SearchParameter> getSearchParameters() {
if (mySearchParameters == null) {
mySearchParameters = new ArrayList<SearchParameter>();
}
return mySearchParameters;
}
@Override
public String getTypeSuffix() {
return "";
}
public void setId(String theId) {
myId = theId;
}
public void setProfile(String theProfile) {
myProfile = theProfile;
}
public class Resource extends BaseRootType {
}

View File

@ -15,7 +15,7 @@ public class SearchParameter {
}
public String getConstantName() {
return "SP_" + myName.toUpperCase().replace("-[X]", "_X").replace('-', '_').replace("!", "");
return "SP_" + myName.toUpperCase().replace("_[X]", "_X").replace("-[X]", "_X").replace('-', '_').replace("!", "");
}
public String getName() {
@ -23,7 +23,7 @@ public class SearchParameter {
}
public String getNameCapitalized() {
return WordUtils.capitalize(myName);
return WordUtils.capitalize(myName).replace("_[x]", "").replace("-[x]", "").replace("_[X]", "").replace("-[X]", "").replace('-', '_').replace("!", "");
}
public String getPath() {

View File

@ -0,0 +1,5 @@
package ca.uhn.fhir.tinder.model;
public class SimpleChild extends Child {
}

View File

@ -11,7 +11,7 @@ import ${packageBase}.resource.*;
/**
* Restful Client Definition Class
*/
public interface ${className} extends IMetadataClient {
public interface ${className} extends IBasicClient {
#foreach ( $resource in ${resources} )
#if ( ${resource.hasReadOperation} )
@ -47,6 +47,7 @@ public interface ${className} extends IMetadataClient {
*/
@Read
${resource.resourceType} get${resource.resourceType}ById(@Read.IdParam IdDt theId, @Read.VersionIdParam IdDt theVersionId);
#end
#if ( ${resource.hasSearchOperation} )
#foreach ( $param in $resource.searchParams )
@ -58,8 +59,8 @@ public interface ${className} extends IMetadataClient {
* </p>
#end
*/
@Search
${resource.resourceType} search${resource.resourceType}By${param.nameCapitalized}(@Required(name=${resource.resourceType}.${param.constantName}) StringDt the${param.nameCapitalized});
@Search(type=${resource.resourceType}.class)
Bundle search${resource.resourceType}By${param.nameCapitalized}(@Required(name=${resource.resourceType}.${param.constantName}) StringDt the${param.nameCapitalized});
#end
#end

View File

@ -5,9 +5,10 @@ package ${packageBase}.composite;
import java.util.*;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.model.primitive.*;
import ${packageBase}.valueset.*;
import ${packageBase}.resource.*;
#foreach ( $import in $imports )
import ${import};
#end
/**
* HAPI/FHIR <b>${className}</b> Datatype

View File

@ -2,14 +2,17 @@
package ${packageBase}.resource;
import java.util.*;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.model.primitive.*;
//import ca.uhn.fhir.model.dstu.composite.*;
import ${packageBase}.composite.*;
import ${packageBase}.valueset.*;
#foreach ( $import in $imports )
import ${import};
#end
##import ${packageBase}.composite.*;
##import ${packageBase}.valueset.*;
/**
* HAPI/FHIR <b>${className}</b> Resource

View File

@ -0,0 +1,484 @@
<?xml version="1.0" encoding="UTF-8"?>
<Profile xmlns="http://hl7.org/fhir">
<text>
<status value="generated"/>
<div xmlns="http://www.w3.org/1999/xhtml">&#x0A;
<pre>&#x0A;&lt;&#x0A;
<a title="A description of a query with a set of parameters." class="dict" href="query-definitions.html#Query">&#x0A;
<b>Query</b>&#x0A; </a> xmlns="http://hl7.org/fhir"&gt; &#x0A;
<span style="float: right">&#x0A;
<a title="Documentation for this format" href="formats.html">&#x0A;
<img alt="doco" src="help.png"/>&#x0A; </a>&#x0A; </span>&#x0A; &lt;!-- from &#x0A;
<a href="resources.html">Resource</a>: &#x0A;
<a href="extensibility.html">extension</a>, &#x0A;
<a href="extensibility.html#modifierExtension">modifierExtension</a>, language, &#x0A;
<a href="narrative.html#Narrative">text</a>, and &#x0A;
<a href="references.html#contained">contained</a> --&gt;&#x0A; &lt;&#x0A;
<a title="Links query and its response(s)." class="dict" href="query-definitions.html#Query.identifier">&#x0A;
<b>identifier</b>&#x0A; </a> value="[&#x0A;
<span style="color: darkgreen">&#x0A;
<a href="datatypes.html#uri">uri</a>&#x0A; </span>]"/&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>1..1</b>&#x0A; </span> &#x0A;
<span style="color: navy">Links query and its response(s)</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&#x0A; &lt;&#x0A;
<a title="Set of query parameters with values." class="dict" href="query-definitions.html#Query.parameter">&#x0A;
<b>parameter</b>&#x0A; </a>&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>1..*</b>&#x0A; </span> &#x0A;
<span style="color: darkgreen">&#x0A;
<a href="extensibility.html#Extension">Extension</a>&#x0A; </span> &#x0A;
<span style="color: navy">Set of query parameters with values</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&lt;/parameter&gt;&#x0A; &lt;&#x0A;
<a title="If this is a response to a query." class="dict" href="query-definitions.html#Query.response">&#x0A;
<b>response</b>&#x0A; </a>&gt; &#x0A;
<span style="color: Gray">&lt;!-- &#x0A;
<span style="color: brown">&#x0A;
<b>0..1</b>&#x0A; </span> If this is a response to a query --&gt;</span>&#x0A; &lt;&#x0A;
<a title="Links response to source query." class="dict" href="query-definitions.html#Query.response.identifier">&#x0A;
<b>identifier</b>&#x0A; </a> value="[&#x0A;
<span style="color: darkgreen">&#x0A;
<a href="datatypes.html#uri">uri</a>&#x0A; </span>]"/&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>1..1</b>&#x0A; </span> &#x0A;
<span style="color: navy">Links response to source query</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&#x0A; &lt;&#x0A;
<a title="Outcome of processing the query." class="dict" href="query-definitions.html#Query.response.outcome">&#x0A;
<b>outcome</b>&#x0A; </a> value="[&#x0A;
<span style="color: darkgreen">&#x0A;
<a href="datatypes.html#code">code</a>&#x0A; </span>]"/&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>1..1</b>&#x0A; </span> &#x0A;
<span style="color: navy">&#x0A;
<a style="color: navy" href="query-outcome.html">ok | limited | refused | error</a>&#x0A; </span>&#x0A;
<span style="color: Gray"> --&gt;</span>&#x0A; &lt;&#x0A;
<a title="Total number of matching records." class="dict" href="query-definitions.html#Query.response.total">&#x0A;
<b>total</b>&#x0A; </a> value="[&#x0A;
<span style="color: darkgreen">&#x0A;
<a href="datatypes.html#integer">integer</a>&#x0A; </span>]"/&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>0..1</b>&#x0A; </span> &#x0A;
<span style="color: navy">Total number of matching records</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&#x0A; &lt;&#x0A;
<a title="Parameters server used." class="dict" href="query-definitions.html#Query.response.parameter">&#x0A;
<b>parameter</b>&#x0A; </a>&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>0..*</b>&#x0A; </span> &#x0A;
<span style="color: darkgreen">&#x0A;
<a href="extensibility.html#Extension">Extension</a>&#x0A; </span> &#x0A;
<span style="color: navy">Parameters server used</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&lt;/parameter&gt;&#x0A; &lt;&#x0A;
<a title="To get first page (if paged)." class="dict" href="query-definitions.html#Query.response.first">&#x0A;
<b>first</b>&#x0A; </a>&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>0..*</b>&#x0A; </span> &#x0A;
<span style="color: darkgreen">&#x0A;
<a href="extensibility.html#Extension">Extension</a>&#x0A; </span> &#x0A;
<span style="color: navy">To get first page (if paged)</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&lt;/first&gt;&#x0A; &lt;&#x0A;
<a title="To get previous page (if paged)." class="dict" href="query-definitions.html#Query.response.previous">&#x0A;
<b>previous</b>&#x0A; </a>&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>0..*</b>&#x0A; </span> &#x0A;
<span style="color: darkgreen">&#x0A;
<a href="extensibility.html#Extension">Extension</a>&#x0A; </span> &#x0A;
<span style="color: navy">To get previous page (if paged)</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&lt;/previous&gt;&#x0A; &lt;&#x0A;
<a title="To get next page (if paged)." class="dict" href="query-definitions.html#Query.response.next">&#x0A;
<b>next</b>&#x0A; </a>&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>0..*</b>&#x0A; </span> &#x0A;
<span style="color: darkgreen">&#x0A;
<a href="extensibility.html#Extension">Extension</a>&#x0A; </span> &#x0A;
<span style="color: navy">To get next page (if paged)</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&lt;/next&gt;&#x0A; &lt;&#x0A;
<a title="To get last page (if paged)." class="dict" href="query-definitions.html#Query.response.last">&#x0A;
<b>last</b>&#x0A; </a>&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>0..*</b>&#x0A; </span> &#x0A;
<span style="color: darkgreen">&#x0A;
<a href="extensibility.html#Extension">Extension</a>&#x0A; </span> &#x0A;
<span style="color: navy">To get last page (if paged)</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&lt;/last&gt;&#x0A; &lt;&#x0A;
<a title="Resources that are the results of the search." class="dict" href="query-definitions.html#Query.response.reference">&#x0A;
<b>reference</b>&#x0A; </a>&gt;&#x0A;
<span style="color: Gray">&lt;!--</span> &#x0A;
<span style="color: brown">&#x0A;
<b>0..*</b>&#x0A; </span> &#x0A;
<span style="color: darkgreen">&#x0A;
<a href="references.html#Resource">Resource</a>(&#x0A;
<a href="resourcelist.html">Any</a>)</span> &#x0A;
<span style="color: navy">Resources that are the results of the search</span>&#x0A;
<span style="color: Gray"> --&gt;</span>&lt;/reference&gt;&#x0A; &lt;/response&gt;&#x0A;&lt;/Query&gt;&#x0A;</pre>&#x0A; </div>
</text>
<name value="query"/>
<publisher value="FHIR Project"/>
<description value="Basic Profile. A description of a query with a set of parameters."/>
<status value="draft"/>
<date value="2014-02-03"/>
<requirements value="Scope and Usage The resource is used to perform queries using messaging-based exchanges, and to perform asynchronous searches using the RESTful interface."/>
<mapping>
<identity value="rim"/>
<uri value="http://hl7.org/v3"/>
<name value="RIM"/>
</mapping>
<structure>
<type value="Query"/>
<publish value="true"/>
<element>
<path value="Query"/>
<definition>
<short value="A description of a query with a set of parameters"/>
<formal value="A description of a query with a set of parameters."/>
<min value="1"/>
<max value="1"/>
<type>
<code value="Resource"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value="QuerySpec"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.extension"/>
<definition>
<short value="Additional Content defined by implementations"/>
<formal value="May be used to represent additional information that is not part of the basic definition of the resource. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension."/>
<comments value="there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone."/>
<synonym value="extensions"/>
<synonym value="user content"/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
</definition>
</element>
<element>
<path value="Query.modifierExtension"/>
<definition>
<short value="Extensions that cannot be ignored"/>
<formal value="May be used to represent additional information that is not part of the basic definition of the resource, and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions."/>
<comments value="there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone."/>
<synonym value="extensions"/>
<synonym value="user content"/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
</definition>
</element>
<element>
<path value="Query.text"/>
<definition>
<short value="Text summary of the resource, for human interpretation"/>
<formal value="A human-readable narrative that contains a summary of the resource, and may be used to represent the content of the resource to a human. The narrative need not encode all the structured data, but is required to contain sufficient detail to make it &quot;clinically safe&quot; for a human to just read the narrative. Resource definitions may define what content should be represented in the narrative to ensure clinical safety."/>
<comments value="Contained resources do not have narrative. Resources that are not contained SHOULD have a narrative."/>
<synonym value="narrative"/>
<synonym value="html"/>
<synonym value="xhtml"/>
<synonym value="display"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Narrative"/>
</type>
<isModifier value="false"/>
</definition>
</element>
<element>
<path value="Query.contained"/>
<definition>
<short value="Contained, inline Resources"/>
<formal value="These resources do not have an independent existence apart from the resource that contains them - they cannot be identified independently, and nor can they have their own independent transaction scope."/>
<comments value="This should never be done when the content can be identified properly, as once identification is lost, it is extremely difficult (and context dependent) to restore it again."/>
<synonym value="inline resources"/>
<synonym value="anonymous resources"/>
<synonym value="contained resources"/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Resource"/>
</type>
<isModifier value="false"/>
</definition>
</element>
<element>
<path value="Query.identifier"/>
<definition>
<short value="Links query and its response(s)"/>
<formal value="Links query and its response(s)."/>
<min value="1"/>
<max value="1"/>
<type>
<code value="uri"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value=".queryId"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.parameter"/>
<definition>
<short value="Set of query parameters with values"/>
<formal value="Set of query parameters with values."/>
<comments value="Unless otherwise specified, parameters are usually strings."/>
<min value="1"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value=".parameter"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response"/>
<definition>
<short value="If this is a response to a query"/>
<formal value="If this is a response to a query."/>
<min value="0"/>
<max value="1"/>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value="QueryAck (indirectly linked through .queryId, directly linked via Message.acknowledges"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.extension"/>
<definition>
<short value="Additional Content defined by implementations"/>
<formal value="May be used to represent additional information that is not part of the basic definition of the resource. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension."/>
<comments value="there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone."/>
<synonym value="extensions"/>
<synonym value="user content"/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
</definition>
</element>
<element>
<path value="Query.response.modifierExtension"/>
<definition>
<short value="Extensions that cannot be ignored"/>
<formal value="May be used to represent additional information that is not part of the basic definition of the resource, and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions."/>
<comments value="there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone."/>
<synonym value="extensions"/>
<synonym value="user content"/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
</definition>
</element>
<element>
<path value="Query.response.identifier"/>
<definition>
<short value="Links response to source query"/>
<formal value="Links response to source query."/>
<min value="1"/>
<max value="1"/>
<type>
<code value="uri"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value=".queryId?"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.outcome"/>
<definition>
<short value="ok | limited | refused | error"/>
<formal value="Outcome of processing the query."/>
<min value="1"/>
<max value="1"/>
<type>
<code value="code"/>
</type>
<isModifier value="false"/>
<binding>
<name value="QueryOutcome"/>
<isExtensible value="false"/>
<conformance value="required"/>
<referenceResource>
<reference value="http://hl7.org/fhir/vs/query-outcome"/>
</referenceResource>
</binding>
<mapping>
<identity value="rim"/>
<map value=".queryResponseCode"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.total"/>
<definition>
<short value="Total number of matching records"/>
<formal value="Total number of matching records."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="integer"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value=".resultTotalQuantity"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.parameter"/>
<definition>
<short value="Parameters server used"/>
<formal value="Parameters server used."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value="Not supported"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.first"/>
<definition>
<short value="To get first page (if paged)"/>
<formal value="To get first page (if paged)."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value="Not supported"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.previous"/>
<definition>
<short value="To get previous page (if paged)"/>
<formal value="To get previous page (if paged)."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value="Not supported"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.next"/>
<definition>
<short value="To get next page (if paged)"/>
<formal value="To get next page (if paged)."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value=".continuationToken"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.last"/>
<definition>
<short value="To get last page (if paged)"/>
<formal value="To get last page (if paged)."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Extension"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value="Not supported"/>
</mapping>
</definition>
</element>
<element>
<path value="Query.response.reference"/>
<definition>
<short value="Resources that are the results of the search"/>
<formal value="Resources that are the results of the search."/>
<comments value="Is query only used in messaging?."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="ResourceReference"/>
<profile value="http://hl7.org/fhir/profiles/Any"/>
</type>
<isModifier value="false"/>
<mapping>
<identity value="rim"/>
<map value=".controlAct.outboundRelationship[typeCode=SUBJ].target or .controlAct.participation[typeCode=SBJ].role"/>
</mapping>
</definition>
</element>
<searchParam>
<name value="_id"/>
<type value="token"/>
<documentation value="The logical resource id associated with the resource (must be supported by all servers)"/>
</searchParam>
<searchParam>
<name value="identifier"/>
<type value="token"/>
<documentation value="Links query and its response(s)"/>
<xpath value="f:Query/f:identifier"/>
</searchParam>
<searchParam>
<name value="response"/>
<type value="token"/>
<documentation value="Links response to source query"/>
<xpath value="f:Query/f:response/f:identifier"/>
</searchParam>
</structure>
</Profile>

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="target/generated-sources/tinder"/>
<classpathentry kind="src" path="src/test/resources"/>
<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"/>

View File

@ -25,6 +25,7 @@
<build>
<plugins>
<!--
<plugin>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-tinder-plugin</artifactId>
@ -60,6 +61,63 @@
</execution>
</executions>
</plugin>
-->
<plugin>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-tinder-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<id>custom-structs</id>
<goals>
<goal>generate-structures</goal>
</goals>
<configuration>
<package>ca.uhn.test.customstructs</package>
<resourceProfileFiles>
<resourceProfileFile>src/test/resources/profile/patient.xml</resourceProfileFile>
<resourceProfileFile>src/test/resources/profile/organization.xml</resourceProfileFile>
</resourceProfileFiles>
<resourceValueSetFiles>
<resourceValueSetFile>src/test/resources/valueset/valueset-cgta-patientidpool.xml</resourceValueSetFile>
<resourceValueSetFile>src/test/resources/valueset/valueset-cgta-provideridpool.xml</resourceValueSetFile>
</resourceValueSetFiles>
</configuration>
</execution>
<execution>
<id>generalstructs</id>
<goals>
<goal>generate-structures</goal>
</goals>
<configuration>
<package>ca.uhn.test.realstructs</package>
<baseResourceNames>
<baseResourceName>patient</baseResourceName>
<baseResourceName>valueset</baseResourceName>
<baseResourceName>organization</baseResourceName>
<baseResourceName>device</baseResourceName>
<baseResourceName>location</baseResourceName>
<baseResourceName>practitioner</baseResourceName>
</baseResourceNames>
<buildDatatypes>true</buildDatatypes>
</configuration>
</execution>
<!--
<execution>
<id>client</id>
<goals>
<goal>generate-client</goal>
</goals>
<configuration>
<clientClassName>ca.uhn.hitest.HiTest</clientClassName>
<serverBaseHref>http://fhir.healthintersections.com.au/open</serverBaseHref>
<generateSearchForAllParams>true</generateSearchForAllParams>
</configuration>
</execution>
-->
</executions>
</plugin>
</plugins>
</build>

View File

@ -0,0 +1,579 @@
<Profile xmlns="http://hl7.org/fhir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://hl7.org/fhir ../fhir-single.xsd">
<text>
<status value="generated" />
<div xmlns="http://www.w3.org/1999/xhtml">
</div>
</text>
<name value="organization" />
<publisher value="ConnectingGTA" />
<description value="TODO: define" />
<status value="draft" />
<date value="2014-02-03" />
<structure>
<type value="Organization" />
<publish value="true" />
<element>
<path value="Organization" />
<definition>
<short value="A grouping of people or organizations with a common purpose" />
<formal
value="A formally or informally recognized grouping of people or organizations formed for the purpose of achieving some form of collective action. Includes companies, institutions, corporations, departments, community groups, healthcare practice groups, etc." />
<min value="1" />
<max value="1" />
<type>
<code value="Resource" />
</type>
<constraint>
<key value="1" />
<name value="AtLeastANameOrId" />
<severity value="error" />
<human value="The organization SHALL at least have a name or an id, and possibly more than one" />
<xpath value="count(f:identifier | f:name) &gt; 0" />
</constraint>
<isModifier value="false" />
</definition>
</element>
<element>
<path value="Organization.extension" />
<slicing>
<discriminator value="url" />
<ordered value="false"/>
<rules value="open"/>
</slicing>
</element>
<element>
<path value="Organization.extension" />
<name value="providerIdPool"/>
<definition>
<short value="Provider ID system pool" />
<formal value="An OID which serves as a namespace (ID root in HL7v3, identifier.system in FHIR) for a provider identifier" />
<min value="0" />
<max value="*" />
<type>
<code value="Extension" />
<profile value="#providerIdPool" />
</type>
<isModifier value="false" />
</definition>
</element>
<element>
<path value="Organization.modifierExtension" />
<definition>
<short value="Extensions that cannot be ignored" />
<formal
value="May be used to represent additional information that is not part of the basic definition of the resource,
and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable,
there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be
met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions." />
<comments
value="there can be no stigma associated
with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what
allows the FHIR specification to retain a core simplicity for everyone." />
<synonym value="extensions" />
<synonym value="user content" />
<min value="0" />
<max value="*" />
<type>
<code value="Extension" />
</type>
<isModifier value="false" />
</definition>
</element>
<element>
<path value="Organization.text" />
<definition>
<short value="Text summary of the
resource, for human interpretation" />
<formal
value="A human-readable narrative that contains a summary of the resource, and may be used to represent the content of the resource to
a human. The narrative need not encode all the structured data, but is required to contain sufficient detail to make it &quot;clinically safe&quot; for a human to just read the narrative.
Resource definitions may define what content should be represented in the narrative to ensure clinical safety." />
<comments value="Contained resources do not have narrative. Resources
that are not contained SHOULD have a narrative." />
<synonym value="narrative" />
<synonym value="html" />
<synonym value="xhtml" />
<synonym value="display" />
<min value="0" />
<max value="1" />
<type>
<code value="Narrative" />
</type>
<isModifier value="false" />
</definition>
</element>
<element>
<path value="Organization.contained" />
<definition>
<short value="Contained,
inline Resources" />
<formal
value="These resources do not have an independent existence apart from the resource that contains them - they cannot be identified independently, and nor
can they have their own independent transaction scope." />
<comments
value="This should never be done when the content can be identified properly, as once identification is lost, it
is extremely difficult (and context dependent) to restore it again." />
<synonym value="inline resources" />
<synonym value="anonymous resources" />
<synonym value="contained resources" />
<min value="0" />
<max value="*" />
<type>
<code value="Resource" />
</type>
<isModifier value="false" />
</definition>
</element>
<!-- <element> <path value="Organization.providerIdPool" /> <definition> <short value="Contact for the organization for a certain purpose" /> <formal value="Contact for the organization
for a certain purpose." /> <min value="0" /> <max value="*" /> <isModifier value="false" /> <extension url=""></extension> </definition> </element> -->
<element>
<path value="Organization.identifier" />
<definition>
<short value="Identifies this organization across multiple systems" />
<formal value="Identifier for the organization that is used to identify the organization across multiple disparate systems." />
<min value="0" />
<max value="*" />
<type>
<code value="Identifier" />
</type>
<isModifier value="false" />
</definition>
</element>
<element>
<path value="Organization.name" />
<definition>
<short value="Name used for the organization" />
<formal value="A name associated with the organization." />
<min value="0" />
<max value="1" />
<type>
<code value="string" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".name" />
</mapping>
<mapping>
<identity value="v2" />
<map value="XON.1 Organization Name" />
</mapping>
<mapping>
<identity value="servd" />
<map value=".PreferredName/Name" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.type" />
<definition>
<short value="Kind of organization" />
<formal value="The kind of organization that this is." />
<comments
value="Organizations can be corporations, wards, sections, clinical teams, government departments, etc. Note that code is generally a classifier of the type of organization; in many applications, codes are used to identity a particular organization (say, ward) as opposed to another of the same type - these are identifiers, not codes." />
<min value="0" />
<max value="1" />
<type>
<code value="CodeableConcept" />
</type>
<isModifier value="false" />
<binding>
<name value="OrganizationType" />
<isExtensible value="true" />
<conformance value="example" />
<referenceValueSet>
<reference value="http://hl7.org/fhir/vs/organization-type" />
</referenceValueSet>
</binding>
<mapping>
<identity value="rim" />
<map value=".code" />
</mapping>
<mapping>
<identity value="v2" />
<map value="No equivalent in v2" />
</mapping>
<mapping>
<identity value="servd" />
<map value="n/a" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.telecom" />
<definition>
<short value="A contact detail for the organization" />
<formal value="A contact detail for the organization." />
<comments
value="The use code home is not to be used. Note that these contacts are not the contact details of people who are employed by or represent the organization, but official contacts for the organization itself." />
<min value="0" />
<max value="*" />
<type>
<code value="Contact" />
</type>
<constraint>
<key value="3" />
<name value="NoHomeUseTelecom" />
<severity value="error" />
<human value="The telecom of an organization can never be of use 'home'" />
<xpath value="count(f:use[@value='home']) = 0" />
</constraint>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".telecom" />
</mapping>
<mapping>
<identity value="v2" />
<map value="No authoritative equivalent in V2.x" />
</mapping>
<mapping>
<identity value="servd" />
<map value="./ContactPoints" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.address" />
<definition>
<short value="An address for the organization" />
<formal value="An address for the organization." />
<comments value="Organization may have multiple addresses with different uses or applicable periods. The use code home is not to be used." />
<min value="0" />
<max value="*" />
<type>
<code value="Address" />
</type>
<constraint>
<key value="2" />
<name value="NoHomeUseAddress" />
<severity value="error" />
<human value="An address of an organization can never be of use 'home'" />
<xpath value="count(f:use[@value='home']) = 0" />
</constraint>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".address" />
</mapping>
<mapping>
<identity value="v2" />
<map value="No authoritative equivalent in V2.x; some V2.x segments such as OBX might provide a serialized instance value" />
</mapping>
<mapping>
<identity value="servd" />
<map value="./PrimaryAddress and ./OtherAddresses" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.partOf" />
<definition>
<short value="The organization of which this organization forms a part" />
<formal value="The organization of which this organization forms a part." />
<min value="0" />
<max value="1" />
<type>
<code value="ResourceReference" />
<profile value="http://hl7.org/fhir/profiles/Organization" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".playedBy[classCode=Part].scoper" />
</mapping>
<mapping>
<identity value="v2" />
<map value="No equivalent in V2.x" />
</mapping>
<mapping>
<identity value="servd" />
<map value="n/a" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.contact" />
<definition>
<short value="Contact for the organization for a certain purpose" />
<formal value="Contact for the organization for a certain purpose." />
<min value="0" />
<max value="*" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".contactParty" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.contact.extension" />
<definition>
<short value="Additional Content defined by implementations" />
<formal
value="May be used to represent additional information that is not part of the basic definition of the resource. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension." />
<comments
value="there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone." />
<synonym value="extensions" />
<synonym value="user content" />
<min value="0" />
<max value="*" />
<type>
<code value="Extension" />
</type>
<isModifier value="false" />
</definition>
</element>
<element>
<path value="Organization.contact.modifierExtension" />
<definition>
<short value="Extensions that cannot be ignored" />
<formal
value="May be used to represent additional information that is not part of the basic definition of the resource, and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions." />
<comments
value="there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone." />
<synonym value="extensions" />
<synonym value="user content" />
<min value="0" />
<max value="*" />
<type>
<code value="Extension" />
</type>
<isModifier value="false" />
</definition>
</element>
<element>
<path value="Organization.contact.purpose" />
<definition>
<short value="The type of contact" />
<formal value="Indicates a purpose for which the contact can be reached." />
<min value="0" />
<max value="1" />
<type>
<code value="CodeableConcept" />
</type>
<isModifier value="false" />
<binding>
<name value="ContactPartyType" />
<isExtensible value="true" />
<conformance value="preferred" />
<referenceValueSet>
<reference value="http://hl7.org/fhir/vs/contactentity-type" />
</referenceValueSet>
</binding>
<mapping>
<identity value="rim" />
<map value="./type" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.contact.name" />
<definition>
<short value="A name associated with the contact" />
<formal value="A name associated with the contact." />
<min value="0" />
<max value="1" />
<type>
<code value="HumanName" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./name" />
</mapping>
<mapping>
<identity value="v2" />
<map value="PID-5, PID-9" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.contact.telecom" />
<definition>
<short value="Contact details (telephone, email, etc) for a contact" />
<formal value="A contact detail (e.g. a telephone number or an email address) by which the party may be contacted." />
<min value="0" />
<max value="*" />
<type>
<code value="Contact" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./telecom" />
</mapping>
<mapping>
<identity value="v2" />
<map value="PID-13, PID-14" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.contact.address" />
<definition>
<short value="Visiting or postal addresses for the contact" />
<formal value="Visiting or postal addresses for the contact." />
<min value="0" />
<max value="1" />
<type>
<code value="Address" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./addr" />
</mapping>
<mapping>
<identity value="v2" />
<map value="PID-11" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.contact.gender" />
<definition>
<short value="Gender for administrative purposes" />
<formal value="Administrative Gender - the gender that the person is considered to have for administration and record keeping purposes." />
<min value="0" />
<max value="1" />
<type>
<code value="CodeableConcept" />
</type>
<isModifier value="false" />
<binding>
<name value="AdministrativeGender" />
<isExtensible value="true" />
<conformance value="preferred" />
<referenceValueSet>
<reference value="http://hl7.org/fhir/vs/administrative-gender" />
</referenceValueSet>
</binding>
<mapping>
<identity value="rim" />
<map value="./administrativeGender" />
</mapping>
<mapping>
<identity value="v2" />
<map value="PID-8" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.location" />
<definition>
<short value="Location(s) the organization uses to provide services" />
<formal value="Location(s) the organization uses to provide services." />
<min value="0" />
<max value="*" />
<type>
<code value="ResourceReference" />
<profile value="http://hl7.org/fhir/profiles/Location" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".scopedBy[classCode=LocatedEntity].scoper" />
</mapping>
<mapping>
<identity value="servd" />
<map value="./Sites" />
</mapping>
</definition>
</element>
<element>
<path value="Organization.active" />
<definition>
<short value="Whether the organization's record is still in active use" />
<formal value="Whether the organization's record is still in active use." />
<comments value="Default is true." />
<min value="0" />
<max value="1" />
<type>
<code value="boolean" />
</type>
<isModifier value="true" />
<mapping>
<identity value="rim" />
<map value=".status" />
</mapping>
<mapping>
<identity value="v2" />
<map value="No equivalent in V2.x" />
</mapping>
<mapping>
<identity value="servd" />
<map
value="./Status (however this concept in ServD more covers why the organization is active or not, could be delisted, deregistered, not operational yet) this could alternatively be derived from ./StartDate and ./EndDate and given a context date." />
</mapping>
</definition>
</element>
<searchParam>
<name value="_id" />
<type value="token" />
<documentation value="The logical resource id associated with the resource (must be supported by all servers)" />
</searchParam>
<searchParam>
<name value="active" />
<type value="token" />
<documentation value="Whether the organization's record is active" />
<xpath value="f:Organization/f:active" />
</searchParam>
<searchParam>
<name value="identifier" />
<type value="token" />
<documentation value="Any identifier for the organization (not the accreditation issuer's identifier)" />
<xpath value="f:Organization/f:identifier" />
</searchParam>
<searchParam>
<name value="name" />
<type value="string" />
<documentation value="A portion of the organization's name" />
<xpath value="f:Organization/f:name" />
</searchParam>
<searchParam>
<name value="partof" />
<type value="reference" />
<documentation value="Search all organizations that are part of the given organization" />
<xpath value="f:Organization/f:partOf" />
</searchParam>
<searchParam>
<name value="phonetic" />
<type value="string" />
<documentation value="A portion of the organization's name using some kind of phonetic matching algorithm" />
</searchParam>
<searchParam>
<name value="type" />
<type value="token" />
<documentation value="A code for the type of organization" />
<xpath value="f:Organization/f:type" />
</searchParam>
</structure>
<extensionDefn>
<code value="providerIdPool" />
<contextType value="resource" />
<context value="Organization" />
<definition>
<short value="Provider ID system pool" />
<formal value="An OID which serves as a namespace (ID root in HL7v3, identifier.system in FHIR) for a provider identifier" />
<min value="0" />
<max value="*" />
<type>
<code value="code" />
</type>
<mustSupport value="false" />
<isModifier value="false" />
<binding>
<name value="ConnectingGTA Provider ID Namespaces" />
<isExtensible value="false" />
</binding>
</definition>
</extensionDefn>
</Profile>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,32 @@
<ValueSet xmlns="http://hl7.org/fhir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://hl7.org/fhir ../fhir-single.xsd">
<text>
<status value="generated" />
<div xmlns="http://www.w3.org/1999/xhtml">
</div>
</text>
<identifier value="urn:cgta:valueset:patientIdPool" />
<name value="ConnectingGTA Patient ID Namespaces" />
<publisher value="ConnectingGTA" />
<description value="Patient ID namespaces for various ID authorities and organizations" />
<status value="active" />
<date value="2013-12-07" />
<define>
<system value="urn:cgta:valueset:providerIdPool" />
<caseSensitive value="true" />
<concept>
<code value="urn:oid:2.16.840.1.113883.3.239.18.148" />
<display value="University Health Network MRNs" />
</concept>
<concept>
<code value="urn:oid:2.16.840.1.113883.3.239.18.157" />
<display value="Women's College Hospital MRNs" />
</concept>
<concept>
<code value="urn:oid:2.16.840.1.113883.4.595" />
<display value="Ontario Health Card (OHIP)"/>
</concept>
</define>
</ValueSet>

View File

@ -0,0 +1,26 @@
<ValueSet xmlns="http://hl7.org/fhir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://hl7.org/fhir ../fhir-single.xsd">
<text>
<status value="generated" />
<div xmlns="http://www.w3.org/1999/xhtml">
</div>
</text>
<identifier value="urn:cgta:valueset:providerIdPool" />
<name value="ConnectingGTA Provider ID Namespaces" />
<publisher value="ConnectingGTA" />
<description value="Provider ID namespaces for various ID authorities and organizations" />
<status value="active" />
<date value="2013-12-07" />
<define>
<system value="urn:cgta:valueset:providerIdPool" />
<caseSensitive value="true" />
<concept>
<code value="urn:oid:1.3.6.1.4.1.12201.1" />
<display value="University Health Network Provider IDs" />
</concept>
<concept>
<code value="urn:oid:2.16.840.1.113883.3.239.23.57.1" />
<display value="Women's College Hospital Provider IDs" />
</concept>
</define>
</ValueSet>