Get extensions working for HL7.org structures

This commit is contained in:
James Agnew 2015-02-20 17:34:13 -05:00
parent cf3a78ecd2
commit 0f01260301
53 changed files with 1254 additions and 531 deletions

View File

@ -8,6 +8,7 @@ import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.rest.annotation.RequiredParam; import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search; import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.server.HardcodedServerAddressStrategy;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer; import ca.uhn.fhir.rest.server.RestfulServer;
@ -36,6 +37,7 @@ public class PlainProvider {
//START SNIPPET: plainProviderServer //START SNIPPET: plainProviderServer
public class ExampleServlet extends RestfulServer { public class ExampleServlet extends RestfulServer {
/** Constructor */
public ExampleServlet() { public ExampleServlet() {
/* /*
* Plain providers are passed to the server in the same way * Plain providers are passed to the server in the same way
@ -54,5 +56,23 @@ public class ExampleServlet extends RestfulServer {
} }
//END SNIPPET: plainProviderServer //END SNIPPET: plainProviderServer
//START SNIPPET: addressStrategy
public class MyServlet extends RestfulServer {
/** Constructor */
public MyServlet() {
String serverBaseUrl = "http://foo.com/fhir";
setServerAddressStrategy(new HardcodedServerAddressStrategy(serverBaseUrl));
// ...add some resource providers, etc...
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
setResourceProviders(resourceProviders);
}
}
//END SNIPPET: addressStrategy
} }

View File

@ -12,6 +12,7 @@ import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.IResourceProvider; import ca.uhn.fhir.rest.server.IResourceProvider;
@SuppressWarnings("null")
//START SNIPPET: provider //START SNIPPET: provider
public class PagingPatientProvider implements IResourceProvider { public class PagingPatientProvider implements IResourceProvider {
@ -21,8 +22,19 @@ public class PagingPatientProvider implements IResourceProvider {
@Search @Search
public IBundleProvider search(@RequiredParam(name = Patient.SP_FAMILY) StringParam theFamily) { public IBundleProvider search(@RequiredParam(name = Patient.SP_FAMILY) StringParam theFamily) {
final InstantDt searchTime = InstantDt.withCurrentTime(); final InstantDt searchTime = InstantDt.withCurrentTime();
final List<String> matchingResourceIds = findIdsByFamily(theFamily);
/*
* First, we'll search the database for a set of database row IDs that
* match the given search criteria. That way we can keep just the
* row IDs around, and load the actual resources on demand later
* as the client pages through them.
*/
final List<Long> matchingResourceIds = null; // <-- implement this
/*
* Return a bundle provider which can page through the IDs and
* return the resources that go with them.
*/
return new IBundleProvider() { return new IBundleProvider() {
@Override @Override
@ -33,7 +45,7 @@ public class PagingPatientProvider implements IResourceProvider {
@Override @Override
public List<IResource> getResources(int theFromIndex, int theToIndex) { public List<IResource> getResources(int theFromIndex, int theToIndex) {
int end = Math.max(theToIndex, matchingResourceIds.size() - 1); int end = Math.max(theToIndex, matchingResourceIds.size() - 1);
List<String> idsToReturn = matchingResourceIds.subList(theFromIndex, end); List<Long> idsToReturn = matchingResourceIds.subList(theFromIndex, end);
return loadResourcesByIds(idsToReturn); return loadResourcesByIds(idsToReturn);
} }
@ -44,18 +56,10 @@ public class PagingPatientProvider implements IResourceProvider {
}; };
} }
/**
* Get a list of resource IDs which match a given family name
*/
private List<String> findIdsByFamily(StringParam theFamily) {
// .. implement this search against the database ..
return null;
}
/** /**
* Load a list of patient resources given their IDs * Load a list of patient resources given their IDs
*/ */
private List<IResource> loadResourcesByIds(List<String> theFamily) { private List<IResource> loadResourcesByIds(List<Long> theIdsToReturn) {
// .. implement this search against the database .. // .. implement this search against the database ..
return null; return null;
} }

View File

@ -195,69 +195,6 @@
</plugins> </plugins>
</reporting> </reporting>
</profile> </profile>
<profile>
<id>ANDROID</id>
<dependencies>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId>
<version>0.9-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-android</artifactId>
<version>${slf4j_version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<shadedArtifactAttached>false</shadedArtifactAttached>
<createDependencyReducedPom>true</createDependencyReducedPom>
<artifactSet>
<includes>
<!--
<include>javax.json:javax.json-api</include>
-->
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</include>
<include>ca.uhn.hapi.fhir:hapi-fhir-structures-dstu</include>
<include>org.glassfish:javax.json</include>
<include>org.codehaus.woodstox:woodstox-core-asl</include>
<include>javax.xml.stream:stax-api</include>
<include>org.codehaus.woodstox:stax2-api</include>
<include>org.slf4j:slf4j*</include>
<include>org.apache.commons:*</include>
<include>org.apache.httpcomponents:*</include>
</includes>
</artifactSet>
<relocations>
<relocation>
<pattern>javax.xml.stream</pattern>
<shadedPattern>ca.uhn.fhir.repackage.javax.xml.stream</shadedPattern>
</relocation>
<relocation>
<pattern>javax.json</pattern>
<shadedPattern>ca.uhn.fhir.repackage.javax.json</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles> </profiles>
</project> </project>

View File

@ -21,6 +21,7 @@ package ca.uhn.fhir.context;
*/ */
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Collections; import java.util.Collections;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -28,7 +29,6 @@ import java.util.Set;
import org.hl7.fhir.instance.model.IBase; import org.hl7.fhir.instance.model.IBase;
import ca.uhn.fhir.model.api.ICodeEnum; import ca.uhn.fhir.model.api.ICodeEnum;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description; import ca.uhn.fhir.model.api.annotation.Description;
@ -41,7 +41,7 @@ public abstract class BaseRuntimeChildDatatypeDefinition extends BaseRuntimeDecl
public BaseRuntimeChildDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype) { public BaseRuntimeChildDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype) {
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName); super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
assert theDatatype != IDatatype.class; // should use RuntimeChildAny assert Modifier.isInterface(theDatatype.getModifiers()) == false : "Type of " + theDatatype + " shouldn't be here"; // should use RuntimeChildAny
myDatatype = theDatatype; myDatatype = theDatatype;
} }

View File

@ -45,9 +45,6 @@ public abstract class BaseRuntimeElementCompositeDefinition<T extends IBase> ext
if (theNext == null) { if (theNext == null) {
throw new NullPointerException(); throw new NullPointerException();
} }
// if (theNext.getValidChildNames().contains("performetPractitioner")) {
// throw new NullPointerException();
// }
if (theNext.getExtensionUrl() != null) { if (theNext.getExtensionUrl() != null) {
throw new IllegalArgumentException("Shouldn't haven an extension URL, use addExtension instead"); throw new IllegalArgumentException("Shouldn't haven an extension URL, use addExtension instead");
} }

View File

@ -29,6 +29,7 @@ import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.IBase; import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
import ca.uhn.fhir.model.api.IValueSetEnumBinder; import ca.uhn.fhir.model.api.IValueSetEnumBinder;
@ -102,8 +103,10 @@ public abstract class BaseRuntimeElementDefinition<T extends IBase> {
try { try {
if (theArgument == null) { if (theArgument == null) {
return getImplementingClass().newInstance(); return getImplementingClass().newInstance();
} else { } else if (theArgument instanceof IValueSetEnumBinder) {
return getImplementingClass().getConstructor(IValueSetEnumBinder.class).newInstance(theArgument); return getImplementingClass().getConstructor(IValueSetEnumBinder.class).newInstance(theArgument);
}else {
return getImplementingClass().getConstructor(IBaseEnumFactory.class).newInstance(theArgument);
} }
} catch (InstantiationException e) { } catch (InstantiationException e) {
throw new ConfigurationException("Failed to instantiate type:" + getImplementingClass().getName(), e); throw new ConfigurationException("Failed to instantiate type:" + getImplementingClass().getName(), e);

View File

@ -55,6 +55,7 @@ import org.hl7.fhir.instance.model.IPrimitiveType;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBackboneElement; import org.hl7.fhir.instance.model.api.IBackboneElement;
import org.hl7.fhir.instance.model.api.IBaseDatatype; import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IDatatypeElement; import org.hl7.fhir.instance.model.api.IDatatypeElement;
import org.hl7.fhir.instance.model.api.IDomainResource; import org.hl7.fhir.instance.model.api.IDomainResource;
@ -555,7 +556,7 @@ class ModelScanner {
RuntimeChildResourceBlockDefinition def = new RuntimeChildResourceBlockDefinition(next, childAnnotation, descriptionAnnotation, elementName, blockDef); RuntimeChildResourceBlockDefinition def = new RuntimeChildResourceBlockDefinition(next, childAnnotation, descriptionAnnotation, elementName, blockDef);
orderMap.put(order, def); orderMap.put(order, def);
} else if (IDatatype.class.equals(nextElementType) || IElement.class.equals(nextElementType) || "org.hl7.fhir.instance.model.Type".equals(nextElementType.getName())) { } else if (IDatatype.class.equals(nextElementType) || IElement.class.equals(nextElementType) || "org.hl7.fhir.instance.model.Type".equals(nextElementType.getName()) || IBaseDatatype.class.equals(nextElementType)) {
RuntimeChildAny def = new RuntimeChildAny(next, elementName, childAnnotation, descriptionAnnotation); RuntimeChildAny def = new RuntimeChildAny(next, elementName, childAnnotation, descriptionAnnotation);
orderMap.put(order, def); orderMap.put(order, def);
@ -565,10 +566,13 @@ class ModelScanner {
addScanAlso(nextDatatype); addScanAlso(nextDatatype);
BaseRuntimeChildDatatypeDefinition def; BaseRuntimeChildDatatypeDefinition def;
if (IPrimitiveDatatype.class.isAssignableFrom(nextElementType)) { if (IPrimitiveType.class.isAssignableFrom(nextElementType)) {
if (nextElementType.equals(BoundCodeDt.class)) { if (nextElementType.equals(BoundCodeDt.class)) {
IValueSetEnumBinder<Enum<?>> binder = getBoundCodeBinder(next); IValueSetEnumBinder<Enum<?>> binder = getBoundCodeBinder(next);
def = new RuntimeChildPrimitiveBoundCodeDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder); def = new RuntimeChildPrimitiveBoundCodeDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, binder);
} else if (childAnnotation.enumFactory().getSimpleName().equals("NoEnumFactory") == false) {
Class<? extends IBaseEnumFactory<?>> enumFactory = childAnnotation.enumFactory();
def = new RuntimeChildEnumerationDatatypeDefinition(next, elementName, childAnnotation, descriptionAnnotation, nextDatatype, enumFactory);
} else { } else {
def = new RuntimeChildPrimitiveDatatypeDefinition(next, elementName, descriptionAnnotation, childAnnotation, nextDatatype); def = new RuntimeChildPrimitiveDatatypeDefinition(next, elementName, descriptionAnnotation, childAnnotation, nextDatatype);
} }

View File

@ -0,0 +1,58 @@
package ca.uhn.fhir.context;
/*
* #%L
* HAPI FHIR - Core Library
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.lang.reflect.Field;
import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
public class RuntimeChildEnumerationDatatypeDefinition extends RuntimeChildPrimitiveDatatypeDefinition {
private Class<? extends IBaseEnumFactory<?>> myBinderType;
private volatile IBaseEnumFactory<?> myBinder;
public RuntimeChildEnumerationDatatypeDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, Class<? extends IBase> theDatatype, Class<? extends IBaseEnumFactory<?>> theBinderType) {
super(theField, theElementName, theDescriptionAnnotation, theChildAnnotation, theDatatype);
myBinderType = theBinderType;
}
@Override
public IBaseEnumFactory<?> getInstanceConstructorArguments() {
IBaseEnumFactory<?> retVal = myBinder;
if (retVal == null) {
try {
retVal = myBinderType.newInstance();
} catch (InstantiationException e) {
throw new IllegalStateException("Failed to instantiate " + myBinderType, e);
} catch (IllegalAccessException e) {
throw new IllegalStateException("Failed to instantiate " + myBinderType, e);
}
myBinder = retVal;
}
return retVal;
}
}

View File

@ -33,4 +33,6 @@ public class RuntimeChildPrimitiveDatatypeDefinition extends BaseRuntimeChildDat
super(theField, theElementName, theChildAnnotation, theDescriptionAnnotation, theDatatype); super(theField, theElementName, theChildAnnotation, theDescriptionAnnotation, theDatatype);
} }
} }

View File

@ -25,6 +25,7 @@ import java.util.Collections;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
public abstract class BaseElement implements IElement, ISupportsUndeclaredExtensions { public abstract class BaseElement implements IElement, ISupportsUndeclaredExtensions {
@ -32,7 +33,7 @@ public abstract class BaseElement implements IElement, ISupportsUndeclaredExtens
private List<ExtensionDt> myUndeclaredModifierExtensions; private List<ExtensionDt> myUndeclaredModifierExtensions;
@Override @Override
public ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IDatatype theValue) { public ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IBaseDatatype theValue) {
Validate.notEmpty(theUrl, "URL must be populated"); Validate.notEmpty(theUrl, "URL must be populated");
Validate.notNull(theValue, "Value must not be null"); Validate.notNull(theValue, "Value must not be null");
ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl, theValue); ExtensionDt retVal = new ExtensionDt(theIsModifier, theUrl, theValue);

View File

@ -24,13 +24,15 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import ca.uhn.fhir.model.api.annotation.Child; import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.DatatypeDef; import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@DatatypeDef(name="Extension") @DatatypeDef(name="Extension")
public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDatatype { public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDatatype, IBaseExtension<ExtensionDt> {
private boolean myModifier; private boolean myModifier;
@ -38,7 +40,7 @@ public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDa
private StringDt myUrl; private StringDt myUrl;
@Child(name="value", type=IDatatype.class, order=1, min=0, max=1) @Child(name="value", type=IDatatype.class, order=1, min=0, max=1)
private IElement myValue; private IBaseDatatype myValue;
public ExtensionDt() { public ExtensionDt() {
} }
@ -54,7 +56,7 @@ public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDa
myUrl = new StringDt(theUrl); myUrl = new StringDt(theUrl);
} }
public ExtensionDt(boolean theIsModifier, String theUrl, IDatatype theValue) { public ExtensionDt(boolean theIsModifier, String theUrl, IBaseDatatype theValue) {
Validate.notEmpty(theUrl, "URL must be populated"); Validate.notEmpty(theUrl, "URL must be populated");
Validate.notNull(theValue, "Value must not be null"); Validate.notNull(theValue, "Value must not be null");
@ -63,15 +65,25 @@ public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDa
myValue=theValue; myValue=theValue;
} }
public StringDt getUrl() { /**
if (myUrl==null) { * Returns the URL for this extension.
myUrl=new StringDt(); * <p>
} * Note that before HAPI 0.9 this method returned a {@link StringDt} but as of
return myUrl; * HAPI 0.9 this method returns a plain string. This was changed because it does not make sense to use a StringDt here
* since the URL itself can not contain extensions and it was therefore misleading.
* </p>
*/
public String getUrl() {
return myUrl != null ? myUrl.getValue() : null;
} }
/**
* Retained for backward compatibility
*
* @see ExtensionDt#getUrl()
*/
public String getUrlAsString() { public String getUrlAsString() {
return getUrl().getValue(); return getUrl();
} }
/** /**
@ -81,7 +93,7 @@ public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDa
* {@link #getUndeclaredModifierExtensions()} to retrieve the child extensions. * {@link #getUndeclaredModifierExtensions()} to retrieve the child extensions.
* </p> * </p>
*/ */
public IElement getValue() { public IBaseDatatype getValue() {
return myValue; return myValue;
} }
@ -117,7 +129,7 @@ public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDa
} }
public ExtensionDt setUrl(String theUrl) { public ExtensionDt setUrl(String theUrl) {
myUrl = new StringDt(theUrl); myUrl = theUrl != null ? new StringDt(theUrl) : myUrl;
return this; return this;
} }
@ -126,8 +138,9 @@ public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDa
return this; return this;
} }
public void setValue(IElement theValue) { public ExtensionDt setValue(IBaseDatatype theValue) {
myValue = theValue; myValue = theValue;
return this;
} }
@Override @Override
@ -135,4 +148,9 @@ public class ExtensionDt extends BaseIdentifiableElement implements ICompositeDa
return new ArrayList<T>(); return new ArrayList<T>();
} }
@Override
public List<ExtensionDt> getExtension() {
return getAllUndeclaredExtensions();
}
} }

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.api; package ca.uhn.fhir.model.api;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -20,6 +22,6 @@ package ca.uhn.fhir.model.api;
* #L% * #L%
*/ */
public interface IDatatype extends IElement { public interface IDatatype extends IElement, IBaseDatatype {
} }

View File

@ -22,6 +22,8 @@ package ca.uhn.fhir.model.api;
import java.util.List; import java.util.List;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
public interface ISupportsUndeclaredExtensions extends IElement { public interface ISupportsUndeclaredExtensions extends IElement {
/** /**
@ -52,7 +54,7 @@ public interface ISupportsUndeclaredExtensions extends IElement {
* <li>{@link ExtensionDt#setUrl(String) URL}</li> * <li>{@link ExtensionDt#setUrl(String) URL}</li>
* <li>And one of: * <li>And one of:
* <ul> * <ul>
* <li>{@link ExtensionDt#setValue(IElement) A datatype value}</li> * <li>{@link ExtensionDt#setValue(IBaseDatatype) A datatype value}</li>
* <li>{@link #addUndeclaredExtension(ExtensionDt) Further sub-extensions}</li> * <li>{@link #addUndeclaredExtension(ExtensionDt) Further sub-extensions}</li>
* </ul> * </ul>
* </ul> * </ul>
@ -64,7 +66,7 @@ public interface ISupportsUndeclaredExtensions extends IElement {
/** /**
* Adds an extension to this object * Adds an extension to this object
*/ */
ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IDatatype theValue); ExtensionDt addUndeclaredExtension(boolean theIsModifier, String theUrl, IBaseDatatype theValue);
/** /**
* Adds an extension to this object. This method is intended for use when * Adds an extension to this object. This method is intended for use when

View File

@ -28,6 +28,8 @@ import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.hl7.fhir.instance.model.IBase;
/** /**
* A collection of tags present on a single resource. TagList is backed by a {@link LinkedHashSet}, so the order of added tags will be consistent, but duplicates will not be preserved. * A collection of tags present on a single resource. TagList is backed by a {@link LinkedHashSet}, so the order of added tags will be consistent, but duplicates will not be preserved.
* *
@ -35,7 +37,7 @@ import java.util.Set;
* <b>Thread safety:</b> This class is not thread safe * <b>Thread safety:</b> This class is not thread safe
* </p> * </p>
*/ */
public class TagList implements Set<Tag>, Serializable { public class TagList implements Set<Tag>, Serializable, IBase {
public static final String ATTR_CATEGORY = "category"; public static final String ATTR_CATEGORY = "category";
public static final String ELEMENT_NAME = "TagList"; public static final String ELEMENT_NAME = "TagList";

View File

@ -24,6 +24,9 @@ import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.util.Enumeration;
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IElement;
@ -97,4 +100,28 @@ public @interface Child {
// */ // */
// String replaces() default ""; // String replaces() default "";
/**
* For children which accept an {@link Enumeration} as the type, this
* field indicates the type to use for the enum factory
*/
Class<? extends IBaseEnumFactory<?>> enumFactory() default NoEnumFactory.class;
public static class NoEnumFactory implements IBaseEnumFactory<Enum<?>> {
private NoEnumFactory() {
// non instantiable
}
@Override
public Enum<?> fromCode(String theCodeString) throws IllegalArgumentException {
return null;
}
@Override
public String toCode(Enum<?> theCode) {
return null;
}
}
} }

View File

@ -22,14 +22,12 @@ package ca.uhn.fhir.model.base.composite;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.List;
import javax.json.JsonValue;
import org.apache.http.HttpResponse; import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient; import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpGet;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.BaseIdentifiableElement; import ca.uhn.fhir.model.api.BaseIdentifiableElement;
@ -40,7 +38,7 @@ import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.client.BaseClient; import ca.uhn.fhir.rest.client.BaseClient;
import ca.uhn.fhir.rest.client.api.IRestfulClient; import ca.uhn.fhir.rest.client.api.IRestfulClient;
public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement { public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement implements IBaseDatatype {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseResourceReferenceDt.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseResourceReferenceDt.class);
private IResource myResource; private IResource myResource;

View File

@ -20,7 +20,9 @@ package ca.uhn.fhir.parser;
* #L% * #L%
*/ */
import static org.apache.commons.lang3.StringUtils.*; import static org.apache.commons.lang3.StringUtils.defaultString;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
@ -54,7 +56,11 @@ import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.IPrimitiveType; import org.hl7.fhir.instance.model.IPrimitiveType;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseBooleanDatatype; import org.hl7.fhir.instance.model.api.IBaseBooleanDatatype;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseDecimalDatatype; import org.hl7.fhir.instance.model.api.IBaseDecimalDatatype;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype; import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
@ -85,7 +91,6 @@ import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt; import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt; import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseBinary; import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.DecimalDt; import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.IntegerDt; import ca.uhn.fhir.model.primitive.IntegerDt;
@ -127,7 +132,7 @@ public class JsonParser extends BaseParser implements IParser {
myContext = theContext; myContext = theContext;
} }
private void addToHeldExtensions(int valueIdx, List<ExtensionDt> ext, ArrayList<ArrayList<HeldExtension>> list) { private void addToHeldExtensions(int valueIdx, List<? extends IBaseExtension<?>> ext, ArrayList<ArrayList<HeldExtension>> list, boolean theIsModifier) {
if (ext.size() > 0) { if (ext.size() > 0) {
list.ensureCapacity(valueIdx); list.ensureCapacity(valueIdx);
while (list.size() <= valueIdx) { while (list.size() <= valueIdx) {
@ -136,8 +141,8 @@ public class JsonParser extends BaseParser implements IParser {
if (list.get(valueIdx) == null) { if (list.get(valueIdx) == null) {
list.set(valueIdx, new ArrayList<JsonParser.HeldExtension>()); list.set(valueIdx, new ArrayList<JsonParser.HeldExtension>());
} }
for (ExtensionDt next : ext) { for (IBaseExtension<?> next : ext) {
list.get(valueIdx).add(new HeldExtension(next)); list.get(valueIdx).add(new HeldExtension(next, theIsModifier));
} }
} }
} }
@ -325,7 +330,6 @@ public class JsonParser extends BaseParser implements IParser {
// //
// writeAuthor(nextEntry, theEventWriter); // writeAuthor(nextEntry, theEventWriter);
if (nextEntry.getSummary().isEmpty() == false) { if (nextEntry.getSummary().isEmpty() == false) {
theEventWriter.write("summary", nextEntry.getSummary().getValueAsString()); theEventWriter.write("summary", nextEntry.getSummary().getValueAsString());
} }
@ -411,8 +415,7 @@ public class JsonParser extends BaseParser implements IParser {
} }
case CONTAINED_RESOURCES: { case CONTAINED_RESOURCES: {
/* /*
* Disabled per #103 * Disabled per #103 ContainedDt value = (ContainedDt) theNextValue; for (IResource next : value.getContainedResources()) { if (getContainedResources().getResourceId(next) != null) {
* ContainedDt value = (ContainedDt) theNextValue; for (IResource next : value.getContainedResources()) { if (getContainedResources().getResourceId(next) != null) {
* continue; } encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true, fixContainedResourceId(next.getId().getValue())); } * continue; } encodeResourceToJsonStreamWriter(theResDef, next, theWriter, null, true, fixContainedResourceId(next.getId().getValue())); }
*/ */
List<IBaseResource> containedResources = getContainedResources().getContainedResources(); List<IBaseResource> containedResources = getContainedResources().getContainedResources();
@ -460,6 +463,10 @@ public class JsonParser extends BaseParser implements IParser {
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter, private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theNextValue, JsonGenerator theEventWriter,
List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException { List<? extends BaseRuntimeChildDefinition> theChildren, boolean theIsSubElementWithinResource) throws IOException {
for (BaseRuntimeChildDefinition nextChild : theChildren) { for (BaseRuntimeChildDefinition nextChild : theChildren) {
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
continue;
}
if (nextChild instanceof RuntimeChildNarrativeDefinition) { if (nextChild instanceof RuntimeChildNarrativeDefinition) {
INarrativeGenerator gen = myContext.getNarrativeGenerator(); INarrativeGenerator gen = myContext.getNarrativeGenerator();
@ -540,12 +547,25 @@ public class JsonParser extends BaseParser implements IParser {
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource); encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childDef, null, theIsSubElementWithinResource);
} }
if (nextValue instanceof ISupportsUndeclaredExtensions && primitive) { if (primitive) {
if (nextValue instanceof ISupportsUndeclaredExtensions) {
List<ExtensionDt> ext = ((ISupportsUndeclaredExtensions) nextValue).getUndeclaredExtensions(); List<ExtensionDt> ext = ((ISupportsUndeclaredExtensions) nextValue).getUndeclaredExtensions();
addToHeldExtensions(valueIdx, ext, extensions); addToHeldExtensions(valueIdx, ext, extensions,false);
ext = ((ISupportsUndeclaredExtensions) nextValue).getUndeclaredModifierExtensions(); ext = ((ISupportsUndeclaredExtensions) nextValue).getUndeclaredModifierExtensions();
addToHeldExtensions(valueIdx, ext, modifierExtensions); addToHeldExtensions(valueIdx, ext, modifierExtensions,true);
}else {
if (nextValue instanceof IBaseHasExtensions) {
IBaseHasExtensions element = (IBaseHasExtensions) nextValue;
List<? extends IBaseExtension<?>> ext = element.getExtension();
addToHeldExtensions(valueIdx, ext, extensions, false);
}
if (nextValue instanceof IBaseHasModifierExtensions) {
IBaseHasModifierExtensions element = (IBaseHasModifierExtensions) nextValue;
List<? extends IBaseExtension<?>> ext = element.getModifierExtension();
addToHeldExtensions(valueIdx, ext, extensions, true);
}
}
} }
} }
@ -751,22 +771,44 @@ public class JsonParser extends BaseParser implements IParser {
} }
} }
private void extractUndeclaredExtensions(IBase theResource, List<HeldExtension> extensions, List<HeldExtension> modifierExtensions) { private void extractUndeclaredExtensions(IBase theElement, List<HeldExtension> extensions, List<HeldExtension> modifierExtensions) {
if (theResource instanceof ISupportsUndeclaredExtensions) { if (theElement instanceof ISupportsUndeclaredExtensions) {
List<ExtensionDt> ext = ((ISupportsUndeclaredExtensions) theResource).getUndeclaredExtensions(); ISupportsUndeclaredExtensions element = (ISupportsUndeclaredExtensions) theElement;
List<ExtensionDt> ext = element.getUndeclaredExtensions();
for (ExtensionDt next : ext) { for (ExtensionDt next : ext) {
if (next == null || next.isEmpty()) { if (next == null || next.isEmpty()) {
continue; continue;
} }
extensions.add(new HeldExtension(next)); extensions.add(new HeldExtension(next, false));
} }
ext = ((ISupportsUndeclaredExtensions) theResource).getUndeclaredModifierExtensions(); ext = element.getUndeclaredModifierExtensions();
for (ExtensionDt next : ext) { for (ExtensionDt next : ext) {
if (next == null || next.isEmpty()) { if (next == null || next.isEmpty()) {
continue; continue;
} }
modifierExtensions.add(new HeldExtension(next)); modifierExtensions.add(new HeldExtension(next, true));
}
} else {
if (theElement instanceof IBaseHasExtensions) {
IBaseHasExtensions element = (IBaseHasExtensions) theElement;
List<? extends IBaseExtension<?>> ext = element.getExtension();
for (IBaseExtension<?> next : ext) {
if (next == null || next.isEmpty()) {
continue;
}
extensions.add(new HeldExtension(next, false));
}
}
if (theElement instanceof IBaseHasModifierExtensions) {
IBaseHasModifierExtensions element = (IBaseHasModifierExtensions) theElement;
List<? extends IBaseExtension<?>> ext = element.getModifierExtension();
for (IBaseExtension<?> next : ext) {
if (next == null || next.isEmpty()) {
continue;
}
modifierExtensions.add(new HeldExtension(next, true));
}
} }
} }
} }
@ -788,16 +830,15 @@ public class JsonParser extends BaseParser implements IParser {
return; return;
} }
boolean newerThanDstu1 = myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1);
JsonObject alternate = (JsonObject) theAlternateVal; JsonObject alternate = (JsonObject) theAlternateVal;
for (Entry<String, JsonValue> nextEntry : alternate.entrySet()) { for (Entry<String, JsonValue> nextEntry : alternate.entrySet()) {
String nextKey = nextEntry.getKey(); String nextKey = nextEntry.getKey();
JsonValue nextVal = nextEntry.getValue(); JsonValue nextVal = nextEntry.getValue();
if (!newerThanDstu1 && "extension".equals(nextKey)) { if ("extension".equals(nextKey)) {
boolean isModifier = false; boolean isModifier = false;
JsonArray array = (JsonArray) nextEntry.getValue(); JsonArray array = (JsonArray) nextEntry.getValue();
parseExtension(theState, array, isModifier); parseExtension(theState, array, isModifier);
} else if (!newerThanDstu1 && "modifierExtension".equals(nextKey)) { } else if ("modifierExtension".equals(nextKey)) {
boolean isModifier = true; boolean isModifier = true;
JsonArray array = (JsonArray) nextEntry.getValue(); JsonArray array = (JsonArray) nextEntry.getValue();
parseExtension(theState, array, isModifier); parseExtension(theState, array, isModifier);
@ -811,12 +852,6 @@ public class JsonParser extends BaseParser implements IParser {
default: default:
break; break;
} }
} else if (newerThanDstu1) {
if (nextKey.indexOf(':') > -1 && newerThanDstu1) {
JsonArray array = (JsonArray) nextEntry.getValue();
parseExtensionInDstu2Style(false, theState, null, nextKey, array);
continue;
}
} }
} }
} }
@ -935,7 +970,6 @@ public class JsonParser extends BaseParser implements IParser {
private void parseChildren(JsonObject theObject, ParserState<?> theState) { private void parseChildren(JsonObject theObject, ParserState<?> theState) {
String elementId = null; String elementId = null;
boolean newerThanDstu1 = myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1);
for (String nextName : theObject.keySet()) { for (String nextName : theObject.keySet()) {
if ("resourceType".equals(nextName)) { if ("resourceType".equals(nextName)) {
continue; continue;
@ -948,29 +982,16 @@ public class JsonParser extends BaseParser implements IParser {
// _id is incorrect, but some early examples in the FHIR spec used it // _id is incorrect, but some early examples in the FHIR spec used it
elementId = theObject.getString(nextName); elementId = theObject.getString(nextName);
continue; continue;
} else if (!newerThanDstu1 && "extension".equals(nextName)) { } else if ("extension".equals(nextName)) {
JsonArray array = theObject.getJsonArray(nextName); JsonArray array = theObject.getJsonArray(nextName);
parseExtension(theState, array, false); parseExtension(theState, array, false);
continue; continue;
} else if (!newerThanDstu1 && "modifierExtension".equals(nextName)) { } else if ("modifierExtension".equals(nextName)) {
JsonArray array = theObject.getJsonArray(nextName); JsonArray array = theObject.getJsonArray(nextName);
parseExtension(theState, array, true); parseExtension(theState, array, true);
continue; continue;
} else if (newerThanDstu1 && "modifier".equals(nextName)) {
JsonObject obj = theObject.getJsonObject(nextName);
for (String nextUrl : obj.keySet()) {
JsonArray array = obj.getJsonArray(nextUrl);
parseExtensionInDstu2Style(true, theState, null, nextUrl, array);
}
continue;
} else if (nextName.charAt(0) == '_') { } else if (nextName.charAt(0) == '_') {
continue; continue;
} else {
if (newerThanDstu1 && nextName.indexOf(':') > -1) {
JsonArray array = theObject.getJsonArray(nextName);
parseExtensionInDstu2Style(false, theState, null, nextName, array);
continue;
}
} }
JsonValue nextVal = theObject.get(nextName); JsonValue nextVal = theObject.get(nextName);
@ -1210,36 +1231,13 @@ public class JsonParser extends BaseParser implements IParser {
private void writeExtensionsAsDirectChild(IBaseResource theResource, JsonGenerator theEventWriter, RuntimeResourceDefinition resDef, List<HeldExtension> extensions, private void writeExtensionsAsDirectChild(IBaseResource theResource, JsonGenerator theEventWriter, RuntimeResourceDefinition resDef, List<HeldExtension> extensions,
List<HeldExtension> modifierExtensions, String theParentExtensionUrl) throws IOException { List<HeldExtension> modifierExtensions, String theParentExtensionUrl) throws IOException {
if (extensions.isEmpty() == false) { if (extensions.isEmpty() == false) {
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
Collections.sort(extensions);
String currentlyWritingExtensionUrl = null;
for (HeldExtension next : extensions) {
currentlyWritingExtensionUrl = next.writeExtensionInDstu2Format(resDef, theResource, theEventWriter, currentlyWritingExtensionUrl, theParentExtensionUrl);
}
if (currentlyWritingExtensionUrl != null) {
theEventWriter.writeEnd();
}
} else {
theEventWriter.writeStartArray("extension"); theEventWriter.writeStartArray("extension");
for (HeldExtension next : extensions) { for (HeldExtension next : extensions) {
next.write(resDef, theResource, theEventWriter); next.write(resDef, theResource, theEventWriter);
} }
theEventWriter.writeEnd(); theEventWriter.writeEnd();
} }
}
if (modifierExtensions.isEmpty() == false) { if (modifierExtensions.isEmpty() == false) {
if (myContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
Collections.sort(modifierExtensions);
theEventWriter.writeStartObject("modifier");
String currentlyWritingExtensionUrl = null;
for (HeldExtension next : modifierExtensions) {
currentlyWritingExtensionUrl = next.writeExtensionInDstu2Format(resDef, theResource, theEventWriter, currentlyWritingExtensionUrl, theParentExtensionUrl);
}
if (currentlyWritingExtensionUrl != null) {
theEventWriter.writeEnd();
}
theEventWriter.writeEnd();
} else {
theEventWriter.writeStartArray("modifierExtension"); theEventWriter.writeStartArray("modifierExtension");
for (HeldExtension next : modifierExtensions) { for (HeldExtension next : modifierExtensions) {
next.write(resDef, theResource, theEventWriter); next.write(resDef, theResource, theEventWriter);
@ -1247,7 +1245,6 @@ public class JsonParser extends BaseParser implements IParser {
theEventWriter.writeEnd(); theEventWriter.writeEnd();
} }
} }
}
private void writeOptionalTagWithNumberNode(JsonGenerator theEventWriter, String theElementName, IntegerDt theValue) { private void writeOptionalTagWithNumberNode(JsonGenerator theEventWriter, String theElementName, IntegerDt theValue) {
if (theValue != null && theValue.isEmpty() == false) { if (theValue != null && theValue.isEmpty() == false) {
@ -1283,14 +1280,6 @@ public class JsonParser extends BaseParser implements IParser {
} }
} }
private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, String theValue) {
if (theValue != null && !theValue.isEmpty()) {
theEventWriter.write(theElementName, theValue);
} else {
theEventWriter.writeNull(theElementName);
}
}
private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, StringDt theStringDt) { private void writeTagWithTextNode(JsonGenerator theEventWriter, String theElementName, StringDt theStringDt) {
if (StringUtils.isNotBlank(theStringDt.getValue())) { if (StringUtils.isNotBlank(theStringDt.getValue())) {
theEventWriter.write(theElementName, theStringDt.getValue()); theEventWriter.write(theElementName, theStringDt.getValue());
@ -1303,12 +1292,14 @@ public class JsonParser extends BaseParser implements IParser {
private class HeldExtension implements Comparable<HeldExtension> { private class HeldExtension implements Comparable<HeldExtension> {
private RuntimeChildDeclaredExtensionDefinition myDef; private RuntimeChildDeclaredExtensionDefinition myDef;
private ExtensionDt myUndeclaredExtension; private IBaseExtension<?> myUndeclaredExtension;
private IBase myValue; private IBase myValue;
private boolean myModifier;
public HeldExtension(ExtensionDt theUndeclaredExtension) { public HeldExtension(IBaseExtension<?> theUndeclaredExtension, boolean theModifier) {
assert theUndeclaredExtension != null; assert theUndeclaredExtension != null;
myUndeclaredExtension = theUndeclaredExtension; myUndeclaredExtension = theUndeclaredExtension;
myModifier = theModifier;
} }
public HeldExtension(RuntimeChildDeclaredExtensionDefinition theDef, IBase theValue) { public HeldExtension(RuntimeChildDeclaredExtensionDefinition theDef, IBase theValue) {
@ -1337,66 +1328,38 @@ public class JsonParser extends BaseParser implements IParser {
} }
} }
public String writeExtensionInDstu2Format(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, String theCurrentlyWritingExtensionUrl, private void writeUndeclaredExtInDstu1Format(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, IBaseExtension<?> ext) throws IOException {
String theParentExtensionUrl) throws IOException { IBaseDatatype value = ext.getValue();
if (myUndeclaredExtension != null) { String extensionUrl = ext.getUrl();
return writeUndeclaredExtInDstu2Format(theResDef, theResource, theEventWriter, myUndeclaredExtension, theCurrentlyWritingExtensionUrl, theParentExtensionUrl);
} else {
String extensionUrl = myDef.getExtensionUrl();
checkIfNewExtensionUrlArrayIsNeeded(theEventWriter, extensionUrl, theCurrentlyWritingExtensionUrl, theParentExtensionUrl);
theEventWriter.writeStartObject();
BaseRuntimeElementDefinition<?> def = myDef.getChildElementDefinitionByDatatype(myValue.getClass());
if (def.getChildType() == ChildTypeEnum.RESOURCE_BLOCK) {
extractAndWriteExtensionsAsDirectChild(myValue, theEventWriter, def, theResDef, theResource, extensionUrl);
} else {
String childName = myDef.getChildNameByDatatype(myValue.getClass());
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, myValue, def, childName, false);
}
theEventWriter.writeEnd();
return extensionUrl;
}
}
private void checkIfNewExtensionUrlArrayIsNeeded(JsonGenerator theEventWriter, String theExtensionUrl, String theCurrentlyWritingExtensionUrl, String theParentExtensionUrl) {
if (StringUtils.equals(theCurrentlyWritingExtensionUrl, theExtensionUrl) == false) {
if (isNotBlank(theCurrentlyWritingExtensionUrl)) {
theEventWriter.writeEnd();
}
String urlToWrite = UrlUtil.constructRelativeUrl(theParentExtensionUrl, theExtensionUrl);
theEventWriter.writeStartArray(urlToWrite);
}
}
private void writeUndeclaredExtInDstu1Format(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, ExtensionDt ext) throws IOException {
IElement value = ext.getValue();
String extensionUrl = ext.getUrl().getValue();
theEventWriter.writeStartObject(); theEventWriter.writeStartObject();
theEventWriter.write("url", extensionUrl); theEventWriter.write("url", extensionUrl);
boolean noValue = value == null || value.isEmpty(); boolean noValue = value == null || value.isEmpty();
if (noValue && ext.getAllUndeclaredExtensions().isEmpty()) { if (noValue && ext.getExtension().isEmpty()) {
ourLog.debug("Extension with URL[{}] has no value", extensionUrl); ourLog.debug("Extension with URL[{}] has no value", extensionUrl);
} else if (noValue) { } else if (noValue) {
if (myModifier) {
theEventWriter.writeStartArray("modifierExtension");
}else {
theEventWriter.writeStartArray("extension"); theEventWriter.writeStartArray("extension");
}
for (ExtensionDt next : ext.getUndeclaredExtensions()) { for (Object next : ext.getExtension()) {
writeUndeclaredExtInDstu1Format(theResDef, theResource, theEventWriter, next); writeUndeclaredExtInDstu1Format(theResDef, theResource, theEventWriter, (IBaseExtension<?>) next);
} }
theEventWriter.writeEnd(); theEventWriter.writeEnd();
} else { } else {
RuntimeChildUndeclaredExtensionDefinition extDef = myContext.getRuntimeChildUndeclaredExtensionDefinition(); RuntimeChildUndeclaredExtensionDefinition extDef = myContext.getRuntimeChildUndeclaredExtensionDefinition();
String childName = extDef.getChildNameByDatatype(value.getClass()); String childName = extDef.getChildNameByDatatype(value.getClass());
if (childName == null) { if (childName == null) {
childName = "value" + myContext.getElementDefinition(value.getClass()).getName();
}
BaseRuntimeElementDefinition<?> childDef = myContext.getElementDefinition(value.getClass());
if (childDef == null) {
throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName()); throw new ConfigurationException("Unable to encode extension, unregognized child element type: " + value.getClass().getCanonicalName());
} }
BaseRuntimeElementDefinition<?> childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true); encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true);
} }
@ -1405,53 +1368,10 @@ public class JsonParser extends BaseParser implements IParser {
theEventWriter.writeEnd(); theEventWriter.writeEnd();
} }
private String writeUndeclaredExtInDstu2Format(RuntimeResourceDefinition theResDef, IBaseResource theResource, JsonGenerator theEventWriter, ExtensionDt ext,
String theCurrentlyWritingExtensionUrl, String theParentExtensionUrl) throws IOException {
IElement value = ext.getValue();
String extensionUrl = ext.getUrl().getValue();
checkIfNewExtensionUrlArrayIsNeeded(theEventWriter, extensionUrl, theCurrentlyWritingExtensionUrl, theParentExtensionUrl);
theEventWriter.writeStartObject();
boolean noValue = value == null || value.isEmpty();
if (noValue && ext.getAllUndeclaredExtensions().isEmpty()) {
ourLog.debug("Extension with URL[{}] has no value", extensionUrl);
} else if (noValue) {
BaseRuntimeElementDefinition<?> elemDef = null;
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theResource);
extractAndWriteExtensionsAsDirectChild(ext, theEventWriter, elemDef, resDef, theResource, extensionUrl);
} else {
RuntimeChildUndeclaredExtensionDefinition extDef = myContext.getRuntimeChildUndeclaredExtensionDefinition();
String childName = extDef.getChildNameByDatatype(value.getClass());
BaseRuntimeElementDefinition<?> childDef;
if (childName == null) {
childDef = myContext.getElementDefinition(value.getClass());
if (childDef == null) {
throw new ConfigurationException("Unable to encode extension, unrecognized child element type: " + value.getClass().getCanonicalName());
} else {
childName = RuntimeChildUndeclaredExtensionDefinition.createExtensionChildName(childDef);
}
} else {
childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
}
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, value, childDef, childName, true);
}
theEventWriter.writeEnd();
return extensionUrl;
}
@Override @Override
public int compareTo(HeldExtension theArg0) { public int compareTo(HeldExtension theArg0) {
String url1 = myDef != null ? myDef.getExtensionUrl() : myUndeclaredExtension.getUrlAsString(); String url1 = myDef != null ? myDef.getExtensionUrl() : myUndeclaredExtension.getUrl();
String url2 = theArg0.myDef != null ? theArg0.myDef.getExtensionUrl() : theArg0.myUndeclaredExtension.getUrlAsString(); String url2 = theArg0.myDef != null ? theArg0.myDef.getExtensionUrl() : theArg0.myUndeclaredExtension.getUrl();
url1 = defaultString(url1); url1 = defaultString(url1);
url2 = defaultString(url2); url2 = defaultString(url2);
return url1.compareTo(url2); return url1.compareTo(url2);

View File

@ -37,7 +37,11 @@ import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.ICompositeType; import org.hl7.fhir.instance.model.ICompositeType;
import org.hl7.fhir.instance.model.IPrimitiveType; import org.hl7.fhir.instance.model.IPrimitiveType;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseElement; import org.hl7.fhir.instance.model.api.IBaseElement;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
import org.hl7.fhir.instance.model.api.IReference; import org.hl7.fhir.instance.model.api.IReference;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
@ -61,6 +65,7 @@ import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.ICompositeDatatype; import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.ICompositeElement; import ca.uhn.fhir.model.api.ICompositeElement;
import ca.uhn.fhir.model.api.IElement; import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IExtension;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IIdentifiableElement; import ca.uhn.fhir.model.api.IIdentifiableElement;
import ca.uhn.fhir.model.api.IPrimitiveDatatype; import ca.uhn.fhir.model.api.IPrimitiveDatatype;
@ -818,12 +823,30 @@ class ParserState<T> {
elem.addUndeclaredExtension(newExtension); elem.addUndeclaredExtension(newExtension);
ExtensionState newState = new ExtensionState(myPreResourceState, newExtension); ExtensionState newState = new ExtensionState(myPreResourceState, newExtension);
push(newState); push(newState);
} else {
if (theIsModifier == false) {
if (getCurrentElement() instanceof IBaseHasExtensions) {
IBaseExtension<?> ext = ((IBaseHasExtensions)getCurrentElement()).addExtension();
ext.setUrl(theUrlAttr);
ParserState<T>.ExtensionState newState = new ExtensionState(myPreResourceState, ext);
push(newState);
} else {
throw new DataFormatException("Type " + getCurrentElement() + " does not support undeclared extentions, and found an extension with URL: " + theUrlAttr);
}
}else {
if (getCurrentElement() instanceof IBaseHasModifierExtensions) {
IBaseExtension<?> ext = ((IBaseHasModifierExtensions)getCurrentElement()).addModifierExtension();
ext.setUrl(theUrlAttr);
ParserState<T>.ExtensionState newState = new ExtensionState(myPreResourceState, ext);
push(newState);
} else { } else {
throw new DataFormatException("Type " + getCurrentElement() + " does not support undeclared extentions, and found an extension with URL: " + theUrlAttr); throw new DataFormatException("Type " + getCurrentElement() + " does not support undeclared extentions, and found an extension with URL: " + theUrlAttr);
} }
} }
}
}
protected Object getCurrentElement() { protected IBase getCurrentElement() {
return null; return null;
} }
@ -879,7 +902,7 @@ class ParserState<T> {
if ("id".equals(theName)) { if ("id".equals(theName)) {
if (myInstance instanceof IIdentifiableElement) { if (myInstance instanceof IIdentifiableElement) {
((IIdentifiableElement) myInstance).setElementSpecificId((theValue)); ((IIdentifiableElement) myInstance).setElementSpecificId((theValue));
} else if (myInstance instanceof IBaseResource) { } else {
(myInstance).setId(new IdDt(theValue)); (myInstance).setId(new IdDt(theValue));
} }
} else if ("contentType".equals(theName)) { } else if ("contentType".equals(theName)) {
@ -1578,16 +1601,16 @@ class ParserState<T> {
private class ExtensionState extends BaseState { private class ExtensionState extends BaseState {
private ExtensionDt myExtension; private IBaseExtension<?> myExtension;
public ExtensionState(PreResourceState thePreResourceState, ExtensionDt theExtension) { public ExtensionState(PreResourceState thePreResourceState, IBaseExtension<?> theExtension) {
super(thePreResourceState); super(thePreResourceState);
myExtension = theExtension; myExtension = theExtension;
} }
@Override @Override
public void endingElement() throws DataFormatException { public void endingElement() throws DataFormatException {
if (myExtension.getValue() != null && myExtension.getUndeclaredExtensions().size() > 0) { if (myExtension.getValue() != null && myExtension.getExtension().size() > 0) {
throw new DataFormatException("Extension must not have both a value and other contained extensions"); throw new DataFormatException("Extension must not have both a value and other contained extensions");
} }
pop(); pop();
@ -1612,7 +1635,7 @@ class ParserState<T> {
case PRIMITIVE_DATATYPE: { case PRIMITIVE_DATATYPE: {
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target; RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(); IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
myExtension.setValue((IElement) newChildInstance); myExtension.setValue(newChildInstance);
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance); PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
push(newState); push(newState);
return; return;
@ -1635,7 +1658,7 @@ class ParserState<T> {
} }
@Override @Override
protected IElement getCurrentElement() { protected IBaseExtension<?> getCurrentElement() {
return myExtension; return myExtension;
} }
@ -1805,6 +1828,15 @@ class ParserState<T> {
super(theResourceType); super(theResourceType);
} }
@SuppressWarnings("unchecked")
@Override
public void wereBack() {
super.wereBack();
if (myTarget == null) {
myObject = (T) getCurrentElement();
}
}
@Override @Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
super.enteringNewElement(theNamespaceURI, theLocalPart); super.enteringNewElement(theNamespaceURI, theLocalPart);
@ -1953,7 +1985,7 @@ class ParserState<T> {
} }
@Override @Override
protected TagList getCurrentElement() { protected IBase getCurrentElement() {
return myTagList; return myTagList;
} }
@ -2237,6 +2269,11 @@ class ParserState<T> {
pop(); pop();
} }
@Override
protected IBase getCurrentElement() {
return myTagList;
}
@Override @Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (TagList.ATTR_CATEGORY.equals(theLocalPart)) { if (TagList.ATTR_CATEGORY.equals(theLocalPart)) {

View File

@ -27,8 +27,10 @@ import java.io.Reader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
import javax.xml.stream.FactoryConfigurationError; import javax.xml.stream.FactoryConfigurationError;
@ -49,6 +51,10 @@ import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.IPrimitiveType; import org.hl7.fhir.instance.model.IPrimitiveType;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
import org.hl7.fhir.instance.model.api.IDomainResource; import org.hl7.fhir.instance.model.api.IDomainResource;
import org.hl7.fhir.instance.model.api.INarrative; import org.hl7.fhir.instance.model.api.INarrative;
@ -171,7 +177,6 @@ public class XmlParser extends BaseParser implements IParser {
throw new DataFormatException("Extension element has no 'url' attribute"); throw new DataFormatException("Extension element has no 'url' attribute");
} }
parserState.enteringNewElementExtension(elem, urlAttr.getValue(), true); parserState.enteringNewElementExtension(elem, urlAttr.getValue(), true);
} else { } else {
String elementName = elem.getName().getLocalPart(); String elementName = elem.getName().getLocalPart();
@ -433,8 +438,8 @@ public class XmlParser extends BaseParser implements IParser {
theEventWriter.close(); theEventWriter.close();
} }
private void encodeChildElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, XMLStreamWriter theEventWriter, IBase nextValue, String childName, private void encodeChildElementToStreamWriter(IBaseResource theResource, XMLStreamWriter theEventWriter, IBase nextValue, String childName, BaseRuntimeElementDefinition<?> childDef,
BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl, boolean theIncludedResource) throws XMLStreamException, DataFormatException { String theExtensionUrl, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
if (nextValue.isEmpty()) { if (nextValue.isEmpty()) {
if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && getContainedResources().isEmpty() == false && theIncludedResource == false) { if (childDef.getChildType() == ChildTypeEnum.CONTAINED_RESOURCES && getContainedResources().isEmpty() == false && theIncludedResource == false) {
// We still want to go in.. // We still want to go in..
@ -450,7 +455,7 @@ public class XmlParser extends BaseParser implements IParser {
if (value != null) { if (value != null) {
theEventWriter.writeStartElement(childName); theEventWriter.writeStartElement(childName);
theEventWriter.writeAttribute("value", value); theEventWriter.writeAttribute("value", value);
encodeExtensionsIfPresent(theResDef, theResource, theEventWriter, nextValue, theIncludedResource); encodeExtensionsIfPresent(theResource, theEventWriter, nextValue, theIncludedResource);
theEventWriter.writeEndElement(); theEventWriter.writeEndElement();
} }
break; break;
@ -462,7 +467,7 @@ public class XmlParser extends BaseParser implements IParser {
theEventWriter.writeAttribute("url", theExtensionUrl); theEventWriter.writeAttribute("url", theExtensionUrl);
} }
BaseRuntimeElementCompositeDefinition<?> childCompositeDef = (BaseRuntimeElementCompositeDefinition<?>) childDef; BaseRuntimeElementCompositeDefinition<?> childCompositeDef = (BaseRuntimeElementCompositeDefinition<?>) childDef;
encodeCompositeElementToStreamWriter(theResDef, theResource, nextValue, theEventWriter, childCompositeDef, theIncludedResource); encodeCompositeElementToStreamWriter(theResource, nextValue, theEventWriter, childCompositeDef, theIncludedResource);
theEventWriter.writeEndElement(); theEventWriter.writeEndElement();
break; break;
} }
@ -512,21 +517,26 @@ public class XmlParser extends BaseParser implements IParser {
} }
private void encodeCompositeElementChildrenToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theElement, XMLStreamWriter theEventWriter, private void encodeCompositeElementChildrenToStreamWriter(IBaseResource theResource, IBase theElement, XMLStreamWriter theEventWriter, List<? extends BaseRuntimeChildDefinition> children,
List<? extends BaseRuntimeChildDefinition> children, boolean theIncludedResource) throws XMLStreamException, DataFormatException { boolean theIncludedResource) throws XMLStreamException, DataFormatException {
for (BaseRuntimeChildDefinition nextChild : children) { for (BaseRuntimeChildDefinition nextChild : children) {
if (nextChild.getElementName().equals("extension") || nextChild.getElementName().equals("modifierExtension")) {
continue;
}
if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) { if (nextChild instanceof RuntimeChildNarrativeDefinition && !theIncludedResource) {
INarrativeGenerator gen = myContext.getNarrativeGenerator(); INarrativeGenerator gen = myContext.getNarrativeGenerator();
if (theResource instanceof IResource) { if (theResource instanceof IResource) {
BaseNarrativeDt<?> narr = ((IResource) theResource).getText(); BaseNarrativeDt<?> narr = ((IResource) theResource).getText();
if (gen != null && narr.isEmpty()) { if (gen != null && narr.isEmpty()) {
gen.generateNarrative(theResDef.getResourceProfile(), theResource, narr); String resourceProfile = myContext.getResourceDefinition(theResource).getResourceProfile();
gen.generateNarrative(resourceProfile, theResource, narr);
} }
if (narr.isEmpty() == false) { if (narr.isEmpty() == false) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
String childName = nextChild.getChildNameByDatatype(child.getDatatype()); String childName = nextChild.getChildNameByDatatype(child.getDatatype());
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName); BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr, childName, type, null, theIncludedResource); encodeChildElementToStreamWriter(theResource, theEventWriter, narr, childName, type, null, theIncludedResource);
continue; continue;
} }
} else { } else {
@ -534,13 +544,14 @@ public class XmlParser extends BaseParser implements IParser {
BaseNarrativeDt<?> narr2 = null; BaseNarrativeDt<?> narr2 = null;
if (gen != null && narr1.isEmpty()) { if (gen != null && narr1.isEmpty()) {
// TODO: need to implement this // TODO: need to implement this
gen.generateNarrative(theResDef.getResourceProfile(), theResource, null); String resourceProfile = myContext.getResourceDefinition(theResource).getResourceProfile();
gen.generateNarrative(resourceProfile, theResource, null);
} }
if (narr2 != null) { if (narr2 != null) {
RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild; RuntimeChildNarrativeDefinition child = (RuntimeChildNarrativeDefinition) nextChild;
String childName = nextChild.getChildNameByDatatype(child.getDatatype()); String childName = nextChild.getChildNameByDatatype(child.getDatatype());
BaseRuntimeElementDefinition<?> type = child.getChildByName(childName); BaseRuntimeElementDefinition<?> type = child.getChildByName(childName);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, narr2, childName, type, null, theIncludedResource); encodeChildElementToStreamWriter(theResource, theEventWriter, narr2, childName, type, null, theIncludedResource);
continue; continue;
} }
} }
@ -563,10 +574,10 @@ public class XmlParser extends BaseParser implements IParser {
super.throwExceptionForUnknownChildType(nextChild, type); super.throwExceptionForUnknownChildType(nextChild, type);
} }
if (nextValue instanceof ExtensionDt) { if (nextValue instanceof IBaseExtension && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
// This is called for the Query resource in DSTU1 only
extensionUrl = ((ExtensionDt) nextValue).getUrlAsString(); extensionUrl = ((IBaseExtension<?>) nextValue).getUrl();
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource); encodeChildElementToStreamWriter(theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource);
} else if (extensionUrl != null && childName.equals("extension") == false) { } else if (extensionUrl != null && childName.equals("extension") == false) {
RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition) nextChild; RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition) nextChild;
@ -577,31 +588,48 @@ public class XmlParser extends BaseParser implements IParser {
} }
theEventWriter.writeAttribute("url", extensionUrl); theEventWriter.writeAttribute("url", extensionUrl);
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, null, theIncludedResource); encodeChildElementToStreamWriter(theResource, theEventWriter, nextValue, childName, childDef, null, theIncludedResource);
theEventWriter.writeEndElement(); theEventWriter.writeEndElement();
} else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIncludedResource) { } else if (nextChild instanceof RuntimeChildNarrativeDefinition && theIncludedResource) {
// suppress narratives from contained resources // suppress narratives from contained resources
} else { } else {
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource); encodeChildElementToStreamWriter(theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource);
} }
} }
} }
} }
private void encodeCompositeElementToStreamWriter(RuntimeResourceDefinition theResDef, IBaseResource theResource, IBase theElement, XMLStreamWriter theEventWriter, private void encodeCompositeElementToStreamWriter(IBaseResource theResource, IBase theElement, XMLStreamWriter theEventWriter, BaseRuntimeElementCompositeDefinition<?> theElementDefinition,
BaseRuntimeElementCompositeDefinition<?> resDef, boolean theIncludedResource) throws XMLStreamException, DataFormatException { boolean theIncludedResource) throws XMLStreamException, DataFormatException {
encodeExtensionsIfPresent(theResDef, theResource, theEventWriter, theElement, theIncludedResource); encodeExtensionsIfPresent(theResource, theEventWriter, theElement, theIncludedResource);
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions(), theIncludedResource); encodeCompositeElementChildrenToStreamWriter(theResource, theElement, theEventWriter, theElementDefinition.getExtensions(), theIncludedResource);
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getChildren(), theIncludedResource); encodeCompositeElementChildrenToStreamWriter(theResource, theElement, theEventWriter, theElementDefinition.getChildren(), theIncludedResource);
} }
private void encodeExtensionsIfPresent(RuntimeResourceDefinition theResDef, IBaseResource theResource, XMLStreamWriter theWriter, IBase theElement, boolean theIncludedResource) private void encodeExtensionsIfPresent(IBaseResource theResource, XMLStreamWriter theWriter, IBase theElement, boolean theIncludedResource) throws XMLStreamException, DataFormatException {
throws XMLStreamException, DataFormatException {
if (theElement instanceof ISupportsUndeclaredExtensions) { if (theElement instanceof ISupportsUndeclaredExtensions) {
ISupportsUndeclaredExtensions res = (ISupportsUndeclaredExtensions) theElement; ISupportsUndeclaredExtensions res = (ISupportsUndeclaredExtensions) theElement;
encodeUndeclaredExtensions(theResDef, theResource, theWriter, res.getUndeclaredExtensions(), "extension", theIncludedResource); encodeUndeclaredExtensions(theResource, theWriter, toBaseExtensionList(res.getUndeclaredExtensions()), "extension", theIncludedResource);
encodeUndeclaredExtensions(theResDef, theResource, theWriter, res.getUndeclaredModifierExtensions(), "modifierExtension", theIncludedResource); encodeUndeclaredExtensions(theResource, theWriter, toBaseExtensionList(res.getUndeclaredModifierExtensions()), "modifierExtension", theIncludedResource);
} }
if (theElement instanceof IBaseHasExtensions) {
IBaseHasExtensions res = (IBaseHasExtensions) theElement;
encodeUndeclaredExtensions(theResource, theWriter, res.getExtension(), "extension", theIncludedResource);
}
if (theElement instanceof IBaseHasModifierExtensions) {
IBaseHasModifierExtensions res = (IBaseHasModifierExtensions) theElement;
encodeUndeclaredExtensions(theResource, theWriter, res.getModifierExtension(), "modifierExtension", theIncludedResource);
}
}
/**
* This is just to work around the fact that casting java.util.List<ca.uhn.fhir.model.api.ExtensionDt> to java.util.List<? extends org.hl7.fhir.instance.model.api.IBaseExtension<?>> seems to be
* rejected by the compiler some of the time.
*/
private <Q extends IBaseExtension<?>> List<IBaseExtension<?>> toBaseExtensionList(final List<Q> theList) {
List<IBaseExtension<?>> retVal = new ArrayList<IBaseExtension<?>>(theList.size());
retVal.addAll(theList);
return retVal;
} }
private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, BaseResourceReferenceDt theRef) throws XMLStreamException { private void encodeResourceReferenceToStreamWriter(XMLStreamWriter theEventWriter, BaseResourceReferenceDt theRef) throws XMLStreamException {
@ -638,12 +666,12 @@ public class XmlParser extends BaseParser implements IParser {
postExtensionChildren.add(next); postExtensionChildren.add(next);
} }
} }
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, preExtensionChildren, theIncludedResource); encodeCompositeElementChildrenToStreamWriter(theResource, theElement, theEventWriter, preExtensionChildren, theIncludedResource);
encodeExtensionsIfPresent(theResDef, theResource, theEventWriter, theElement, theIncludedResource); encodeExtensionsIfPresent(theResource, theEventWriter, theElement, theIncludedResource);
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, resDef.getExtensions(), theIncludedResource); encodeCompositeElementChildrenToStreamWriter(theResource, theElement, theEventWriter, resDef.getExtensions(), theIncludedResource);
encodeCompositeElementChildrenToStreamWriter(theResDef, theResource, theElement, theEventWriter, postExtensionChildren, theIncludedResource); encodeCompositeElementChildrenToStreamWriter(theResource, theElement, theEventWriter, postExtensionChildren, theIncludedResource);
} }
@ -706,7 +734,7 @@ public class XmlParser extends BaseParser implements IParser {
if (theResource instanceof IAnyResource) { if (theResource instanceof IAnyResource) {
// HL7.org Structures // HL7.org Structures
encodeCompositeElementToStreamWriter(resDef, theResource, theResource, theEventWriter, resDef, theContainedResource); encodeCompositeElementToStreamWriter(theResource, theResource, theEventWriter, resDef, theContainedResource);
} else { } else {
@ -753,7 +781,7 @@ public class XmlParser extends BaseParser implements IParser {
} }
theEventWriter.writeCharacters(bin.getContentAsBase64()); theEventWriter.writeCharacters(bin.getContentAsBase64());
} else { } else {
encodeCompositeElementToStreamWriter(resDef, theResource, theResource, theEventWriter, resDef, theContainedResource); encodeCompositeElementToStreamWriter(theResource, theResource, theEventWriter, resDef, theContainedResource);
} }
} }
@ -794,25 +822,20 @@ public class XmlParser extends BaseParser implements IParser {
} }
} }
private void encodeUndeclaredExtensions(RuntimeResourceDefinition theResDef, IBaseResource theResource, XMLStreamWriter theWriter, List<ExtensionDt> theExtensions, String tagName, private void encodeUndeclaredExtensions(IBaseResource theResource, XMLStreamWriter theWriter, List<? extends IBaseExtension<?>> theExtensions, String tagName, boolean theIncludedResource)
boolean theIncludedResource) throws XMLStreamException, DataFormatException { throws XMLStreamException, DataFormatException {
for (ExtensionDt next : theExtensions) { for (IBaseExtension<?> next : theExtensions) {
if (next == null) {
continue;
}
theWriter.writeStartElement(tagName); theWriter.writeStartElement(tagName);
theWriter.writeAttribute("url", next.getUrl().getValue());
String url = next.getUrl();
theWriter.writeAttribute("url", url);
if (next.getValue() != null) { if (next.getValue() != null) {
IElement value = next.getValue(); IBaseDatatype value = next.getValue();
// RuntimeChildUndeclaredExtensionDefinition extDef =
// myContext.getRuntimeChildUndeclaredExtensionDefinition();
// String childName = extDef.getChildNameByDatatype(nextValue.getClass());
// if (childName == null) {
// throw new ConfigurationException("Unable to encode extension, unregognized child element type: " +
// nextValue.getClass().getCanonicalName());
// }
// BaseRuntimeElementDefinition<?> childDef =
// extDef.getChildElementDefinitionByDatatype(nextValue.getClass());
//
//
RuntimeChildUndeclaredExtensionDefinition extDef = myContext.getRuntimeChildUndeclaredExtensionDefinition(); RuntimeChildUndeclaredExtensionDefinition extDef = myContext.getRuntimeChildUndeclaredExtensionDefinition();
String childName = extDef.getChildNameByDatatype(value.getClass()); String childName = extDef.getChildNameByDatatype(value.getClass());
BaseRuntimeElementDefinition<?> childDef; BaseRuntimeElementDefinition<?> childDef;
@ -826,11 +849,11 @@ public class XmlParser extends BaseParser implements IParser {
} else { } else {
childDef = extDef.getChildElementDefinitionByDatatype(value.getClass()); childDef = extDef.getChildElementDefinitionByDatatype(value.getClass());
} }
encodeChildElementToStreamWriter(theResDef, theResource, theWriter, value, childName, childDef, null, theIncludedResource); encodeChildElementToStreamWriter(theResource, theWriter, value, childName, childDef, null, theIncludedResource);
} }
// child extensions // child extensions
encodeExtensionsIfPresent(theResDef, theResource, theWriter, next, theIncludedResource); encodeExtensionsIfPresent(theResource, theWriter, next, theIncludedResource);
theWriter.writeEndElement(); theWriter.writeEndElement();
} }

View File

@ -26,15 +26,12 @@ import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import ca.uhn.fhir.rest.annotation.*;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
@ -47,6 +44,18 @@ import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum; import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum; import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.parser.IParser; import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.annotation.AddTags;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.DeleteTags;
import ca.uhn.fhir.rest.annotation.GetTags;
import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.MethodOutcome; import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation; import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException; import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
@ -61,9 +70,9 @@ import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException; import ca.uhn.fhir.rest.server.exceptions.MethodNotAllowedException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException; import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException; import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionNotSpecifiedException;
import ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException; import ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.ReflectionUtil; import ca.uhn.fhir.util.ReflectionUtil;
@ -217,7 +226,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
ex = new ResourceVersionConflictException("Server responded with HTTP 409"); ex = new ResourceVersionConflictException("Server responded with HTTP 409");
break; break;
case Constants.STATUS_HTTP_412_PRECONDITION_FAILED: case Constants.STATUS_HTTP_412_PRECONDITION_FAILED:
ex = new ResourceVersionNotSpecifiedException("Server responded with HTTP 412"); ex = new PreconditionFailedException("Server responded with HTTP 412");
break; break;
case Constants.STATUS_HTTP_422_UNPROCESSABLE_ENTITY: case Constants.STATUS_HTTP_422_UNPROCESSABLE_ENTITY:
IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theStatusCode); IParser parser = createAppropriateParserForParsingResponse(theResponseMimeType, theResponseReader, theStatusCode);

