Added preliminary support for DSTU2-style security labels.

This commit is contained in:
mochaholic 2015-02-19 18:14:02 -07:00
parent a5be8a10f4
commit 31d4dcdb90
5 changed files with 206 additions and 17 deletions

View File

@ -28,6 +28,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.text.WordUtils;
import org.hl7.fhir.instance.model.IBase;
@ -131,6 +132,23 @@ public class FhirContext {
return getLocalizer().getMessage(FhirContext.class, "unknownResourceName", theResourceName, theVersion);
}
public Class<? extends BaseCodingDt> getCodingDtImplementation() {
FhirVersionEnum myVersionEnum = myVersion.getVersion();
try {
if (myVersionEnum.isEquivalentTo(FhirVersionEnum.DSTU2)) {
return (Class<? extends BaseCodingDt>) Class.forName("ca.uhn.fhir.model.dstu2.composite.CodingDt");
} else if (myVersionEnum.isEquivalentTo(FhirVersionEnum.DSTU1)) {
return (Class<? extends BaseCodingDt>) Class.forName("ca.uhn.fhir.model.dstu.composite.CodingDt");
} else {
throw new IllegalStateException("No implementation found for BaseCodingDt in this FHIR Version." + myVersionEnum.toString());
}
} catch (ClassNotFoundException e) {
throw new IllegalStateException("No implementation found for BaseCodingDt.", e);
}
}
/**
* Returns the scanned runtime model for the given type. This is an advanced feature which is generally only needed
* for extending the core library.

View File

@ -28,6 +28,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import org.apache.commons.lang3.StringUtils;
import ca.uhn.fhir.model.primitive.DecimalDt;
@ -62,6 +63,36 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
*/
public abstract class ResourceMetadataKeyEnum<T> {
public static final ResourceMetadataKeyEnum<List<BaseCodingDt>> SECURITY_LABELS = new ResourceMetadataKeyEnum<List<BaseCodingDt>>("SECURITY_LABELS") {
@Override
public List<BaseCodingDt> get(IResource resource) {
Object obj = resource.getResourceMetadata().get(SECURITY_LABELS);
if (obj == null) {
return null;
} else {
try {
List<BaseCodingDt> securityLabels = (List<BaseCodingDt>) obj;
if (securityLabels.isEmpty())
return null;
else
return securityLabels;
} catch (ClassCastException e) {
throw new InternalErrorException("Found an object of type '" + obj.getClass().getCanonicalName() + "' in resource metadata for key SECURITY_LABELS - Expected "
+ BaseCodingDt.class.getCanonicalName());
}
}
}
@Override
public void put(IResource iResource, List<BaseCodingDt> labels) {
iResource.getResourceMetadata().put(SECURITY_LABELS, labels);
}
};
/**
* If present and populated with a date/time (as an instance of {@link InstantDt}), this value is an indication that the resource is in the deleted state. This key is only used in a limited number
* of scenarios, such as POSTing transaction bundles to a server, or returning resource history.

View File

@ -47,6 +47,8 @@ import javax.json.stream.JsonGenerator;
import javax.json.stream.JsonGeneratorFactory;
import javax.json.stream.JsonParsingException;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.primitive.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.IBase;
@ -85,12 +87,6 @@ import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
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.IdDt;
import ca.uhn.fhir.model.primitive.IntegerDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.util.ElementUtil;
import ca.uhn.fhir.util.UrlUtil;
@ -652,7 +648,41 @@ public class JsonParser extends BaseParser implements IParser {
theEventWriter.writeStartObject("meta");
writeOptionalTagWithTextNode(theEventWriter, "versionId", resource.getId().getVersionIdPart());
writeOptionalTagWithTextNode(theEventWriter, "lastUpdated", ResourceMetadataKeyEnum.UPDATED.get(resource));
theEventWriter.writeEnd();
Object securityLabelRawObj = resource.getResourceMetadata().get(ResourceMetadataKeyEnum.SECURITY_LABELS);
if (securityLabelRawObj != null) {
List<BaseCodingDt> securityLabels = (List<BaseCodingDt>) securityLabelRawObj;
if (!securityLabels.isEmpty()) {
theEventWriter.writeStartArray("security");
for (BaseCodingDt securityLabel : securityLabels) {
theEventWriter.writeStartObject();
UriDt system = securityLabel.getSystemElement();
if (system != null && !system.isEmpty())
writeOptionalTagWithTextNode(theEventWriter, "system", system.getValueAsString());
CodeDt code = securityLabel.getCodeElement();
if (code != null && !code.isEmpty())
writeOptionalTagWithTextNode(theEventWriter, "code", code.getValueAsString());
StringDt display = securityLabel.getDisplayElement();
if (display != null && !display.isEmpty())
writeOptionalTagWithTextNode(theEventWriter, "display", display.getValueAsString());
/*todo: handle version
StringDt version = securityLabel.getVersion();
if (version != null && ! version.isEmpty())
writeOptionalTagWithTextNode(theEventWriter, "version", version.getValueAsString());
*/
theEventWriter.writeEnd(); //end the individual security label
}
theEventWriter.writeEnd(); //end security labels array
}
}
theEventWriter.writeEnd(); //end meta
}
}