View File

@ -0,0 +1,25 @@
package org.hl7.fhir.instance.model.api;
public interface IBaseEnumFactory<T extends Enum<?>> {
/**
* Read an enumeration value from the string that represents it on the XML or JSON
*
* @param codeString
* the value found in the XML or JSON
* @return the enumeration value
* @throws IllegalArgumentException
* is the value is not known
*/
public T fromCode(String codeString) throws IllegalArgumentException;
/**
* Get the XML/JSON representation for an enumerated value
*
* @param code
* - the enumeration value
* @return the XML/JSON representation
*/
public String toCode(T code);
}

View File

@ -12,4 +12,8 @@ public interface IBaseExtension<T> extends ICompositeType {
IBaseDatatype getValue(); IBaseDatatype getValue();
T setUrl(String theUrl);
T setValue(IBaseDatatype theValue);
} }

View File

@ -0,0 +1,11 @@
package org.hl7.fhir.instance.model.api;
import java.util.List;
public interface IBaseHasExtensions {
public List<? extends IBaseExtension<?>> getExtension();
public IBaseExtension<?> addExtension();
}

View File

@ -0,0 +1,11 @@
package org.hl7.fhir.instance.model.api;
import java.util.List;
public interface IBaseHasModifierExtensions {
public List<? extends IBaseExtension<?>> getModifierExtension();
public IBaseExtension<?> addModifierExtension();
}

View File

@ -22,7 +22,7 @@ public class MultiVersionJsonParserTest {
String str = FhirContext.forDstu2().newJsonParser().encodeResourceToString(p); String str = FhirContext.forDstu2().newJsonParser().encodeResourceToString(p);
ourLog.info(str); ourLog.info(str);
assertThat(str,StringContains.containsString("{\"resourceType\":\"Patient\",\"http://foo#ext\":[{\"valueQuantity\":{\"value\":2.2}}],\"identifier\":[{\"system\":\"urn:sys\",\"value\":\"001\"}]}")); assertThat(str,StringContains.containsString("{\"resourceType\":\"Patient\",\"extension\":[{\"url\":\"http://foo#ext\",\"valueQuantity\":{\"value\":2.2}}],\"identifier\":[{\"system\":\"urn:sys\",\"value\":\"001\"}]}"));
} }
} }

View File

@ -19,7 +19,8 @@ public class ValidatorTest {
assertTrue(val.isValidateAgainstStandardSchema()); assertTrue(val.isValidateAgainstStandardSchema());
assertFalse(val.isValidateAgainstStandardSchematron()); assertFalse(val.isValidateAgainstStandardSchematron());
try { val.setValidateAgainstStandardSchematron(true); try {
val.setValidateAgainstStandardSchematron(true);
fail(); fail();
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
assertEquals("Phloc-schematron library not found on classpath, can not enable perform schematron validation", e.getMessage()); assertEquals("Phloc-schematron library not found on classpath, can not enable perform schematron validation", e.getMessage());

View File

@ -9,6 +9,7 @@ import org.springframework.web.context.WebApplicationContext;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1; import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu1;
import ca.uhn.fhir.jpa.provider.JpaSystemProviderDstu2;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator; import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.server.ETagSupportEnum; import ca.uhn.fhir.rest.server.ETagSupportEnum;
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider; import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
@ -48,7 +49,7 @@ public class JpaServerDemo extends RestfulServer {
* The system provider implements non-resource-type methods, such as * The system provider implements non-resource-type methods, such as
* transaction, and global history. * transaction, and global history.
*/ */
JpaSystemProviderDstu1 systemProvider = myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu1.class); JpaSystemProviderDstu2 systemProvider = myAppCtx.getBean("mySystemProviderDstu2", JpaSystemProviderDstu2.class);
setPlainProviders(systemProvider); setPlainProviders(systemProvider);
/* /*

View File

@ -23,10 +23,12 @@ package ca.uhn.fhir.model.dev;
import java.io.InputStream; import java.io.InputStream;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.composite.BaseContainedDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt;
@ -102,6 +104,4 @@ public class FhirDev implements IFhirVersion {
return ContainedDt.class; return ContainedDt.class;
} }
} }

View File

@ -57,7 +57,6 @@ import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition; import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
import ca.uhn.fhir.model.api.ICompositeDatatype; import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IPrimitiveDatatype; import ca.uhn.fhir.model.api.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
@ -378,6 +377,4 @@ public class FhirDstu1 implements IFhirVersion {
return ContainedDt.class; return ContainedDt.class;
} }
} }

View File

@ -1,9 +1,15 @@
package ca.uhn.fhir.parser; package ca.uhn.fhir.parser;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*; import static org.hamcrest.Matchers.not;
import static org.mockito.Matchers.*; import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.mockito.Mockito.*; import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
@ -24,8 +30,6 @@ import org.hamcrest.text.StringContainsInOrder;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.Matchers;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
@ -41,7 +45,6 @@ import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt; import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.dstu.composite.AddressDt; import ca.uhn.fhir.model.dstu.composite.AddressDt;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt; import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.NarrativeDt;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt; import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Binary; import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.dstu.resource.Conformance; import ca.uhn.fhir.model.dstu.resource.Conformance;
@ -59,7 +62,10 @@ import ca.uhn.fhir.model.dstu.resource.ValueSet;
import ca.uhn.fhir.model.dstu.resource.ValueSet.Define; import ca.uhn.fhir.model.dstu.resource.ValueSet.Define;
import ca.uhn.fhir.model.dstu.resource.ValueSet.DefineConcept; import ca.uhn.fhir.model.dstu.resource.ValueSet.DefineConcept;
import ca.uhn.fhir.model.dstu.valueset.AddressUseEnum; import ca.uhn.fhir.model.dstu.valueset.AddressUseEnum;
import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum; import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.DecimalDt; import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
@ -94,6 +100,120 @@ public class JsonParserTest {
} }
@Test
public void testEncodeAndParseExtensions() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
ExtensionDt ext = new ExtensionDt();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
patient.addUndeclaredExtension(ext);
ExtensionDt parent = new ExtensionDt().setUrl("http://example.com#parent");
patient.addUndeclaredExtension(parent);
ExtensionDt child1 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value1"));
parent.addUndeclaredExtension(child1);
ExtensionDt child2 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value2"));
parent.addUndeclaredExtension(child2);
ExtensionDt modExt = new ExtensionDt();
modExt.setUrl("http://example.com/extensions#modext");
modExt.setValue(new DateDt("1995-01-02"));
modExt.setModifier(true);
patient.addUndeclaredExtension(modExt);
HumanNameDt name = patient.addName();
name.addFamily("Blah");
StringDt given = name.addGiven();
given.setValue("Joe");
ExtensionDt ext2 = new ExtensionDt().setUrl("http://examples.com#givenext").setValue(new StringDt("given"));
given.addUndeclaredExtension(ext2);
StringDt given2 = name.addGiven();
given2.setValue("Shmoe");
ExtensionDt given2ext = new ExtensionDt().setUrl("http://examples.com#givenext_parent");
given2.addUndeclaredExtension(given2ext);
given2ext.addUndeclaredExtension(new ExtensionDt().setUrl("http://examples.com#givenext_child").setValue(new StringDt("CHILD")));
String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
assertThat(enc, org.hamcrest.Matchers.stringContainsInOrder("{\"resourceType\":\"Patient\",",
"\"extension\":[{\"url\":\"http://example.com/extensions#someext\",\"valueDateTime\":\"2011-01-02T11:13:15\"}",
"{\"url\":\"http://example.com#parent\",\"extension\":[{\"url\":\"http://example.com#child\",\"valueString\":\"value1\"},{\"url\":\"http://example.com#child\",\"valueString\":\"value2\"}]}"
));
assertThat(enc, org.hamcrest.Matchers.stringContainsInOrder("\"modifierExtension\":[" +
"{" +
"\"url\":\"http://example.com/extensions#modext\"," +
"\"valueDate\":\"1995-01-02\"" +
"}" +
"],"));
assertThat(enc, containsString("\"_given\":[" +
"{" +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext\"," +
"\"valueString\":\"given\"" +
"}" +
"]" +
"}," +
"{" +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext_parent\"," +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext_child\"," +
"\"valueString\":\"CHILD\"" +
"}" +
"]" +
"}" +
"]" +
"}"));
/*
* Now parse this back
*/
Patient parsed =ourCtx.newJsonParser().parseResource(Patient.class, enc);
ext = parsed.getUndeclaredExtensions().get(0);
assertEquals("http://example.com/extensions#someext", ext.getUrl());
assertEquals("2011-01-02T11:13:15", ((DateTimeDt)ext.getValue()).getValueAsString());
parent = patient.getUndeclaredExtensions().get(1);
assertEquals("http://example.com#parent", parent.getUrl());
assertNull(parent.getValue());
child1 = parent.getExtension().get(0);
assertEquals( "http://example.com#child", child1.getUrl());
assertEquals("value1", ((StringDt)child1.getValue()).getValueAsString());
child2 = parent.getExtension().get(1);
assertEquals( "http://example.com#child", child2.getUrl());
assertEquals("value2", ((StringDt)child2.getValue()).getValueAsString());
modExt = parsed.getUndeclaredModifierExtensions().get(0);
assertEquals("http://example.com/extensions#modext", modExt.getUrl());
assertEquals("1995-01-02", ((DateDt)modExt.getValue()).getValueAsString());
name = parsed.getName().get(0);
ext2 = name.getGiven().get(0).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext", ext2.getUrl());
assertEquals("given", ((StringDt)ext2.getValue()).getValueAsString());
given2ext = name.getGiven().get(1).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
assertNull(given2ext.getValue());
ExtensionDt given2ext2 = given2ext.getExtension().get(0);
assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
assertEquals("CHILD", ((StringDt)given2ext2.getValue()).getValue());
}
/** /**
* #65 * #65
*/ */
@ -1136,7 +1256,7 @@ public class JsonParserTest {
List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions();
ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); ExtensionDt undeclaredExtension = undeclaredExtensions.get(0);
assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl());
ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out)); ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out));
@ -1184,7 +1304,7 @@ public class JsonParserTest {
List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions();
ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); ExtensionDt undeclaredExtension = undeclaredExtensions.get(0);
assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl());
IParser jsonParser = fhirCtx.newJsonParser().setPrettyPrint(true); IParser jsonParser = fhirCtx.newJsonParser().setPrettyPrint(true);
String encoded = jsonParser.encodeResourceToString(obs); String encoded = jsonParser.encodeResourceToString(obs);