View File

@ -30,13 +30,13 @@ import java.util.Map;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.IBaseResource;
import org.hl7.fhir.instance.model.ICompositeType;
import org.hl7.fhir.instance.model.IPrimitiveType;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseElement;
import org.hl7.fhir.instance.model.api.IReference;
@ -48,29 +48,24 @@ import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
import ca.uhn.fhir.context.RuntimeElemContainedResources;
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeNarrativeDefinition;
import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
import ca.uhn.fhir.model.api.BaseBundle;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.ICompositeElement;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IIdentifiableElement;
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.IResourceBlock;
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
@ -1641,6 +1636,75 @@ class ParserState<T> {
}
private class CodingSubElementState extends BaseState {
BaseCodingDt myCoding;
String thePartWeAreAt;
public CodingSubElementState(PreResourceState thePreResourceState, BaseCodingDt codingDt, String whichPartAreWeAt) {
super(thePreResourceState);
myCoding = codingDt;
thePartWeAreAt = whichPartAreWeAt;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("value".equals(theName)) {
if ("system".equals(thePartWeAreAt))
myCoding.setSystem(theValue);
else if ("code".equals(thePartWeAreAt))
myCoding.setCode(theValue);
else if ("display".equals(thePartWeAreAt))
myCoding.setDisplay(theValue);
else if ("version".equals(thePartWeAreAt)) {
/*
todo: handle version properly when BaseCodingDt is fixed to support version. For now, we just swallow version in order to avoid throwing a DataFormat exception.
myCoding.setVersion(theValue);
*/
} else
throw new DataFormatException("Unexpected element '" + theValue + "' found in 'security' element");
} else {
throw new DataFormatException("Unexpected attribute '" + theName + "' found in '" + thePartWeAreAt + "' element");
}
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new DataFormatException("Unexpected element '" + theLocalPart + "' found in 'system' element");
}
}
private class CodingElementState extends BaseState {
BaseCodingDt myCoding;
public CodingElementState(ParserState<T>.PreResourceState thePreResourceState, BaseCodingDt codingDt) {
super(thePreResourceState);
myCoding = codingDt;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
push(new CodingSubElementState(getPreResourceState(), myCoding, theLocalPart));
}
}
private class MetaElementState extends BaseState {
private ResourceMetadataMap myMap;
@ -1664,6 +1728,22 @@ class ParserState<T> {
InstantDt updated = new InstantDt();
push(new PrimitiveState(getPreResourceState(), updated));
myMap.put(ResourceMetadataKeyEnum.UPDATED, updated);
} else if (theLocalPart.equals("security")) {
List<BaseCodingDt> securityLabels = (List<BaseCodingDt>) myMap.get(ResourceMetadataKeyEnum.SECURITY_LABELS);
if (securityLabels == null) {
securityLabels = new ArrayList<BaseCodingDt>();
myMap.put(ResourceMetadataKeyEnum.SECURITY_LABELS, securityLabels);
}
BaseCodingDt securityLabel;
try {
securityLabel = myContext.getCodingDtImplementation().newInstance();
} catch (InstantiationException e) {
throw new DataFormatException("Error parsing element 'security' ", e);
} catch (IllegalAccessException e) {
throw new DataFormatException("Error parsing element 'security' ", e);
}
push(new CodingElementState(getPreResourceState(), securityLabel));
securityLabels.add(securityLabel);
} else {
throw new DataFormatException("Unexpected element '" + theLocalPart + "' found in 'meta' element");
}

View File

@ -44,6 +44,8 @@ import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.primitive.*;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.IBase;
import org.hl7.fhir.instance.model.IBaseResource;
@ -76,10 +78,6 @@ import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseNarrativeDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseBinary;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.util.NonPrettyPrintWriterWrapper;
@ -719,6 +717,38 @@ public class XmlParser extends BaseParser implements IParser {
if (updated != null) {
writeOptionalTagWithValue(theEventWriter, "lastUpdated", updated.getValueAsString());
}
Object securityLabelRawObj = resource.getResourceMetadata().get(ResourceMetadataKeyEnum.SECURITY_LABELS);
if (securityLabelRawObj != null) {
List<BaseCodingDt> securityLabels = (List<BaseCodingDt>) securityLabelRawObj;
if (!securityLabels.isEmpty()) {
for (BaseCodingDt securityLabel : securityLabels) {
theEventWriter.writeStartElement("security");
UriDt system = securityLabel.getSystemElement();
if (system != null && !system.isEmpty())
writeOptionalTagWithValue(theEventWriter, "system", system.getValueAsString());
CodeDt code = securityLabel.getCodeElement();
if (code != null && !code.isEmpty())
writeOptionalTagWithValue(theEventWriter, "code", code.getValueAsString());
StringDt display = securityLabel.getDisplayElement();
if (display != null && !display.isEmpty())
writeOptionalTagWithValue(theEventWriter, "display", display.getValueAsString());
/*todo: handle version
StringDt version = securityLabel.getVersion();
if (version != null && ! version.isEmpty())
writeOptionalTagWithValue(theEventWriter, "version", version.getValueAsString());
*/
theEventWriter.writeEndElement();
}
}
}
theEventWriter.writeEndElement();
}