View File

@ -67,6 +67,7 @@ import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
import ca.uhn.fhir.model.dstu.valueset.DocumentReferenceStatusEnum; import ca.uhn.fhir.model.dstu.valueset.DocumentReferenceStatusEnum;
import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum; import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum; import ca.uhn.fhir.model.dstu.valueset.NarrativeStatusEnum;
import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.DecimalDt; import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
@ -151,6 +152,95 @@ public class XmlParserTest {
} }
@Test
public void testEncodeAndParseExtensions() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
ExtensionDt ext = new ExtensionDt();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
patient.addUndeclaredExtension(ext);
ExtensionDt parent = new ExtensionDt().setUrl("http://example.com#parent");
patient.addUndeclaredExtension(parent);
ExtensionDt child1 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value1"));
parent.addUndeclaredExtension(child1);
ExtensionDt child2 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value2"));
parent.addUndeclaredExtension(child2);
ExtensionDt modExt = new ExtensionDt();
modExt.setUrl("http://example.com/extensions#modext");
modExt.setValue(new DateDt("1995-01-02"));
modExt.setModifier(true);
patient.addUndeclaredExtension(modExt);
HumanNameDt name = patient.addName();
name.addFamily("Blah");
StringDt given = name.addGiven();
given.setValue("Joe");
ExtensionDt ext2 = new ExtensionDt().setUrl("http://examples.com#givenext").setValue(new StringDt("given"));
given.addUndeclaredExtension(ext2);
StringDt given2 = name.addGiven();
given2.setValue("Shmoe");
ExtensionDt given2ext = new ExtensionDt().setUrl("http://examples.com#givenext_parent");
given2.addUndeclaredExtension(given2ext);
given2ext.addUndeclaredExtension(new ExtensionDt().setUrl("http://examples.com#givenext_child").setValue(new StringDt("CHILD")));
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
assertThat(enc, containsString("<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://example.com/extensions#someext\"><valueDateTime value=\"2011-01-02T11:13:15\"/></extension>"));
assertThat(enc, containsString("<modifierExtension url=\"http://example.com/extensions#modext\"><valueDate value=\"1995-01-02\"/></modifierExtension>"));
assertThat(
enc,
containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value2\"/></extension></extension>"));
assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
assertThat(enc, containsString("<given value=\"Shmoe\"><extension url=\"http://examples.com#givenext_parent\"><extension url=\"http://examples.com#givenext_child\"><valueString value=\"CHILD\"/></extension></extension></given>"));
/*
* Now parse this back
*/
Patient parsed =ourCtx.newXmlParser().parseResource(Patient.class, enc);
ext = parsed.getUndeclaredExtensions().get(0);
assertEquals("http://example.com/extensions#someext", ext.getUrl());
assertEquals("2011-01-02T11:13:15", ((DateTimeDt)ext.getValue()).getValueAsString());
parent = patient.getUndeclaredExtensions().get(1);
assertEquals("http://example.com#parent", parent.getUrl());
assertNull(parent.getValue());
child1 = parent.getExtension().get(0);
assertEquals( "http://example.com#child", child1.getUrl());
assertEquals("value1", ((StringDt)child1.getValue()).getValueAsString());
child2 = parent.getExtension().get(1);
assertEquals( "http://example.com#child", child2.getUrl());
assertEquals("value2", ((StringDt)child2.getValue()).getValueAsString());
modExt = parsed.getUndeclaredModifierExtensions().get(0);
assertEquals("http://example.com/extensions#modext", modExt.getUrl());
assertEquals("1995-01-02", ((DateDt)modExt.getValue()).getValueAsString());
name = parsed.getName().get(0);
ext2 = name.getGiven().get(0).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext", ext2.getUrl());
assertEquals("given", ((StringDt)ext2.getValue()).getValueAsString());
given2ext = name.getGiven().get(1).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
assertNull(given2ext.getValue());
ExtensionDt given2ext2 = given2ext.getExtension().get(0);
assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
assertEquals("CHILD", ((StringDt)given2ext2.getValue()).getValue());
}
@Test @Test
public void testEncodeBundle() throws InterruptedException { public void testEncodeBundle() throws InterruptedException {
Bundle b = new Bundle(); Bundle b = new Bundle();
@ -1490,7 +1580,7 @@ public class XmlParserTest {
List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions();
ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); ExtensionDt undeclaredExtension = undeclaredExtensions.get(0);
assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl());
ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out)); ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out));
@ -1545,7 +1635,7 @@ public class XmlParserTest {
List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions(); List<ExtensionDt> undeclaredExtensions = obs.getContact().get(0).getName().getFamily().get(0).getUndeclaredExtensions();
ExtensionDt undeclaredExtension = undeclaredExtensions.get(0); ExtensionDt undeclaredExtension = undeclaredExtensions.get(0);
assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl().getValue()); assertEquals("http://hl7.org/fhir/Profile/iso-21090#qualifier", undeclaredExtension.getUrl());
fhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out)); fhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToWriter(obs, new OutputStreamWriter(System.out));

View File

@ -23,10 +23,12 @@ package ca.uhn.fhir.model.dstu2;
import java.io.InputStream; import java.io.InputStream;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IDatatype; import ca.uhn.fhir.model.api.IDatatype;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;

View File

@ -13,6 +13,7 @@ import net.sf.json.JSONSerializer;
import net.sf.json.JsonConfig; import net.sf.json.JsonConfig;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.hamcrest.Matchers;
import org.junit.Test; import org.junit.Test;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
@ -20,13 +21,16 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu2.resource.Binary; import ca.uhn.fhir.model.dstu2.resource.Binary;
import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription; import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription;
import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.dstu2.resource.QuestionnaireAnswers; import ca.uhn.fhir.model.dstu2.resource.QuestionnaireAnswers;
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.primitive.BooleanDt; import ca.uhn.fhir.model.primitive.BooleanDt;
import ca.uhn.fhir.model.primitive.CodeDt; import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.DateDt; import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt; import ca.uhn.fhir.model.primitive.StringDt;
@ -65,6 +69,120 @@ public class JsonParserTest {
//@formatter:on //@formatter:on
} }
@Test
public void testEncodeAndParseExtensions() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
ExtensionDt ext = new ExtensionDt();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
patient.addUndeclaredExtension(ext);
ExtensionDt parent = new ExtensionDt().setUrl("http://example.com#parent");
patient.addUndeclaredExtension(parent);
ExtensionDt child1 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value1"));
parent.addUndeclaredExtension(child1);
ExtensionDt child2 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value2"));
parent.addUndeclaredExtension(child2);
ExtensionDt modExt = new ExtensionDt();
modExt.setUrl("http://example.com/extensions#modext");
modExt.setValue(new DateDt("1995-01-02"));
modExt.setModifier(true);
patient.addUndeclaredExtension(modExt);
HumanNameDt name = patient.addName();
name.addFamily("Blah");
StringDt given = name.addGiven();
given.setValue("Joe");
ExtensionDt ext2 = new ExtensionDt().setUrl("http://examples.com#givenext").setValue(new StringDt("given"));
given.addUndeclaredExtension(ext2);
StringDt given2 = name.addGiven();
given2.setValue("Shmoe");
ExtensionDt given2ext = new ExtensionDt().setUrl("http://examples.com#givenext_parent");
given2.addUndeclaredExtension(given2ext);
given2ext.addUndeclaredExtension(new ExtensionDt().setUrl("http://examples.com#givenext_child").setValue(new StringDt("CHILD")));
String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
assertThat(enc, Matchers.stringContainsInOrder("{\"resourceType\":\"Patient\",",
"\"extension\":[{\"url\":\"http://example.com/extensions#someext\",\"valueDateTime\":\"2011-01-02T11:13:15\"}",
"{\"url\":\"http://example.com#parent\",\"extension\":[{\"url\":\"http://example.com#child\",\"valueString\":\"value1\"},{\"url\":\"http://example.com#child\",\"valueString\":\"value2\"}]}"
));
assertThat(enc, Matchers.stringContainsInOrder("\"modifierExtension\":[" +
"{" +
"\"url\":\"http://example.com/extensions#modext\"," +
"\"valueDate\":\"1995-01-02\"" +
"}" +
"],"));
assertThat(enc, containsString("\"_given\":[" +
"{" +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext\"," +
"\"valueString\":\"given\"" +
"}" +
"]" +
"}," +
"{" +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext_parent\"," +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext_child\"," +
"\"valueString\":\"CHILD\"" +
"}" +
"]" +
"}" +
"]" +
"}"));
/*
* Now parse this back
*/
Patient parsed =ourCtx.newJsonParser().parseResource(Patient.class, enc);
ext = parsed.getUndeclaredExtensions().get(0);
assertEquals("http://example.com/extensions#someext", ext.getUrl());
assertEquals("2011-01-02T11:13:15", ((DateTimeDt)ext.getValue()).getValueAsString());
parent = patient.getUndeclaredExtensions().get(1);
assertEquals("http://example.com#parent", parent.getUrl());
assertNull(parent.getValue());
child1 = parent.getExtension().get(0);
assertEquals( "http://example.com#child", child1.getUrl());
assertEquals("value1", ((StringDt)child1.getValue()).getValueAsString());
child2 = parent.getExtension().get(1);
assertEquals( "http://example.com#child", child2.getUrl());
assertEquals("value2", ((StringDt)child2.getValue()).getValueAsString());
modExt = parsed.getUndeclaredModifierExtensions().get(0);
assertEquals("http://example.com/extensions#modext", modExt.getUrl());
assertEquals("1995-01-02", ((DateDt)modExt.getValue()).getValueAsString());
name = parsed.getName().get(0);
ext2 = name.getGiven().get(0).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext", ext2.getUrl());
assertEquals("given", ((StringDt)ext2.getValue()).getValueAsString());
given2ext = name.getGiven().get(1).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
assertNull(given2ext.getValue());
ExtensionDt given2ext2 = given2ext.getExtension().get(0);
assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
assertEquals("CHILD", ((StringDt)given2ext2.getValue()).getValue());
}
/** /**
* #65 * #65
*/ */
@ -77,7 +195,7 @@ public class JsonParserTest {
String encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(parsed); String encoded = ourCtx.newJsonParser().setPrettyPrint(false).encodeResourceToString(parsed);
ourLog.info(encoded); ourLog.info(encoded);
assertThat(encoded, containsString("{\"linkId\":\"value123\",\"_linkId\":{\"http://123\":[{\"valueString\":\"HELLO\"}]}}")); assertThat(encoded, containsString("{\"linkId\":\"value123\",\"_linkId\":{\"extension\":[{\"url\":\"http://123\",\"valueString\":\"HELLO\"}]}}"));
} }
@ -244,102 +362,6 @@ public class JsonParserTest {
} }
@Test
public void testParseAndEncodeNewExtensionFormat() {
//@formatter:off
String resource = "{\n" +
" \"resourceType\" : \"Patient\",\n" +
" \"http://acme.org/fhir/ExtensionDefinition/trial-status\" : [{\n" +
" \"code\" : [{ \"valueCode\" : \"unsure\" }],\n" +
" \"date\" : [{ \"valueDate\" : \"2009-03-14\" }], \n" +
" \"registrar\" : [{ \"valueReference\" : {\n" +
" \"reference\" : \"Practitioner/example\"\n" +
" }\n" +
" }]\n" +
" }],\n" +
" \"modifier\" : { \n" +
" \"http://example.org/fhir/ExtensionDefinition/some-kind-of-modifier\" : [{\n" +
" \"valueBoolean\" : true\n" +
" }]\n" +
" }," +
" \"name\" : [{\n" +
" \"family\": [\n" +
" \"du\",\n" +
" \"Marché\"\n" +
" ],\n" +
" \"_family\": [\n" +
" {\n" +
" \"http://hl7.org/fhir/ExtensionDefinition/iso21090-EN-qualifier\": [\n" +
" {\n" +
" \"valueCode\": \"VV\"\n" +
" }\n" +
" ]\n" +
" },\n" +
" null\n" +
" ],\n" +
" \"given\": [\n" +
" \"Bénédicte\"\n" +
" ]\n" +
" }],\n" +
" \"gender\" : \"M\"\n" +
"}";
//@formatter:on
// ourLog.info(resource);
Patient parsed = ourCtx.newJsonParser().parseResource(Patient.class, resource);
// Modifier extension
assertEquals(1, parsed.getUndeclaredExtensionsByUrl("http://example.org/fhir/ExtensionDefinition/some-kind-of-modifier").size());
assertTrue( parsed.getUndeclaredExtensionsByUrl("http://example.org/fhir/ExtensionDefinition/some-kind-of-modifier").get(0).isModifier());
assertEquals(BooleanDt.class, parsed.getUndeclaredExtensionsByUrl("http://example.org/fhir/ExtensionDefinition/some-kind-of-modifier").get(0).getValueAsPrimitive().getClass());
assertEquals("true", parsed.getUndeclaredExtensionsByUrl("http://example.org/fhir/ExtensionDefinition/some-kind-of-modifier").get(0).getValueAsPrimitive().getValueAsString());
// Gender
assertEquals("M",parsed.getGender());
assertEquals(1, parsed.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/trial-status").size());
// Trial status
ExtensionDt ext = parsed.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/trial-status").get(0);
assertNull(ext.getValue());
assertEquals(1, ext.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/code").size());
assertEquals(CodeDt.class, ext.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/code").get(0).getValue().getClass());
assertEquals("unsure", ext.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/code").get(0).getValueAsPrimitive().getValueAsString());
assertEquals(1, ext.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/date").size());
assertEquals(DateDt.class, ext.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/date").get(0).getValue().getClass());
assertEquals("2009-03-14", ext.getUndeclaredExtensionsByUrl("http://acme.org/fhir/ExtensionDefinition/date").get(0).getValueAsPrimitive().getValueAsString());
// Name
assertEquals(1, parsed.getName().size());
assertEquals(2, parsed.getName().get(0).getFamily().size());
assertEquals("du Marché", parsed.getName().get(0).getFamilyAsSingleString());
assertEquals(1, parsed.getName().get(0).getGiven().size());
assertEquals("Bénédicte", parsed.getName().get(0).getGivenAsSingleString());
// Patient.name[0].family extensions
assertEquals(1, parsed.getNameFirstRep().getFamily().get(0).getUndeclaredExtensionsByUrl("http://hl7.org/fhir/ExtensionDefinition/iso21090-EN-qualifier").size());
assertEquals(CodeDt.class, parsed.getNameFirstRep().getFamily().get(0).getUndeclaredExtensionsByUrl("http://hl7.org/fhir/ExtensionDefinition/iso21090-EN-qualifier").get(0).getValueAsPrimitive().getClass());
assertEquals("VV", parsed.getNameFirstRep().getFamily().get(0).getUndeclaredExtensionsByUrl("http://hl7.org/fhir/ExtensionDefinition/iso21090-EN-qualifier").get(0).getValueAsPrimitive().getValueAsString());
/*
* Now re-encode
*/
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(parsed);
ourLog.info(encoded);
JSON expected = JSONSerializer.toJSON(resource.trim());
JSON actual = JSONSerializer.toJSON(encoded.trim());
String exp = expected.toString().replace("\\r\\n", "\\n"); // .replace("&sect;", "§");
String act = actual.toString().replace("\\r\\n", "\\n");
ourLog.info("Expected: {}", exp);
ourLog.info("Actual : {}", act);
assertEquals(exp, act);
}
@Test @Test
public void testParseAndEncodeBundleWithDeletedEntry() { public void testParseAndEncodeBundleWithDeletedEntry() {

View File

@ -1,7 +1,13 @@
package ca.uhn.fhir.parser; package ca.uhn.fhir.parser;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*; import static org.hamcrest.Matchers.emptyOrNullString;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.io.StringReader; import java.io.StringReader;
@ -13,8 +19,10 @@ import org.junit.Test;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum; import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.dstu2.composite.DurationDt; import ca.uhn.fhir.model.dstu2.composite.DurationDt;
import ca.uhn.fhir.model.dstu2.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu2.resource.AllergyIntolerance; import ca.uhn.fhir.model.dstu2.resource.AllergyIntolerance;
import ca.uhn.fhir.model.dstu2.resource.Binary; import ca.uhn.fhir.model.dstu2.resource.Binary;
import ca.uhn.fhir.model.dstu2.resource.Composition; import ca.uhn.fhir.model.dstu2.resource.Composition;
@ -22,7 +30,11 @@ import ca.uhn.fhir.model.dstu2.resource.Encounter;
import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription; import ca.uhn.fhir.model.dstu2.resource.MedicationPrescription;
import ca.uhn.fhir.model.dstu2.resource.Organization; import ca.uhn.fhir.model.dstu2.resource.Organization;
import ca.uhn.fhir.model.dstu2.resource.Patient; import ca.uhn.fhir.model.dstu2.resource.Patient;
import ca.uhn.fhir.model.dstu2.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.primitive.DateDt;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.InstantDt; import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
public class XmlParserTest { public class XmlParserTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserTest.class);
@ -89,7 +101,8 @@ public class XmlParserTest {
public void testParseAndEncodeBundleNewStyle() throws Exception { public void testParseAndEncodeBundleNewStyle() throws Exception {
String content = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/bundle-example.xml")); String content = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/bundle-example.xml"));
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = ourCtx.newXmlParser().parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, content); IParser newXmlParser = ourCtx.newXmlParser();
ca.uhn.fhir.model.dstu2.resource.Bundle parsed = newXmlParser.parseResource(ca.uhn.fhir.model.dstu2.resource.Bundle.class, content);
assertEquals("http://example.com/base/Bundle/example/_history/1", parsed.getId().getValue()); assertEquals("http://example.com/base/Bundle/example/_history/1", parsed.getId().getValue());
assertEquals("1", parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION)); assertEquals("1", parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION));
assertEquals(new InstantDt("2014-08-18T01:43:30Z"), parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED)); assertEquals(new InstantDt("2014-08-18T01:43:30Z"), parsed.getResourceMetadata().get(ResourceMetadataKeyEnum.UPDATED));
@ -275,4 +288,93 @@ public class XmlParserTest {
assertEquals(2, parsed.getContained().getContainedResources().size()); assertEquals(2, parsed.getContained().getContainedResources().size());
} }
@Test
public void testEncodeAndParseExtensions() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUseEnum.OFFICIAL).setSystem("urn:example").setValue("7000135");
ExtensionDt ext = new ExtensionDt();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeDt("2011-01-02T11:13:15"));
patient.addUndeclaredExtension(ext);
ExtensionDt parent = new ExtensionDt().setUrl("http://example.com#parent");
patient.addUndeclaredExtension(parent);
ExtensionDt child1 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value1"));
parent.addUndeclaredExtension(child1);
ExtensionDt child2 = new ExtensionDt().setUrl( "http://example.com#child").setValue( new StringDt("value2"));
parent.addUndeclaredExtension(child2);
ExtensionDt modExt = new ExtensionDt();
modExt.setUrl("http://example.com/extensions#modext");
modExt.setValue(new DateDt("1995-01-02"));
modExt.setModifier(true);
patient.addUndeclaredExtension(modExt);
HumanNameDt name = patient.addName();
name.addFamily("Blah");
StringDt given = name.addGiven();
given.setValue("Joe");
ExtensionDt ext2 = new ExtensionDt().setUrl("http://examples.com#givenext").setValue(new StringDt("given"));
given.addUndeclaredExtension(ext2);
StringDt given2 = name.addGiven();
given2.setValue("Shmoe");
ExtensionDt given2ext = new ExtensionDt().setUrl("http://examples.com#givenext_parent");
given2.addUndeclaredExtension(given2ext);
given2ext.addUndeclaredExtension(new ExtensionDt().setUrl("http://examples.com#givenext_child").setValue(new StringDt("CHILD")));
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
assertThat(enc, containsString("<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://example.com/extensions#someext\"><valueDateTime value=\"2011-01-02T11:13:15\"/></extension>"));
assertThat(enc, containsString("<modifierExtension url=\"http://example.com/extensions#modext\"><valueDate value=\"1995-01-02\"/></modifierExtension>"));
assertThat(
enc,
containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value2\"/></extension></extension>"));
assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
assertThat(enc, containsString("<given value=\"Shmoe\"><extension url=\"http://examples.com#givenext_parent\"><extension url=\"http://examples.com#givenext_child\"><valueString value=\"CHILD\"/></extension></extension></given>"));
/*
* Now parse this back
*/
Patient parsed =ourCtx.newXmlParser().parseResource(Patient.class, enc);
ext = parsed.getUndeclaredExtensions().get(0);
assertEquals("http://example.com/extensions#someext", ext.getUrl());
assertEquals("2011-01-02T11:13:15", ((DateTimeDt)ext.getValue()).getValueAsString());
parent = patient.getUndeclaredExtensions().get(1);
assertEquals("http://example.com#parent", parent.getUrl());
assertNull(parent.getValue());
child1 = parent.getExtension().get(0);
assertEquals( "http://example.com#child", child1.getUrl());
assertEquals("value1", ((StringDt)child1.getValue()).getValueAsString());
child2 = parent.getExtension().get(1);
assertEquals( "http://example.com#child", child2.getUrl());
assertEquals("value2", ((StringDt)child2.getValue()).getValueAsString());
modExt = parsed.getUndeclaredModifierExtensions().get(0);
assertEquals("http://example.com/extensions#modext", modExt.getUrl());
assertEquals("1995-01-02", ((DateDt)modExt.getValue()).getValueAsString());
name = parsed.getName().get(0);
ext2 = name.getGiven().get(0).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext", ext2.getUrl());
assertEquals("given", ((StringDt)ext2.getValue()).getValueAsString());
given2ext = name.getGiven().get(1).getUndeclaredExtensions().get(0);
assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
assertNull(given2ext.getValue());
ExtensionDt given2ext2 = given2ext.getExtension().get(0);
assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
assertEquals("CHILD", ((StringDt)given2ext2.getValue()).getValue());
}
} }

View File

@ -475,21 +475,4 @@ public class IncludeTest {
} }
public static void main(String[] args) {
Organization org = new Organization();
org.setId("Organization/65546");
org.getNameElement().setValue("Contained Test Organization");
Patient patient = new Patient();
patient.setId("Patient/1333");
patient.addIdentifier().setSystem("urn:mrns").setValue("253345");
patient.getManagingOrganization().setResource(patient);
System.out.println(new FhirContext().newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
patient.getManagingOrganization().getReference();
}
} }

View File

@ -27,7 +27,7 @@ import ca.uhn.fhir.model.primitive.DateTimeDt;
public class ResourceValidatorTest { public class ResourceValidatorTest {
private static FhirContext ourCtx = new FhirContext(); private static FhirContext ourCtx = FhirContext.forDstu2();
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidatorTest.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidatorTest.class);
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")

View File

@ -26,12 +26,15 @@ import java.util.ArrayList;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.conf.ServerConformanceProvider; import org.hl7.fhir.instance.conf.ServerConformanceProvider;
import org.hl7.fhir.instance.conf.ServerProfileProvider; import org.hl7.fhir.instance.conf.ServerProfileProvider;
import org.hl7.fhir.instance.model.Extension;
import org.hl7.fhir.instance.model.Profile; import org.hl7.fhir.instance.model.Profile;
import org.hl7.fhir.instance.model.Reference; import org.hl7.fhir.instance.model.Reference;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.IFhirVersion; import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.composite.BaseContainedDt; import ca.uhn.fhir.model.base.composite.BaseContainedDt;

View File

@ -37,11 +37,13 @@ import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
import org.hl7.fhir.instance.model.annotations.DatatypeDef; import org.hl7.fhir.instance.model.annotations.DatatypeDef;
import org.hl7.fhir.instance.model.api.IBackboneElement; import org.hl7.fhir.instance.model.api.IBackboneElement;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
/** /**
* Base definition for all elements that are defined inside a resource - but not those in a data type. * Base definition for all elements that are defined inside a resource - but not those in a data type.
*/ */
@DatatypeDef(name="BackboneElement") @DatatypeDef(name="BackboneElement")
public abstract class BackboneElement extends Element implements IBackboneElement { public abstract class BackboneElement extends Element implements IBackboneElement, IBaseHasExtensions, IBaseHasModifierExtensions {
/** /**
* May be used to represent additional information that is not part of the basic definition of the element, 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 set of 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. * May be used to represent additional information that is not part of the basic definition of the element, 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 set of 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.

View File

@ -38,11 +38,13 @@ import org.hl7.fhir.instance.model.annotations.SearchParamDefinition;
import org.hl7.fhir.instance.model.annotations.Block; import org.hl7.fhir.instance.model.annotations.Block;
import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
/** /**
* A resource that includes narrative, extensions, and contained resources. * A resource that includes narrative, extensions, and contained resources.
*/ */
@ResourceDef(name="DomainResource", profile="http://hl7.org/fhir/Profile/DomainResource") @ResourceDef(name="DomainResource", profile="http://hl7.org/fhir/Profile/DomainResource")
public abstract class DomainResource extends Resource { public abstract class DomainResource extends Resource implements IBaseHasExtensions, IBaseHasModifierExtensions {
/** /**
* 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 "clinically safe" for a human to just read the narrative. Resource definitions may define what content should be represented in the narrative to ensure clinical safety. * 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 "clinically safe" for a human to just read the narrative. Resource definitions may define what content should be represented in the narrative to ensure clinical safety.

View File

@ -37,10 +37,11 @@ import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
import org.hl7.fhir.instance.model.annotations.DatatypeDef; import org.hl7.fhir.instance.model.annotations.DatatypeDef;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
/** /**
* Base definition for all elements in a resource. * Base definition for all elements in a resource.
*/ */
public abstract class Element extends Base { public abstract class Element extends Base implements IBaseHasExtensions {
/** /**
* unique id for the element within a resource (for internal references). * unique id for the element within a resource (for internal references).

View File

@ -1,5 +1,7 @@
package org.hl7.fhir.instance.model; package org.hl7.fhir.instance.model;
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
/* /*
Copyright (c) 2011+, HL7, Inc Copyright (c) 2011+, HL7, Inc
@ -33,7 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
/** /**
* Helper class to help manage generic enumerated types * Helper class to help manage generic enumerated types
*/ */
public interface EnumFactory<T extends Enum<?>> { public interface EnumFactory<T extends Enum<?>> extends IBaseEnumFactory<T> {
/** /**
* Read an enumeration value from the string that represents it on the XML or JSON * Read an enumeration value from the string that represents it on the XML or JSON

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.instance.model; package org.hl7.fhir.instance.model;
import org.hl7.fhir.instance.model.annotations.DatatypeDef; import org.hl7.fhir.instance.model.annotations.DatatypeDef;
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
/* /*
Copyright (c) 2011+, HL7, Inc Copyright (c) 2011+, HL7, Inc
@ -50,6 +51,16 @@ public class Enumeration<T extends Enum<?>> extends PrimitiveType<T> {
myEnumFactory = theEnumFactory; myEnumFactory = theEnumFactory;
} }
/**
* Constructor
*/
public Enumeration(IBaseEnumFactory<T> theEnumFactory) {
if (theEnumFactory == null)
throw new IllegalArgumentException("An enumeration factory must be provided");
myEnumFactory = (EnumFactory<T>) theEnumFactory;
}
/** /**
* Constructor * Constructor
*/ */

View File

@ -36,12 +36,14 @@ import java.util.List;
import org.hl7.fhir.instance.model.annotations.Child; import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.DatatypeDef; import org.hl7.fhir.instance.model.annotations.DatatypeDef;
import org.hl7.fhir.instance.model.annotations.Description; import org.hl7.fhir.instance.model.annotations.Description;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
/** /**
* Optional Extensions Element - found in all resources. * Optional Extensions Element - found in all resources.
*/ */
@DatatypeDef(name="Extension") @DatatypeDef(name="Extension")
public class Extension extends Element implements IBaseExtension<Extension> { public class Extension extends Element implements IBaseExtension<Extension>, IBaseHasExtensions {
/** /**
* Source of the definition for the extension code - a logical name or a URL. * Source of the definition for the extension code - a logical name or a URL.
@ -175,6 +177,11 @@ public class Extension extends Element implements IBaseExtension<Extension> {
; ;
} }
@Override
public Extension setValue(IBaseDatatype theValue) {
return setValue((Type)theValue);
}
} }

View File

@ -146,7 +146,7 @@ public class Identifier extends Type implements ICompositeType {
/** /**
* The purpose of this identifier. * The purpose of this identifier.
*/ */
@Child(name="use", type={CodeType.class}, order=0, min=0, max=1) @Child(name="use", type={CodeType.class}, order=0, min=0, max=1, enumFactory=IdentifierUseEnumFactory.class)
@Description(shortDefinition="usual | official | temp | secondary (If known)", formalDefinition="The purpose of this identifier." ) @Description(shortDefinition="usual | official | temp | secondary (If known)", formalDefinition="The purpose of this identifier." )
protected Enumeration<IdentifierUse> use; protected Enumeration<IdentifierUse> use;

View File

@ -2,8 +2,9 @@ package org.hl7.fhir.instance.model;
import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T> { public abstract class PrimitiveType<T> extends Type implements IPrimitiveType<T>, IBaseHasExtensions {
private static final long serialVersionUID = 3L; private static final long serialVersionUID = 3L;

View File

@ -34,7 +34,9 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import org.hl7.fhir.instance.model.Enumeration;
import org.hl7.fhir.instance.model.IBase; import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.api.IBaseEnumFactory;
/** /**
* Field annotation for fields within resource and datatype definitions, indicating * Field annotation for fields within resource and datatype definitions, indicating
@ -96,6 +98,12 @@ public @interface Child {
*/ */
Class<? extends IBase>[] type() default {}; Class<? extends IBase>[] type() default {};
/**
* For children which accept an {@link Enumeration} as the type, this
* field indicates the type to use for the enum factory
*/
Class<? extends IBaseEnumFactory<?>> enumFactory() default NoEnumFactory.class;
// Not implemented // Not implemented
// /** // /**
// * This value is used when extending a built-in model class and defining a // * This value is used when extending a built-in model class and defining a
@ -106,4 +114,22 @@ public @interface Child {
// */ // */
// String replaces() default ""; // String replaces() default "";
public static class NoEnumFactory implements IBaseEnumFactory<Enum<?>> {
private NoEnumFactory() {
// non instantiable
}
@Override
public Enum<?> fromCode(String theCodeString) throws IllegalArgumentException {
return null;
}
@Override
public String toCode(Enum<?> theCode) {
return null;
}
}
} }

View File

@ -1,19 +1,24 @@
package ca.uhn.fhir.model; package ca.uhn.fhir.model;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import org.hl7.fhir.instance.model.Address; import org.hl7.fhir.instance.model.Address;
import org.hl7.fhir.instance.model.BackboneElement;
import org.hl7.fhir.instance.model.Base; import org.hl7.fhir.instance.model.Base;
import org.hl7.fhir.instance.model.BooleanType; import org.hl7.fhir.instance.model.BooleanType;
import org.hl7.fhir.instance.model.Bundle; import org.hl7.fhir.instance.model.Bundle;
import org.hl7.fhir.instance.model.Coding; import org.hl7.fhir.instance.model.Coding;
import org.hl7.fhir.instance.model.DecimalType; import org.hl7.fhir.instance.model.DecimalType;
import org.hl7.fhir.instance.model.DomainResource;
import org.hl7.fhir.instance.model.Element;
import org.hl7.fhir.instance.model.Extension; import org.hl7.fhir.instance.model.Extension;
import org.hl7.fhir.instance.model.IBase; import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.ICompositeType; import org.hl7.fhir.instance.model.ICompositeType;
import org.hl7.fhir.instance.model.IPrimitiveType; import org.hl7.fhir.instance.model.IPrimitiveType;
import org.hl7.fhir.instance.model.IdType; import org.hl7.fhir.instance.model.IdType;
import org.hl7.fhir.instance.model.Identifier;
import org.hl7.fhir.instance.model.IntegerType; import org.hl7.fhir.instance.model.IntegerType;
import org.hl7.fhir.instance.model.Meta; import org.hl7.fhir.instance.model.Meta;
import org.hl7.fhir.instance.model.Narrative; import org.hl7.fhir.instance.model.Narrative;
@ -22,7 +27,9 @@ import org.hl7.fhir.instance.model.Reference;
import org.hl7.fhir.instance.model.Resource; import org.hl7.fhir.instance.model.Resource;
import org.hl7.fhir.instance.model.Timing; import org.hl7.fhir.instance.model.Timing;
import org.hl7.fhir.instance.model.Type; import org.hl7.fhir.instance.model.Type;
import org.hl7.fhir.instance.model.Identifier.IdentifierUseEnumFactory;
import org.hl7.fhir.instance.model.annotations.Block; import org.hl7.fhir.instance.model.annotations.Block;
import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.api.IAnyResource; import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBackboneElement; import org.hl7.fhir.instance.model.api.IBackboneElement;
import org.hl7.fhir.instance.model.api.IBaseBooleanDatatype; import org.hl7.fhir.instance.model.api.IBaseBooleanDatatype;
@ -30,6 +37,8 @@ import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseDatatype; import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseDecimalDatatype; import org.hl7.fhir.instance.model.api.IBaseDecimalDatatype;
import org.hl7.fhir.instance.model.api.IBaseExtension; import org.hl7.fhir.instance.model.api.IBaseExtension;
import org.hl7.fhir.instance.model.api.IBaseHasExtensions;
import org.hl7.fhir.instance.model.api.IBaseHasModifierExtensions;
import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype; import org.hl7.fhir.instance.model.api.IBaseIntegerDatatype;
import org.hl7.fhir.instance.model.api.ICoding; import org.hl7.fhir.instance.model.api.ICoding;
import org.hl7.fhir.instance.model.api.IDatatypeElement; import org.hl7.fhir.instance.model.api.IDatatypeElement;
@ -56,6 +65,9 @@ public class ModelInheritanceTest {
* *
* ElementDefinition * ElementDefinition
* * Backbone elements (eg .ElementDefinitionSlicingComponent) do not extend BackboneElement or have a @Block annotation for some reason * * Backbone elements (eg .ElementDefinitionSlicingComponent) do not extend BackboneElement or have a @Block annotation for some reason
*
* Extension
* * Should URL not be StringType since it can't take extensions?
* </pre> * </pre>
*/ */
@ -77,12 +89,19 @@ public class ModelInheritanceTest {
assertTrue(IBase.class.isAssignableFrom(Base.class)); assertTrue(IBase.class.isAssignableFrom(Base.class));
} }
public void testIdentifierUse() throws Exception {
Child child = Identifier.class.getField("use").getAnnotation(Child.class);
assertEquals(IdentifierUseEnumFactory.class, child.enumFactory());
}
/** /**
* Should be "implements IBaseExtension<Extension>" * Should be "implements IBaseExtension<Extension>"
*/ */
@Test @Test
public void testExtension() { public void testExtension() {
assertTrue(IBaseExtension.class.isAssignableFrom(Extension.class)); assertTrue(IBaseExtension.class.isAssignableFrom(Extension.class));
assertTrue(IBaseHasExtensions.class.isAssignableFrom(Extension.class));
} }
@Test @Test
@ -108,6 +127,7 @@ public class ModelInheritanceTest {
@Test @Test
public void testPrimitiveType() { public void testPrimitiveType() {
assertTrue(IPrimitiveType.class.isAssignableFrom(PrimitiveType.class)); assertTrue(IPrimitiveType.class.isAssignableFrom(PrimitiveType.class));
assertTrue(IBaseHasExtensions.class.isAssignableFrom(PrimitiveType.class));
} }
@Test @Test
@ -136,7 +156,20 @@ public class ModelInheritanceTest {
@Test @Test
public void testBackboneElement() { public void testBackboneElement() {
assertTrue(IBackboneElement.class.isAssignableFrom(IBackboneElement.class)); assertTrue(IBackboneElement.class.isAssignableFrom(BackboneElement.class));
assertTrue(IBaseHasExtensions.class.isAssignableFrom(BackboneElement.class));
assertTrue(IBaseHasModifierExtensions.class.isAssignableFrom(BackboneElement.class));
}
@Test
public void testElement() {
assertTrue(IBaseHasExtensions.class.isAssignableFrom(Element.class));
}
@Test
public void testDomainResource() {
assertTrue(IBaseHasExtensions.class.isAssignableFrom(DomainResource.class));
assertTrue(IBaseHasModifierExtensions.class.isAssignableFrom(DomainResource.class));
} }
@Test @Test

View File

@ -1,7 +1,16 @@
package ca.uhn.fhir.parser; package ca.uhn.fhir.parser;
import static org.hamcrest.Matchers.*; import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.*; import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.stringContainsInOrder;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter; import java.io.OutputStreamWriter;
@ -25,15 +34,16 @@ import org.hl7.fhir.instance.model.Bundle;
import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent; import org.hl7.fhir.instance.model.Bundle.BundleEntryComponent;
import org.hl7.fhir.instance.model.Conformance; import org.hl7.fhir.instance.model.Conformance;
import org.hl7.fhir.instance.model.DateTimeType; import org.hl7.fhir.instance.model.DateTimeType;
import org.hl7.fhir.instance.model.DateType;
import org.hl7.fhir.instance.model.DecimalType; import org.hl7.fhir.instance.model.DecimalType;
import org.hl7.fhir.instance.model.DiagnosticReport; import org.hl7.fhir.instance.model.DiagnosticReport;
import org.hl7.fhir.instance.model.Extension; import org.hl7.fhir.instance.model.Extension;
import org.hl7.fhir.instance.model.HumanName; import org.hl7.fhir.instance.model.HumanName;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.IPrimitiveType; import org.hl7.fhir.instance.model.IPrimitiveType;
import org.hl7.fhir.instance.model.Identifier.IdentifierUse;
import org.hl7.fhir.instance.model.InstantType; import org.hl7.fhir.instance.model.InstantType;
import org.hl7.fhir.instance.model.List_; import org.hl7.fhir.instance.model.List_;
import org.hl7.fhir.instance.model.Identifier.IdentifierUse;
import org.hl7.fhir.instance.model.Narrative.NarrativeStatus; import org.hl7.fhir.instance.model.Narrative.NarrativeStatus;
import org.hl7.fhir.instance.model.Observation; import org.hl7.fhir.instance.model.Observation;
import org.hl7.fhir.instance.model.Organization; import org.hl7.fhir.instance.model.Organization;
@ -83,6 +93,119 @@ public class JsonParserTest {
} }
@Test
public void testEncodeAndParseExtensions() throws Exception {
Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
Extension ext = new Extension();
ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
patient.getExtension().add(ext);
Extension parent = new Extension().setUrl("http://example.com#parent");
patient.getExtension().add(parent);
Extension child1 = new Extension().setUrl( "http://example.com#child").setValue( new StringType("value1"));
parent.getExtension().add(child1);
Extension child2 = new Extension().setUrl( "http://example.com#child").setValue( new StringType("value2"));
parent.getExtension().add(child2);
Extension modExt = new Extension();
modExt.setUrl("http://example.com/extensions#modext");
modExt.setValue(new DateType("1995-01-02"));
patient.getModifierExtension().add(modExt);
HumanName name = patient.addName();
name.addFamily("Blah");
StringType given = name.addGivenElement();
given.setValue("Joe");
Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given"));
given.getExtension().add(ext2);
StringType given2 = name.addGivenElement();
given2.setValue("Shmoe");
Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent");
given2.getExtension().add(given2ext);
given2ext.addExtension().setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD"));
String output = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output);
String enc = ourCtx.newJsonParser().encodeResourceToString(patient);
assertThat(enc, org.hamcrest.Matchers.stringContainsInOrder("{\"resourceType\":\"Patient\",",
"\"extension\":[{\"url\":\"http://example.com/extensions#someext\",\"valueDateTime\":\"2011-01-02T11:13:15\"}",
"{\"url\":\"http://example.com#parent\",\"extension\":[{\"url\":\"http://example.com#child\",\"valueString\":\"value1\"},{\"url\":\"http://example.com#child\",\"valueString\":\"value2\"}]}"
));
assertThat(enc, org.hamcrest.Matchers.stringContainsInOrder("\"modifierExtension\":[" +
"{" +
"\"url\":\"http://example.com/extensions#modext\"," +
"\"valueDate\":\"1995-01-02\"" +
"}" +
"],"));
assertThat(enc, containsString("\"_given\":[" +
"{" +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext\"," +
"\"valueString\":\"given\"" +
"}" +
"]" +
"}," +
"{" +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext_parent\"," +
"\"extension\":[" +
"{" +
"\"url\":\"http://examples.com#givenext_child\"," +
"\"valueString\":\"CHILD\"" +
"}" +
"]" +
"}" +
"]" +
"}"));
/*
* Now parse this back
*/
Patient parsed =ourCtx.newJsonParser().parseResource(Patient.class, enc);
ext = parsed.getExtension().get(0);
assertEquals("http://example.com/extensions#someext", ext.getUrl());
assertEquals("2011-01-02T11:13:15", ((DateTimeType)ext.getValue()).getValueAsString());
parent = patient.getExtension().get(1);
assertEquals("http://example.com#parent", parent.getUrl());
assertNull(parent.getValue());
child1 = parent.getExtension().get(0);
assertEquals( "http://example.com#child", child1.getUrl());
assertEquals("value1", ((StringType)child1.getValue()).getValueAsString());
child2 = parent.getExtension().get(1);
assertEquals( "http://example.com#child", child2.getUrl());
assertEquals("value2", ((StringType)child2.getValue()).getValueAsString());
modExt = parsed.getModifierExtension().get(0);
assertEquals("http://example.com/extensions#modext", modExt.getUrl());
assertEquals("1995-01-02", ((DateType)modExt.getValue()).getValueAsString());
name = parsed.getName().get(0);
ext2 = name.getGiven().get(0).getExtension().get(0);
assertEquals("http://examples.com#givenext", ext2.getUrl());
assertEquals("given", ((StringType)ext2.getValue()).getValueAsString());
given2ext = name.getGiven().get(1).getExtension().get(0);
assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
assertNull(given2ext.getValue());
Extension given2ext2 = given2ext.getExtension().get(0);
assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
assertEquals("CHILD", ((StringType)given2ext2.getValue()).getValue());
}
@Test @Test
public void testEncodeNonContained() { public void testEncodeNonContained() {
Organization org = new Organization(); Organization org = new Organization();
@ -740,6 +863,7 @@ public class JsonParserTest {
enc, enc,
containsString("<extension><extension><url value=\"http://example.com#child\"/><valueString value=\"value1\"/></extension><extension><url value=\"http://example.com#child\"/><valueString value=\"value1\"/></extension><url value=\"http://example.com#parent\"/></extension>")); containsString("<extension><extension><url value=\"http://example.com#child\"/><valueString value=\"value1\"/></extension><extension><url value=\"http://example.com#child\"/><valueString value=\"value1\"/></extension><url value=\"http://example.com#parent\"/></extension>"));
assertThat(enc, containsString("<given value=\"Joe\"><extension><url value=\"http://examples.com#givenext\"/><valueString value=\"given\"/></extension></given>")); assertThat(enc, containsString("<given value=\"Joe\"><extension><url value=\"http://examples.com#givenext\"/><valueString value=\"given\"/></extension></given>"));
assertThat(enc, containsString("<given value=\"Shmoe\"><extension><extension><url value=\"http://examples.com#givenext\"/><valueString value=\"given\"/></extension><url value=\"http://examples.com#givenext_child\"/></extension></given>"));
} }

View File

@ -37,6 +37,7 @@ import org.hl7.fhir.instance.model.Composition;
import org.hl7.fhir.instance.model.Conformance; import org.hl7.fhir.instance.model.Conformance;
import org.hl7.fhir.instance.model.Conformance.ConformanceRestResourceComponent; import org.hl7.fhir.instance.model.Conformance.ConformanceRestResourceComponent;
import org.hl7.fhir.instance.model.DateTimeType; import org.hl7.fhir.instance.model.DateTimeType;
import org.hl7.fhir.instance.model.DateType;
import org.hl7.fhir.instance.model.DecimalType; import org.hl7.fhir.instance.model.DecimalType;
import org.hl7.fhir.instance.model.DiagnosticReport; import org.hl7.fhir.instance.model.DiagnosticReport;
import org.hl7.fhir.instance.model.DocumentManifest; import org.hl7.fhir.instance.model.DocumentManifest;
@ -876,7 +877,7 @@ public class XmlParserTest {
} }
@Test @Test
public void testMoreExtensions() throws Exception { public void testEncodeAndParseExtensions() throws Exception {
Patient patient = new Patient(); Patient patient = new Patient();
patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135"); patient.addIdentifier().setUse(IdentifierUse.OFFICIAL).setSystem("urn:example").setValue("7000135");
@ -884,14 +885,22 @@ public class XmlParserTest {
Extension ext = new Extension(); Extension ext = new Extension();
ext.setUrl("http://example.com/extensions#someext"); ext.setUrl("http://example.com/extensions#someext");
ext.setValue(new DateTimeType("2011-01-02T11:13:15")); ext.setValue(new DateTimeType("2011-01-02T11:13:15"));
// Add the extension to the resource
patient.getExtension().add(ext); patient.getExtension().add(ext);
// END SNIPPET: resourceExtension
// START SNIPPET: resourceStringExtension Extension parent = new Extension().setUrl("http://example.com#parent");
patient.getExtension().add(parent);
Extension child1 = new Extension().setUrl( "http://example.com#child").setValue( new StringType("value1"));
parent.getExtension().add(child1);
Extension child2 = new Extension().setUrl( "http://example.com#child").setValue( new StringType("value2"));
parent.getExtension().add(child2);
Extension modExt = new Extension();
modExt.setUrl("http://example.com/extensions#modext");
modExt.setValue(new DateType("1995-01-02"));
patient.getModifierExtension().add(modExt);
HumanName name = patient.addName(); HumanName name = patient.addName();
name.addFamily("Shmoe"); name.addFamily("Blah");
StringType given = name.addGivenElement(); StringType given = name.addGivenElement();
given.setValue("Joe"); given.setValue("Joe");
Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given")); Extension ext2 = new Extension().setUrl("http://examples.com#givenext").setValue(new StringType("given"));
@ -902,28 +911,55 @@ public class XmlParserTest {
Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent"); Extension given2ext = new Extension().setUrl("http://examples.com#givenext_parent");
given2.getExtension().add(given2ext); given2.getExtension().add(given2ext);
given2ext.addExtension().setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD")); given2ext.addExtension().setUrl("http://examples.com#givenext_child").setValue(new StringType("CHILD"));
// END SNIPPET: resourceStringExtension
// START SNIPPET: subExtension
Extension parent = new Extension().setUrl("http://example.com#parent");
patient.getExtension().add(parent);
Extension child1 = new Extension().setUrl( "http://example.com#child").setValue( new StringType("value1"));
parent.getExtension().add(child1);
Extension child2 = new Extension().setUrl( "http://example.com#child").setValue( new StringType("value1"));
parent.getExtension().add(child2);
// END SNIPPET: subExtension
String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient); String output = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient);
ourLog.info(output); ourLog.info(output);
String enc = ourCtx.newXmlParser().encodeResourceToString(patient); String enc = ourCtx.newXmlParser().encodeResourceToString(patient);
assertThat(enc, containsString("<Patient xmlns=\"http://hl7.org/fhir\"><extension><url value=\"http://example.com/extensions#someext\"/><valueDateTime value=\"2011-01-02T11:13:15\"/></extension>")); assertThat(enc, containsString("<Patient xmlns=\"http://hl7.org/fhir\"><extension url=\"http://example.com/extensions#someext\"><valueDateTime value=\"2011-01-02T11:13:15\"/></extension>"));
assertThat(enc, containsString("<modifierExtension url=\"http://example.com/extensions#modext\"><valueDate value=\"1995-01-02\"/></modifierExtension>"));
assertThat( assertThat(
enc, enc,
containsString("<extension><extension><url value=\"http://example.com#child\"/><valueString value=\"value1\"/></extension><extension><url value=\"http://example.com#child\"/><valueString value=\"value1\"/></extension><url value=\"http://example.com#parent\"/></extension>")); containsString("<extension url=\"http://example.com#parent\"><extension url=\"http://example.com#child\"><valueString value=\"value1\"/></extension><extension url=\"http://example.com#child\"><valueString value=\"value2\"/></extension></extension>"));
assertThat(enc, containsString("<given value=\"Joe\"><extension><url value=\"http://examples.com#givenext\"/><valueString value=\"given\"/></extension></given>")); assertThat(enc, containsString("<given value=\"Joe\"><extension url=\"http://examples.com#givenext\"><valueString value=\"given\"/></extension></given>"));
assertThat(enc, containsString("<given value=\"Shmoe\"><extension url=\"http://examples.com#givenext_parent\"><extension url=\"http://examples.com#givenext_child\"><valueString value=\"CHILD\"/></extension></extension></given>"));
/*
* Now parse this back
*/
Patient parsed =ourCtx.newXmlParser().parseResource(Patient.class, enc);
ext = parsed.getExtension().get(0);
assertEquals("http://example.com/extensions#someext", ext.getUrl());
assertEquals("2011-01-02T11:13:15", ((DateTimeType)ext.getValue()).getValueAsString());
parent = patient.getExtension().get(1);
assertEquals("http://example.com#parent", parent.getUrl());
assertNull(parent.getValue());
child1 = parent.getExtension().get(0);
assertEquals( "http://example.com#child", child1.getUrl());
assertEquals("value1", ((StringType)child1.getValue()).getValueAsString());
child2 = parent.getExtension().get(1);
assertEquals( "http://example.com#child", child2.getUrl());
assertEquals("value2", ((StringType)child2.getValue()).getValueAsString());
modExt = parsed.getModifierExtension().get(0);
assertEquals("http://example.com/extensions#modext", modExt.getUrl());
assertEquals("1995-01-02", ((DateType)modExt.getValue()).getValueAsString());
name = parsed.getName().get(0);
ext2 = name.getGiven().get(0).getExtension().get(0);
assertEquals("http://examples.com#givenext", ext2.getUrl());
assertEquals("given", ((StringType)ext2.getValue()).getValueAsString());
given2ext = name.getGiven().get(1).getExtension().get(0);
assertEquals("http://examples.com#givenext_parent", given2ext.getUrl());
assertNull(given2ext.getValue());
Extension given2ext2 = given2ext.getExtension().get(0);
assertEquals("http://examples.com#givenext_child", given2ext2.getUrl());
assertEquals("CHILD", ((StringType)given2ext2.getValue()).getValue());
} }
@Test @Test

View File

@ -24,6 +24,7 @@ import java.io.InputStream;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
@ -107,5 +108,11 @@ public class FhirDev implements IFhirVersion {
} }
@Override
public IBaseExtension<?> newExtension() {
return null;
}
} }

View File

@ -35,6 +35,7 @@ import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.text.WordUtils;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition; import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
@ -379,6 +380,11 @@ public class FhirDstu1 implements IFhirVersion {
return ContainedDt.class; return ContainedDt.class;
} }
@Override
public IBaseExtension<?> newExtension() {
return null;
}
} }

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.model.dstu2;
import java.io.InputStream; import java.io.InputStream;
import org.hl7.fhir.instance.model.IBaseResource; import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.api.IBaseExtension;
import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.FhirVersionEnum;
@ -92,4 +93,9 @@ public class FhirDstu2 implements IFhirVersion {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
@Override
public IBaseExtension<?> newExtension() {
return null;
}
} }

View File

@ -141,6 +141,29 @@
</subsection> </subsection>
<subsection name="Configure the Server's Identity/Web Address">
<p>
The server will return data in a number of places that includes the
complete "identity" of a resource. Identity in this case refers to the
web address that a user can use to access the resource.
</p>
<p>
For instance, if your server is hosted at <code>http://foo.com/fhir</code>
and your resource provider returns a Patient resource with the ID "123",
the server should translate that ID to "http://foo.com/fhir/Patient/123".
</p>
<p>
The server will attempt to determine what the base URL should be based on
what the request it receives looks like, but if it is not getting
the right address you may wish to hardcode the base URL, as shown
in the following example:
</p>
<macro name="snippet">
<param name="id" value="addressStrategy" />
<param name="file" value="examples/src/main/java/example/ExampleProviders.java" />
</macro>
</subsection>
<subsection name="Deploy"> <subsection name="Deploy">
<p> <p>