2621 lines
82 KiB
Java
Raw Normal View History

2014-02-18 08:26:49 -05:00
package ca.uhn.fhir.parser;
/*
* #%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%
*/
2015-02-16 11:33:46 -05:00
import static org.apache.commons.lang3.StringUtils.*;
2014-02-22 15:33:02 -05:00
import java.util.ArrayList;
import java.util.HashMap;
2014-02-22 15:33:02 -05:00
import java.util.List;
import java.util.Map;
2014-02-21 21:06:11 -05:00
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
2014-02-27 11:57:50 -05:00
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
2014-12-10 22:02:31 -05:00
import org.hl7.fhir.instance.model.IBase;
2014-12-10 17:40:47 -05:00
import org.hl7.fhir.instance.model.IBaseResource;
2015-02-16 11:33:46 -05:00
import org.hl7.fhir.instance.model.ICompositeType;
2014-12-10 22:02:31 -05:00
import org.hl7.fhir.instance.model.IPrimitiveType;
2015-03-04 08:44:31 -05:00
import org.hl7.fhir.instance.model.api.IBaseBinary;
2015-02-16 11:33:46 -05:00
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;
2015-04-13 08:32:49 -04:00
import org.hl7.fhir.instance.model.api.IBaseXhtml;
2015-04-20 07:31:45 -04:00
import org.hl7.fhir.instance.model.api.IDomainResource;
2015-05-01 12:27:56 -07:00
import org.hl7.fhir.instance.model.api.IBaseReference;
2014-02-27 11:57:50 -05:00
2014-02-18 08:26:49 -05:00
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
2015-02-16 11:33:46 -05:00
import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IMutator;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
2014-02-18 08:26:49 -05:00
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.ConfigurationException;
2014-02-18 08:26:49 -05:00
import ca.uhn.fhir.context.FhirContext;
2014-12-01 08:13:32 -05:00
import ca.uhn.fhir.context.FhirVersionEnum;
2014-02-23 18:13:59 -05:00
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
2014-02-22 15:33:02 -05:00
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeNarrativeDefinition;
2015-04-13 08:32:49 -04:00
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition;
2014-02-20 12:13:05 -05:00
import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
2014-02-18 08:26:49 -05:00
import ca.uhn.fhir.context.RuntimeResourceDefinition;
2014-02-27 16:51:43 -05:00
import ca.uhn.fhir.model.api.BaseBundle;
2014-02-26 17:13:49 -05:00
import ca.uhn.fhir.model.api.Bundle;
2014-02-27 16:51:43 -05:00
import ca.uhn.fhir.model.api.BundleEntry;
2014-03-27 08:51:02 -04:00
import ca.uhn.fhir.model.api.ExtensionDt;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.model.api.ICompositeDatatype;
2014-02-22 15:33:02 -05:00
import ca.uhn.fhir.model.api.IElement;
2015-02-13 18:01:55 -05:00
import ca.uhn.fhir.model.api.IFhirVersion;
2014-07-04 09:27:36 -04:00
import ca.uhn.fhir.model.api.IIdentifiableElement;
2014-02-19 11:59:12 -05:00
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
2014-02-27 07:39:36 -05:00
import ca.uhn.fhir.model.api.IResource;
2014-02-26 17:13:49 -05:00
import ca.uhn.fhir.model.api.ISupportsUndeclaredExtensions;
2014-04-14 08:40:30 -04:00
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
2014-05-11 21:46:36 -04:00
import ca.uhn.fhir.model.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
2014-12-01 08:13:32 -05:00
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
import ca.uhn.fhir.model.primitive.IdDt;
2014-05-21 18:12:00 -04:00
import ca.uhn.fhir.model.primitive.InstantDt;
2014-12-01 08:13:32 -05:00
import ca.uhn.fhir.model.primitive.StringDt;
2014-02-24 11:46:08 -05:00
import ca.uhn.fhir.model.primitive.XhtmlDt;
2014-04-14 08:40:30 -04:00
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.util.FhirTerser;
import ca.uhn.fhir.util.IModelVisitor;
2014-02-18 08:26:49 -05:00
class ParserState<T> {
2014-02-18 08:26:49 -05:00
2014-02-21 21:06:11 -05:00
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class);
private FhirContext myContext;
private boolean myJsonMode;
2014-02-27 07:39:36 -05:00
private T myObject;
2014-02-21 21:06:11 -05:00
private BaseState myState;
2014-02-19 17:33:46 -05:00
2014-03-22 12:33:07 -04:00
private ParserState(FhirContext theContext, boolean theJsonMode) {
2014-02-21 21:06:11 -05:00
myContext = theContext;
2014-03-22 12:33:07 -04:00
myJsonMode = theJsonMode;
2014-02-21 21:06:11 -05:00
}
2014-02-19 17:33:46 -05:00
2014-02-27 16:51:43 -05:00
public void attributeValue(String theName, String theValue) throws DataFormatException {
myState.attributeValue(theName, theValue);
2014-02-19 17:33:46 -05:00
}
public void endingElement() throws DataFormatException {
myState.endingElement();
2014-02-21 21:06:11 -05:00
}
2014-02-19 11:59:12 -05:00
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theName) throws DataFormatException {
myState.enteringNewElement(theNamespaceURI, theName);
2014-02-21 21:06:11 -05:00
}
2014-02-18 08:26:49 -05:00
2014-03-10 18:17:30 -04:00
public void enteringNewElementExtension(StartElement theElem, String theUrlAttr, boolean theIsModifier) {
myState.enteringNewElementExtension(theElem, theUrlAttr, theIsModifier);
2014-02-22 15:33:02 -05:00
}
2014-03-22 12:33:07 -04:00
@SuppressWarnings("unchecked")
2014-02-27 07:39:36 -05:00
public T getObject() {
2014-03-22 12:33:07 -04:00
return (T) myState.getCurrentElement();
2014-02-19 11:59:12 -05:00
}
2014-02-21 21:06:11 -05:00
public boolean isComplete() {
return myObject != null;
2014-02-19 11:59:12 -05:00
}
public boolean isPreResource() {
return myState.isPreResource();
}
2015-02-16 11:33:46 -05:00
private Object newContainedDt(IResource theTarget) {
2015-02-16 11:33:46 -05:00
Object newChildInstance;
try {
newChildInstance = theTarget.getStructureFhirVersionEnum().getVersionImplementation().getContainedType().newInstance();
} catch (InstantiationException e) {
throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e);
}
return newChildInstance;
}
2015-02-16 11:33:46 -05:00
private IBase newResourceReferenceDt(IBaseResource theTarget) {
2015-02-16 11:33:46 -05:00
IBase newChildInstance;
try {
2015-02-16 11:33:46 -05:00
IFhirVersion version;
if (theTarget instanceof IResource) {
version = ((IResource) theTarget).getStructureFhirVersionEnum().getVersionImplementation();
} else {
version = FhirVersionEnum.DSTU2_HL7ORG.getVersionImplementation();
}
newChildInstance = version.getResourceReferenceType().newInstance();
} catch (InstantiationException e) {
throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Failed to instantiate " + myContext.getVersion().getResourceReferenceType(), e);
}
return newChildInstance;
}
private void pop() {
myState = myState.myStack;
myState.wereBack();
}
private void push(BaseState theState) {
theState.setStack(myState);
myState = theState;
}
private void putPlacerResourceInDeletedEntry(BundleEntry entry) {
IdDt id = null;
if (entry.getLinkSelf() != null && entry.getLinkSelf().isEmpty() == false) {
id = new IdDt(entry.getLinkSelf().getValue());
} else {
id = entry.getId();
}
IResource resource = entry.getResource();
if (resource == null && id != null && isNotBlank(id.getResourceType())) {
String resourceType = id.getResourceType();
RuntimeResourceDefinition def = myContext.getResourceDefinition(resourceType);
if (def == null) {
throw new DataFormatException("Entry references unknown resource type: " + resourceType);
}
2014-12-10 17:40:47 -05:00
resource = (IResource) def.newInstance();
resource.setId(id);
entry.setResource(resource);
}
if (resource != null) {
resource.getResourceMetadata().put(ResourceMetadataKeyEnum.DELETED_AT, entry.getDeletedAt());
resource.getResourceMetadata().put(ResourceMetadataKeyEnum.VERSION_ID, id);
}
}
2014-02-27 16:51:43 -05:00
public void string(String theData) {
myState.string(theData);
}
public boolean verifyNamespace(String theExpect, String theActual) {
if (myJsonMode) {
return true;
}
2014-02-27 16:51:43 -05:00
return StringUtils.equals(theExpect, theActual);
}
/**
2014-12-01 08:13:32 -05:00
* Invoked after any new XML event is individually processed, containing a copy of the XML event. This is basically
* intended for embedded XHTML content
2014-02-27 16:51:43 -05:00
*/
public void xmlEvent(XMLEvent theNextEvent) {
myState.xmlEvent(theNextEvent);
}
2014-12-10 17:40:47 -05:00
public static ParserState<Bundle> getPreAtomInstance(FhirContext theContext, Class<? extends IBaseResource> theResourceType, boolean theJsonMode) throws DataFormatException {
2014-03-22 12:33:07 -04:00
ParserState<Bundle> retVal = new ParserState<Bundle>(theContext, theJsonMode);
2014-12-01 08:13:32 -05:00
if (theContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
retVal.push(retVal.new PreAtomState(theResourceType));
} else {
retVal.push(retVal.new PreBundleState(theResourceType));
}
2014-02-27 07:39:36 -05:00
return retVal;
}
2014-03-07 16:23:49 -05:00
/**
* @param theResourceType
* May be null
*/
2014-12-10 17:40:47 -05:00
public static <T extends IBaseResource> ParserState<T> getPreResourceInstance(Class<T> theResourceType, FhirContext theContext, boolean theJsonMode) throws DataFormatException {
2014-03-22 12:33:07 -04:00
ParserState<T> retVal = new ParserState<T>(theContext, theJsonMode);
2015-02-16 11:33:46 -05:00
if (theResourceType == null) {
if (theContext.getVersion().getVersion() != FhirVersionEnum.DSTU2_HL7ORG) {
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
} else {
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
}
} else {
if (IResource.class.isAssignableFrom(theResourceType)) {
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
} else {
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
}
}
2014-02-27 16:51:43 -05:00
return retVal;
}
2014-02-26 17:13:49 -05:00
public static ParserState<TagList> getPreTagListInstance(FhirContext theContext, boolean theJsonMode) {
ParserState<TagList> retVal = new ParserState<TagList>(theContext, theJsonMode);
retVal.push(retVal.new PreTagListState());
return retVal;
}
2014-02-27 16:51:43 -05:00
public class AtomAuthorState extends BaseState {
2014-02-26 17:13:49 -05:00
2014-02-27 16:51:43 -05:00
private BaseBundle myInstance;
public AtomAuthorState(BaseBundle theEntry) {
super(null);
2014-02-27 16:51:43 -05:00
myInstance = theEntry;
2014-02-18 08:26:49 -05:00
}
2014-02-19 11:59:12 -05:00
2014-02-26 17:13:49 -05:00
@Override
public void endingElement() throws DataFormatException {
2014-02-26 17:13:49 -05:00
pop();
}
2014-02-19 11:59:12 -05:00
2014-02-26 17:13:49 -05:00
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-02-27 16:51:43 -05:00
if ("name".equals(theLocalPart)) {
push(new AtomPrimitiveState(myInstance.getAuthorName()));
} else if ("uri".equals(theLocalPart)) {
push(new AtomPrimitiveState(myInstance.getAuthorUri()));
} else {
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
}
}
2014-03-06 17:12:05 -05:00
public class AtomCategoryState extends BaseState {
private static final int STATE_LABEL = 2;
private static final int STATE_NONE = 0;
private static final int STATE_SCHEME = 3;
private static final int STATE_TERM = 1;
2014-07-04 09:27:36 -04:00
private int myCatState = STATE_NONE;
private String myLabel;
private String myScheme;
private TagList myTagList;
private String myTerm;
2014-03-06 17:12:05 -05:00
public AtomCategoryState(TagList theTagList) {
super(null);
myTagList = theTagList;
2014-03-06 17:12:05 -05:00
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("term".equals(theName)) {
myTerm = theValue;
2014-03-06 17:12:05 -05:00
} else if ("label".equals(theName)) {
myLabel = theValue;
2014-03-06 17:12:05 -05:00
} else if ("scheme".equals(theName)) {
myScheme = theValue;
} else if ("value".equals(theName)) {
/*
2014-12-01 08:13:32 -05:00
* This handles XML parsing, which is odd for this quasi-resource type, since the tag has three values
* instead of one like everything else.
*/
switch (myCatState) {
case STATE_LABEL:
myLabel = theValue;
break;
case STATE_TERM:
myTerm = theValue;
break;
case STATE_SCHEME:
myScheme = theValue;
break;
default:
super.string(theValue);
break;
}
2014-03-06 17:12:05 -05:00
}
}
@Override
public void endingElement() throws DataFormatException {
if (myCatState != STATE_NONE) {
myCatState = STATE_NONE;
} else {
if (isNotEmpty(myScheme) || isNotBlank(myTerm) || isNotBlank(myLabel)) {
myTagList.addTag(myScheme, myTerm, myLabel);
}
pop();
}
}
@Override
public void enteringNewElement(String theNamespaceURI, String theName) throws DataFormatException {
if (myCatState != STATE_NONE) {
throw new DataFormatException("Unexpected element in entry: " + theName);
}
if ("term".equals(theName)) {
myCatState = STATE_TERM;
} else if ("label".equals(theName)) {
myCatState = STATE_LABEL;
} else if ("scheme".equals(theName)) {
myCatState = STATE_SCHEME;
}
}
2014-03-06 17:12:05 -05:00
}
2014-12-01 08:13:32 -05:00
public class AtomDeletedEntryByState extends BaseState {
private BundleEntry myEntry;
public AtomDeletedEntryByState(BundleEntry theEntry) {
super(null);
myEntry = theEntry;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("name".equals(theLocalPart)) {
push(new AtomPrimitiveState(myEntry.getDeletedByName()));
} else if ("email".equals(theLocalPart)) {
push(new AtomPrimitiveState(myEntry.getDeletedByEmail()));
} else {
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
}
}
}
public class AtomDeletedEntryState extends AtomEntryState {
2014-12-10 17:40:47 -05:00
public AtomDeletedEntryState(Bundle theInstance, Class<? extends IBaseResource> theResourceType) {
super(theInstance, theResourceType);
}
2014-05-28 07:30:40 -04:00
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("ref".equals(theName)) {
getEntry().setId(new IdDt(theValue));
} else if ("when".equals(theName)) {
getEntry().setDeleted(new InstantDt(theValue));
}
}
2014-05-28 07:30:40 -04:00
@Override
public void endingElement() throws DataFormatException {
putPlacerResourceInDeletedEntry(getEntry());
super.endingElement();
}
2014-07-11 18:27:27 -04:00
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-12-01 08:13:32 -05:00
if ("by".equals(theLocalPart) && verifyNamespace(XmlParser.TOMBSTONES_NS, theNamespaceURI)) {
push(new AtomDeletedEntryByState(getEntry()));
} else if ("comment".equals(theLocalPart)) {
push(new AtomPrimitiveState(getEntry().getDeletedComment()));
2014-07-11 18:27:27 -04:00
} else {
2014-12-01 08:13:32 -05:00
super.enteringNewElement(theNamespaceURI, theLocalPart);
2014-07-11 18:27:27 -04:00
}
}
}
private class AtomDeletedJsonWhenState extends BaseState {
private String myData;
private IPrimitiveDatatype<?> myPrimitive;
public AtomDeletedJsonWhenState(IPrimitiveDatatype<?> thePrimitive) {
super(null);
Validate.notNull(thePrimitive, "thePrimitive");
myPrimitive = thePrimitive;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
myData = theValue;
}
@Override
public void endingElement() throws DataFormatException {
myPrimitive.setValueAsString(myData);
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new DataFormatException("Unexpected nested element in atom tag: " + theLocalPart);
}
@Override
protected IElement getCurrentElement() {
return null;
}
}
2014-02-27 16:51:43 -05:00
public class AtomEntryState extends BaseState {
private boolean myDeleted;
2014-02-27 16:51:43 -05:00
private BundleEntry myEntry;
2014-12-10 17:40:47 -05:00
private Class<? extends IBaseResource> myResourceType;
2014-02-27 16:51:43 -05:00
2014-12-10 17:40:47 -05:00
public AtomEntryState(Bundle theInstance, Class<? extends IBaseResource> theResourceType) {
super(null);
2014-02-27 16:51:43 -05:00
myEntry = new BundleEntry();
myResourceType = theResourceType;
2014-02-27 16:51:43 -05:00
theInstance.getEntries().add(myEntry);
2014-02-26 17:13:49 -05:00
}
@Override
public void endingElement() throws DataFormatException {
2014-04-14 08:40:30 -04:00
populateResourceMetadata();
2014-02-27 16:51:43 -05:00
pop();
if (myDeleted) {
putPlacerResourceInDeletedEntry(myEntry);
}
2014-02-26 17:13:49 -05:00
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("title".equals(theLocalPart)) {
push(new AtomPrimitiveState(myEntry.getTitle()));
} else if ("id".equals(theLocalPart)) {
push(new AtomPrimitiveState(myEntry.getId()));
} else if ("link".equals(theLocalPart)) {
push(new AtomLinkState(myEntry));
} else if ("updated".equals(theLocalPart)) {
push(new AtomPrimitiveState(myEntry.getUpdated()));
} else if ("published".equals(theLocalPart)) {
push(new AtomPrimitiveState(myEntry.getPublished()));
} else if ("author".equals(theLocalPart)) {
push(new AtomAuthorState(myEntry));
} else if ("content".equals(theLocalPart)) {
2015-02-16 11:33:46 -05:00
push(new PreResourceStateHapi(myEntry, myResourceType));
} else if ("summary".equals(theLocalPart)) {
push(new XhtmlState(getPreResourceState(), myEntry.getSummary(), false));
} else if ("category".equals(theLocalPart)) {
push(new AtomCategoryState(myEntry.getCategories()));
2014-05-21 18:12:00 -04:00
} else if ("deleted".equals(theLocalPart) && myJsonMode) {
// JSON and XML deleted entries are completely different for some reason
myDeleted = true;
2014-05-21 18:12:00 -04:00
push(new AtomDeletedJsonWhenState(myEntry.getDeletedAt()));
} else {
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
}
// TODO: handle category
}
protected BundleEntry getEntry() {
return myEntry;
}
@SuppressWarnings("deprecation")
2014-04-14 08:40:30 -04:00
private void populateResourceMetadata() {
if (myEntry.getResource() == null) {
return;
}
2014-05-26 09:09:54 -04:00
IdDt id = myEntry.getId();
2014-05-28 07:30:40 -04:00
if (id != null && id.isEmpty() == false) {
2014-05-26 09:09:54 -04:00
myEntry.getResource().setId(id);
}
2014-05-28 07:30:40 -04:00
Map<ResourceMetadataKeyEnum<?>, Object> metadata = myEntry.getResource().getResourceMetadata();
2014-04-14 08:40:30 -04:00
if (myEntry.getPublished().isEmpty() == false) {
ResourceMetadataKeyEnum.PUBLISHED.put(myEntry.getResource(), myEntry.getPublished());
2014-04-14 08:40:30 -04:00
}
if (myEntry.getUpdated().isEmpty() == false) {
ResourceMetadataKeyEnum.UPDATED.put(myEntry.getResource(), myEntry.getUpdated());
2014-04-14 08:40:30 -04:00
}
2014-07-04 09:27:36 -04:00
2014-07-03 18:02:14 -04:00
ResourceMetadataKeyEnum.TITLE.put(myEntry.getResource(), myEntry.getTitle().getValue());
2014-07-04 09:27:36 -04:00
if (myEntry.getCategories().isEmpty() == false) {
TagList tagList = new TagList();
for (Tag next : myEntry.getCategories()) {
tagList.add(next);
}
ResourceMetadataKeyEnum.TAG_LIST.put(myEntry.getResource(), tagList);
}
2014-04-14 08:40:30 -04:00
if (!myEntry.getLinkSelf().isEmpty()) {
String linkSelfValue = myEntry.getLinkSelf().getValue();
2014-05-26 09:09:54 -04:00
IdDt linkSelf = new IdDt(linkSelfValue);
myEntry.getResource().setId(linkSelf);
2014-06-23 09:04:48 -04:00
if (isNotBlank(linkSelf.getVersionIdPart())) {
2014-05-26 09:09:54 -04:00
metadata.put(ResourceMetadataKeyEnum.VERSION_ID, linkSelf);
2014-04-14 08:40:30 -04:00
}
}
if (!myEntry.getLinkAlternate().isEmpty()) {
ResourceMetadataKeyEnum.LINK_ALTERNATE.put(myEntry.getResource(), myEntry.getLinkAlternate().getValue());
}
if (!myEntry.getLinkSearch().isEmpty()) {
ResourceMetadataKeyEnum.LINK_SEARCH.put(myEntry.getResource(), myEntry.getLinkSearch().getValue());
}
2014-04-14 08:40:30 -04:00
}
2014-02-18 08:26:49 -05:00
}
2014-02-27 11:57:50 -05:00
private class AtomLinkState extends BaseState {
2014-02-27 16:51:43 -05:00
private BundleEntry myEntry;
2014-02-27 11:57:50 -05:00
private String myHref;
private Bundle myInstance;
2014-02-27 16:51:43 -05:00
private String myRel;
2014-02-27 11:57:50 -05:00
public AtomLinkState(Bundle theInstance) {
super(null);
2014-02-27 11:57:50 -05:00
myInstance = theInstance;
}
2014-02-27 16:51:43 -05:00
public AtomLinkState(BundleEntry theEntry) {
super(null);
2014-02-27 16:51:43 -05:00
myEntry = theEntry;
}
@Override
2014-02-27 16:51:43 -05:00
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("rel".equals(theName)) {
2014-02-27 11:57:50 -05:00
myRel = theValue;
2014-02-27 16:51:43 -05:00
} else if ("href".equals(theName)) {
2014-02-27 11:57:50 -05:00
myHref = theValue;
}
}
@Override
public void endingElement() throws DataFormatException {
2014-02-27 16:51:43 -05:00
if (myInstance != null) {
if ("self".equals(myRel)) {
myInstance.getLinkSelf().setValueAsString(myHref);
} else if ("first".equals(myRel)) {
myInstance.getLinkFirst().setValueAsString(myHref);
} else if ("previous".equals(myRel)) {
myInstance.getLinkPrevious().setValueAsString(myHref);
} else if ("next".equals(myRel)) {
myInstance.getLinkNext().setValueAsString(myHref);
} else if ("last".equals(myRel)) {
myInstance.getLinkLast().setValueAsString(myHref);
} else if ("fhir-base".equals(myRel)) {
myInstance.getLinkBase().setValueAsString(myHref);
}
} else {
2014-05-26 09:09:54 -04:00
if ("self".equals(myRel)) {
myEntry.getLinkSelf().setValueAsString(myHref);
} else if ("search".equals(myRel)) {
myEntry.getLinkSearch().setValueAsString(myHref);
2014-05-26 09:09:54 -04:00
} else if ("alternate".equals(myRel)) {
myEntry.getLinkAlternate().setValueAsString(myHref);
}
2014-02-27 11:57:50 -05:00
}
pop();
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-03-19 17:38:31 -04:00
throw new DataFormatException("Found unexpected element content '" + theLocalPart + "' within <link>");
}
}
2014-02-27 16:51:43 -05:00
private class AtomPrimitiveState extends BaseState {
private String myData;
private IPrimitiveDatatype<?> myPrimitive;
public AtomPrimitiveState(IPrimitiveDatatype<?> thePrimitive) {
super(null);
Validate.notNull(thePrimitive, "thePrimitive");
2014-02-27 16:51:43 -05:00
myPrimitive = thePrimitive;
}
2014-05-21 18:12:00 -04:00
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if (myJsonMode) {
string(theValue);
}
super.attributeValue(theName, theValue);
}
2014-02-27 16:51:43 -05:00
@Override
public void endingElement() throws DataFormatException {
2014-02-27 16:51:43 -05:00
myPrimitive.setValueAsString(myData);
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new DataFormatException("Unexpected nested element in atom tag: " + theLocalPart);
}
@Override
protected IElement getCurrentElement() {
return null;
}
2014-02-27 16:51:43 -05:00
@Override
public void string(String theData) {
if (myData == null) {
myData = theData;
} else {
// this shouldn't generally happen so it's ok that it's
// inefficient
myData = myData + theData;
}
}
2014-05-21 18:12:00 -04:00
}
2014-02-26 17:13:49 -05:00
private class AtomState extends BaseState {
private Bundle myInstance;
2014-12-10 17:40:47 -05:00
private Class<? extends IBaseResource> myResourceType;
2014-02-26 17:13:49 -05:00
2014-12-10 17:40:47 -05:00
public AtomState(Bundle theInstance, Class<? extends IBaseResource> theResourceType) {
super(null);
2014-02-26 17:13:49 -05:00
myInstance = theInstance;
myResourceType = theResourceType;
2014-02-26 17:13:49 -05:00
}
@Override
public void endingElement() throws DataFormatException {
2014-02-26 17:13:49 -05:00
pop();
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-02-27 12:04:19 -05:00
if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) {
push(new AtomEntryState(myInstance, myResourceType));
2014-02-27 12:04:19 -05:00
} else if (theLocalPart.equals("title")) {
2014-02-26 17:13:49 -05:00
push(new AtomPrimitiveState(myInstance.getTitle()));
} else if ("id".equals(theLocalPart)) {
push(new AtomPrimitiveState(myInstance.getBundleId()));
} else if ("link".equals(theLocalPart)) {
2014-02-27 11:57:50 -05:00
push(new AtomLinkState(myInstance));
} else if ("totalResults".equals(theLocalPart) && (verifyNamespace(XmlParser.OPENSEARCH_NS, theNamespaceURI) || verifyNamespace(Constants.OPENSEARCH_NS_OLDER, theNamespaceURI))) {
2014-02-27 11:57:50 -05:00
push(new AtomPrimitiveState(myInstance.getTotalResults()));
} else if ("updated".equals(theLocalPart)) {
push(new AtomPrimitiveState(myInstance.getUpdated()));
} else if ("author".equals(theLocalPart)) {
push(new AtomAuthorState(myInstance));
} else if ("category".equals(theLocalPart)) {
push(new AtomCategoryState(myInstance.getCategories()));
2014-05-21 18:12:00 -04:00
} else if ("deleted-entry".equals(theLocalPart) && verifyNamespace(XmlParser.TOMBSTONES_NS, theNamespaceURI)) {
push(new AtomDeletedEntryState(myInstance, myResourceType));
2014-02-27 16:51:43 -05:00
} else {
if (theNamespaceURI != null) {
throw new DataFormatException("Unexpected element: {" + theNamespaceURI + "}" + theLocalPart);
} else {
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
2014-02-27 12:04:19 -05:00
}
2014-02-27 11:57:50 -05:00
// TODO: handle category and DSig
2014-02-26 17:13:49 -05:00
}
@Override
protected IElement getCurrentElement() {
return myInstance;
2014-02-26 17:13:49 -05:00
}
}
2014-12-01 08:13:32 -05:00
private class BasePreAtomOrBundleState extends BaseState {
private Bundle myInstance;
private Class<? extends IBaseResource> myResourceType;
2014-12-01 08:13:32 -05:00
public BasePreAtomOrBundleState(Class<? extends IBaseResource> theResourceType) {
2014-12-01 08:13:32 -05:00
super(null);
myResourceType = theResourceType;
}
@Override
public void endingElement() throws DataFormatException {
// ignore
}
@Override
protected IElement getCurrentElement() {
return myInstance;
}
public Bundle getInstance() {
return myInstance;
}
protected Class<? extends IBaseResource> getResourceType() {
2014-12-01 08:13:32 -05:00
return myResourceType;
}
public void setInstance(Bundle theInstance) {
myInstance = theInstance;
}
@SuppressWarnings("unchecked")
@Override
public void wereBack() {
myObject = (T) myInstance;
/*
* Stitch together resource references
*/
Map<String, IResource> idToResource = new HashMap<String, IResource>();
List<IResource> resources = myInstance.toListOfResources();
for (IResource next : resources) {
if (next.getId() != null && next.getId().isEmpty() == false) {
idToResource.put(next.getId().toUnqualifiedVersionless().getValue(), next);
}
}
for (IResource next : resources) {
List<BaseResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt nextRef : refs) {
2014-12-01 08:13:32 -05:00
if (nextRef.isEmpty() == false && nextRef.getReference() != null) {
IResource target = idToResource.get(nextRef.getReference().getValue());
if (target != null) {
nextRef.setResource(target);
}
}
}
}
}
}
2014-02-20 12:13:05 -05:00
private abstract class BaseState {
2014-02-26 17:13:49 -05:00
private PreResourceState myPreResourceState;
2014-02-20 12:13:05 -05:00
private BaseState myStack;
2014-02-18 08:26:49 -05:00
public BaseState(PreResourceState thePreResourceState) {
super();
myPreResourceState = thePreResourceState;
}
2014-08-28 07:53:41 -04:00
@SuppressWarnings("unused")
2014-02-27 16:51:43 -05:00
public void attributeValue(String theName, String theValue) throws DataFormatException {
2014-02-27 11:57:50 -05:00
// ignore by default
}
2014-02-21 21:06:11 -05:00
public void endingElement() throws DataFormatException {
2014-02-27 11:57:50 -05:00
// ignore by default
}
2014-02-19 11:59:12 -05:00
2014-08-28 07:53:41 -04:00
@SuppressWarnings("unused")
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
// ignore by default
}
2014-02-18 08:26:49 -05:00
2014-02-23 18:13:59 -05:00
/**
* Default implementation just handles undeclared extensions
*/
2014-08-28 07:53:41 -04:00
@SuppressWarnings("unused")
2014-07-04 09:27:36 -04:00
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
if (myPreResourceState != null && getCurrentElement() instanceof ISupportsUndeclaredExtensions) {
2014-03-27 08:51:02 -04:00
ExtensionDt newExtension = new ExtensionDt(theIsModifier, theUrlAttr);
2014-03-10 18:17:30 -04:00
ISupportsUndeclaredExtensions elem = (ISupportsUndeclaredExtensions) getCurrentElement();
elem.addUndeclaredExtension(newExtension);
ExtensionState newState = new ExtensionState(myPreResourceState, newExtension);
2014-02-22 15:33:02 -05:00
push(newState);
2014-02-28 13:27:35 -05:00
} 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 {
throw new DataFormatException("Type " + getCurrentElement() + " does not support undeclared extentions, and found an extension with URL: " + theUrlAttr);
}
}
2014-02-22 15:33:02 -05:00
}
}
protected IBase getCurrentElement() {
return null;
}
public PreResourceState getPreResourceState() {
return myPreResourceState;
}
public boolean isPreResource() {
return false;
}
2014-02-20 12:13:05 -05:00
public void setStack(BaseState theState) {
myStack = theState;
}
2014-08-27 08:55:00 -04:00
/**
* @param theData
* The string value
2014-08-27 08:55:00 -04:00
*/
2014-07-03 18:02:14 -04:00
public void string(String theData) {
2014-02-27 11:57:50 -05:00
// ignore by default
}
2014-02-27 16:51:43 -05:00
public void wereBack() {
// allow an implementor to override
}
2014-08-27 08:55:00 -04:00
/**
* @param theNextEvent
* The XML event
2014-08-27 08:55:00 -04:00
*/
2014-07-03 18:02:14 -04:00
public void xmlEvent(XMLEvent theNextEvent) {
2014-02-27 11:57:50 -05:00
// ignore
}
}
2014-12-18 08:21:07 -05:00
private class BinaryResourceStateForDstu1 extends BaseState {
private static final int SUBSTATE_CONTENT = 2;
private static final int SUBSTATE_CT = 1;
private String myData;
2015-03-04 08:44:31 -05:00
private IBaseBinary myInstance;
private int mySubState = 0;
2015-03-04 08:44:31 -05:00
public BinaryResourceStateForDstu1(PreResourceState thePreResourceState, IBaseBinary theInstance) {
super(thePreResourceState);
myInstance = theInstance;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("id".equals(theName)) {
if (myInstance instanceof IIdentifiableElement) {
((IIdentifiableElement) myInstance).setElementSpecificId((theValue));
} else {
((IResource) myInstance).setId(new IdDt(theValue));
}
} else if ("contentType".equals(theName)) {
myInstance.setContentType(theValue);
} else if (myJsonMode && "value".equals(theName)) {
string(theValue);
}
}
@Override
public void endingElement() throws DataFormatException {
if (mySubState == SUBSTATE_CT) {
myInstance.setContentType(myData);
mySubState = 0;
2014-07-04 09:27:36 -04:00
myData = null;
return;
} else if (mySubState == SUBSTATE_CONTENT) {
myInstance.setContentAsBase64(myData);
mySubState = 0;
2014-07-04 09:27:36 -04:00
myData = null;
return;
} else {
if (!myJsonMode) {
2014-07-04 09:27:36 -04:00
myInstance.setContentAsBase64(myData);
}
pop();
}
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (myJsonMode && "contentType".equals(theLocalPart) && mySubState == 0) {
mySubState = SUBSTATE_CT;
} else if (myJsonMode && "content".equals(theLocalPart) && mySubState == 0) {
mySubState = SUBSTATE_CONTENT;
} else {
throw new DataFormatException("Unexpected nested element in atom tag: " + theLocalPart);
}
}
@Override
protected IElement getCurrentElement() {
2014-02-27 16:51:43 -05:00
return null;
}
@Override
public void string(String theData) {
if (myData == null) {
myData = theData;
} else {
// this shouldn't generally happen so it's ok that it's
// inefficient
myData = myData + theData;
}
}
2014-02-26 17:13:49 -05:00
}
2014-12-01 08:13:32 -05:00
private class BundleEntryDeletedState extends BaseState {
private BundleEntry myEntry;
public BundleEntryDeletedState(PreResourceState thePreResourceState, BundleEntry theEntry) {
super(thePreResourceState);
myEntry = theEntry;
}
@Override
public void endingElement() throws DataFormatException {
String resType = myEntry.getDeletedResourceType().getValue();
String id = myEntry.getDeletedResourceId().getValue();
String version = myEntry.getDeletedResourceVersion().getValue();
myEntry.setLinkSelf(new StringDt(new IdDt(resType, id, version).getValue()));
putPlacerResourceInDeletedEntry(myEntry);
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("type".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceType()));
} else if ("id".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceId()));
2015-02-06 15:50:29 -05:00
} else if ("resourceId".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceId()));
2014-12-01 08:13:32 -05:00
} else if ("version".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceVersion()));
2015-02-06 15:50:29 -05:00
} else if ("versionId".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedResourceVersion()));
2014-12-01 08:13:32 -05:00
} else if ("instant".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getDeletedAt()));
} else {
throw new DataFormatException("Unexpected element '" + theLocalPart + "' in element 'deleted'");
}
}
}
public class BundleEntrySearchState extends BaseState {
private BundleEntry myEntry;
public BundleEntrySearchState(BundleEntry theEntry) {
super(null);
myEntry = theEntry;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("mode".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getSearchMode()));
} else if ("score".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getScore()));
} else {
throw new DataFormatException("Unexpected element in Bundle.entry.search: " + theLocalPart);
}
}
}
2014-12-01 08:13:32 -05:00
public class BundleEntryState extends BaseState {
private BundleEntry myEntry;
private Class<? extends IBaseResource> myResourceType;
2014-12-01 08:13:32 -05:00
public BundleEntryState(Bundle theInstance, Class<? extends IBaseResource> theResourceType) {
2014-12-01 08:13:32 -05:00
super(null);
myEntry = new BundleEntry();
myResourceType = theResourceType;
theInstance.getEntries().add(myEntry);
}
@Override
public void endingElement() throws DataFormatException {
populateResourceMetadata();
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("base".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getLinkBase()));
} else if ("transaction".equals(theLocalPart)) {
push(new BundleEntryTransactionState(myEntry));
2014-12-01 08:13:32 -05:00
} else if ("search".equals(theLocalPart)) {
push(new BundleEntrySearchState(myEntry));
2014-12-01 08:13:32 -05:00
} else if ("score".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getScore()));
} else if ("resource".equals(theLocalPart)) {
2015-02-16 11:33:46 -05:00
push(new PreResourceStateHapi(myEntry, myResourceType));
2014-12-01 08:13:32 -05:00
} else if ("deleted".equals(theLocalPart)) {
push(new BundleEntryDeletedState(getPreResourceState(), myEntry));
} else {
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
}
// TODO: handle category
}
protected BundleEntry getEntry() {
return myEntry;
}
@SuppressWarnings("deprecation")
private void populateResourceMetadata() {
if (myEntry.getResource() == null) {
return;
}
IdDt id = myEntry.getId();
if (id != null && id.isEmpty() == false) {
myEntry.getResource().setId(id);
}
Map<ResourceMetadataKeyEnum<?>, Object> metadata = myEntry.getResource().getResourceMetadata();
if (myEntry.getPublished().isEmpty() == false) {
ResourceMetadataKeyEnum.PUBLISHED.put(myEntry.getResource(), myEntry.getPublished());
}
if (myEntry.getUpdated().isEmpty() == false) {
ResourceMetadataKeyEnum.UPDATED.put(myEntry.getResource(), myEntry.getUpdated());
}
ResourceMetadataKeyEnum.TITLE.put(myEntry.getResource(), myEntry.getTitle().getValue());
if (myEntry.getCategories().isEmpty() == false) {
TagList tagList = new TagList();
for (Tag next : myEntry.getCategories()) {
tagList.add(next);
}
ResourceMetadataKeyEnum.TAG_LIST.put(myEntry.getResource(), tagList);
}
if (!myEntry.getLinkSelf().isEmpty()) {
String linkSelfValue = myEntry.getLinkSelf().getValue();
IdDt linkSelf = new IdDt(linkSelfValue);
myEntry.getResource().setId(linkSelf);
if (isNotBlank(linkSelf.getVersionIdPart())) {
metadata.put(ResourceMetadataKeyEnum.VERSION_ID, linkSelf);
}
}
if (!myEntry.getLinkAlternate().isEmpty()) {
ResourceMetadataKeyEnum.LINK_ALTERNATE.put(myEntry.getResource(), myEntry.getLinkAlternate().getValue());
}
if (!myEntry.getLinkSearch().isEmpty()) {
ResourceMetadataKeyEnum.LINK_SEARCH.put(myEntry.getResource(), myEntry.getLinkSearch().getValue());
}
if (!myEntry.getSearchMode().isEmpty()) {
ResourceMetadataKeyEnum.ENTRY_SEARCH_MODE.put(myEntry.getResource(), myEntry.getSearchMode().getValueAsEnum());
}
if (!myEntry.getTransactionMethod().isEmpty()) {
ResourceMetadataKeyEnum.ENTRY_TRANSACTION_METHOD.put(myEntry.getResource(), myEntry.getTransactionMethod().getValueAsEnum());
2015-01-09 22:02:31 -05:00
}
if (!myEntry.getScore().isEmpty()) {
ResourceMetadataKeyEnum.ENTRY_SCORE.put(myEntry.getResource(), myEntry.getScore());
}
2014-12-01 08:13:32 -05:00
}
}
public class BundleEntryTransactionState extends BaseState {
private BundleEntry myEntry;
public BundleEntryTransactionState(BundleEntry theEntry) {
super(null);
myEntry = theEntry;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("method".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getTransactionMethod()));
2015-02-16 23:02:50 -05:00
} else if ("url".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myEntry.getLinkSearch()));
} else {
ourLog.warn("Unexpected element in Bundle.entry.search: " + theLocalPart);
push(new SwallowChildrenWholeState(getPreResourceState()));
}
}
}
2014-12-01 08:13:32 -05:00
private class BundleLinkState extends BaseState {
private BundleEntry myEntry;
private String myHref;
private boolean myInRelation = false;
private Bundle myInstance;
2014-12-01 08:13:32 -05:00
private boolean myInUrl = false;
private String myRel;
2014-12-01 08:13:32 -05:00
public BundleLinkState(Bundle theInstance) {
super(null);
myInstance = theInstance;
}
public BundleLinkState(BundleEntry theEntry) {
super(null);
myEntry = theEntry;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if (myInRelation) {
myRel = theValue;
} else if (myInUrl) {
myHref = theValue;
}
}
@Override
public void endingElement() throws DataFormatException {
if (!myInRelation && !myInUrl) {
if (myInstance != null) {
if ("self".equals(myRel)) {
myInstance.getLinkSelf().setValueAsString(myHref);
} else if ("first".equals(myRel)) {
myInstance.getLinkFirst().setValueAsString(myHref);
} else if ("previous".equals(myRel)) {
myInstance.getLinkPrevious().setValueAsString(myHref);
} else if ("next".equals(myRel)) {
myInstance.getLinkNext().setValueAsString(myHref);
} else if ("last".equals(myRel)) {
myInstance.getLinkLast().setValueAsString(myHref);
} else if ("fhir-base".equals(myRel)) {
myInstance.getLinkBase().setValueAsString(myHref);
}
} else {
if ("self".equals(myRel)) {
myEntry.getLinkSelf().setValueAsString(myHref);
} else if ("search".equals(myRel)) {
myEntry.getLinkSearch().setValueAsString(myHref);
} else if ("alternate".equals(myRel)) {
myEntry.getLinkAlternate().setValueAsString(myHref);
}
}
pop();
} else {
myInRelation = false;
myInUrl = false;
}
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (myInRelation || myInUrl) {
throw new DataFormatException("Unexpected element '" + theLocalPart + "' in element 'link'");
}
if ("relation".equals(theLocalPart)) {
myInRelation = true;
} else if ("url".equals(theLocalPart)) {
myInUrl = true;
} else {
throw new DataFormatException("Unexpected element '" + theLocalPart + "' in element 'link'");
}
}
}
private class BundleState extends BaseState {
private Bundle myInstance;
private Class<? extends IBaseResource> myResourceType;
2014-12-01 08:13:32 -05:00
public BundleState(Bundle theInstance, Class<? extends IBaseResource> theResourceType) {
2014-12-01 08:13:32 -05:00
super(null);
myInstance = theInstance;
myResourceType = theResourceType;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if ("id".equals(theLocalPart)) {
push(new PrimitiveState(null, myInstance.getId()));
} else if ("meta".equals(theLocalPart)) {
push(new MetaElementState(null, myInstance.getResourceMetadata()));
} else if ("type".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myInstance.getType()));
} else if ("base".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myInstance.getLinkBase()));
} else if ("total".equals(theLocalPart)) {
push(new PrimitiveState(getPreResourceState(), myInstance.getTotalResults()));
} else if ("link".equals(theLocalPart)) {
push(new BundleLinkState(myInstance));
} else if ("entry".equals(theLocalPart)) {
push(new BundleEntryState(myInstance, myResourceType));
} else if ("text".equals(theLocalPart)) {
push(new SwallowChildrenWholeState(getPreResourceState()));
2014-12-01 08:13:32 -05:00
} else {
throw new DataFormatException("Unxpected element '" + theLocalPart + "' in element 'Bundle'");
2014-12-01 08:13:32 -05:00
}
// if ("entry".equals(theLocalPart) && verifyNamespace(XmlParser.ATOM_NS, theNamespaceURI)) {
// push(new AtomEntryState(myInstance, myResourceType));
// } else if (theLocalPart.equals("published")) {
// push(new AtomPrimitiveState(myInstance.getPublished()));
// } else if (theLocalPart.equals("title")) {
// push(new AtomPrimitiveState(myInstance.getTitle()));
// } else if ("id".equals(theLocalPart)) {
// push(new AtomPrimitiveState(myInstance.getBundleId()));
// } else if ("link".equals(theLocalPart)) {
// push(new AtomLinkState(myInstance));
// } else if ("totalResults".equals(theLocalPart) && (verifyNamespace(XmlParser.OPENSEARCH_NS,
// theNamespaceURI) || verifyNamespace(Constants.OPENSEARCH_NS_OLDER, theNamespaceURI))) {
// push(new AtomPrimitiveState(myInstance.getTotalResults()));
// } else if ("updated".equals(theLocalPart)) {
// push(new AtomPrimitiveState(myInstance.getUpdated()));
// } else if ("author".equals(theLocalPart)) {
// push(new AtomAuthorState(myInstance));
// } else if ("category".equals(theLocalPart)) {
// push(new AtomCategoryState(myInstance.getCategories()));
// } else if ("deleted-entry".equals(theLocalPart) && verifyNamespace(XmlParser.TOMBSTONES_NS,
// theNamespaceURI)) {
// push(new AtomDeletedEntryState(myInstance, myResourceType));
// } else {
// if (theNamespaceURI != null) {
// throw new DataFormatException("Unexpected element: {" + theNamespaceURI + "}" + theLocalPart);
// } else {
// throw new DataFormatException("Unexpected element: " + theLocalPart);
// }
// }
// TODO: handle category and DSig
}
@Override
protected IElement getCurrentElement() {
return myInstance;
}
@Override
public void wereBack() {
for (BundleEntry nextEntry : myInstance.getEntries()) {
IResource nextResource = nextEntry.getResource();
if (nextResource == null) {
continue;
}
String bundleBaseUrl = myInstance.getLinkBase().getValue();
String entryBaseUrl = nextEntry.getLinkBase().getValue();
String version = ResourceMetadataKeyEnum.VERSION.get(nextResource);
String resourceName = myContext.getResourceDefinition(nextResource).getName();
String bundleIdPart = nextResource.getId().getIdPart();
if (isNotBlank(bundleIdPart)) {
if (isNotBlank(entryBaseUrl)) {
nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
} else {
nextResource.setId(new IdDt(bundleBaseUrl, resourceName, bundleIdPart, version));
}
}
}
String bundleVersion = (String) myInstance.getResourceMetadata().get(ResourceMetadataKeyEnum.VERSION);
String baseUrl = myInstance.getLinkBase().getValue();
String id = myInstance.getId().getIdPart();
if (isNotBlank(id)) {
myInstance.setId(new IdDt(baseUrl, "Bundle", id, bundleVersion));
}
}
2014-12-01 08:13:32 -05:00
}
2015-02-16 11:33:46 -05:00
private class ContainedResourcesStateHapi extends PreResourceState {
2014-03-22 12:33:07 -04:00
2015-02-16 11:33:46 -05:00
public ContainedResourcesStateHapi(PreResourceState thePreResourcesState) {
super(thePreResourcesState, ((IResource) thePreResourcesState.myInstance).getStructureFhirVersionEnum());
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void wereBack() {
2014-12-10 22:02:31 -05:00
IResource res = (IResource) getCurrentElement();
assert res != null;
2014-03-22 12:33:07 -04:00
if (res.getId() == null || res.getId().isEmpty()) {
2014-03-17 08:57:57 -04:00
ourLog.debug("Discarding contained resource with no ID!");
} else {
getPreResourceState().getContainedResources().put(res.getId().getValueAsString(), res);
2014-10-15 14:34:14 -04:00
if (!res.getId().isLocal()) {
res.setId(new IdDt('#' + res.getId().getIdPart()));
}
}
2014-12-10 22:02:31 -05:00
IResource preResCurrentElement = (IResource) getPreResourceState().getCurrentElement();
@SuppressWarnings("unchecked")
List<IResource> containedResources = (List<IResource>) preResCurrentElement.getContained().getContainedResources();
containedResources.add(res);
}
}
2015-04-13 08:32:49 -04:00
private class ContainedResourcesStateHl7Org extends PreResourceState {
public ContainedResourcesStateHl7Org(PreResourceState thePreResourcesState) {
super(thePreResourcesState, FhirVersionEnum.DSTU2_HL7ORG);
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void wereBack() {
IBaseResource res = getCurrentElement();
assert res != null;
if (res.getId() == null || res.getId().isEmpty()) {
ourLog.debug("Discarding contained resource with no ID!");
} else {
getPreResourceState().getContainedResources().put(res.getId().getValue(), res);
if (!res.getId().isLocal()) {
res.getId().setValue('#' + res.getId().getIdPart());
}
}
2015-04-13 08:32:49 -04:00
IBaseResource preResCurrentElement = getPreResourceState().getCurrentElement();
RuntimeResourceDefinition def = myContext.getResourceDefinition(preResCurrentElement);
def.getChildByName("contained").getMutator().addValue(preResCurrentElement, res);
}
}
2014-02-26 17:13:49 -05:00
private class DeclaredExtensionState extends BaseState {
2014-12-10 22:02:31 -05:00
private IBase myChildInstance;
2014-02-26 17:13:49 -05:00
private RuntimeChildDeclaredExtensionDefinition myDefinition;
2014-12-10 22:02:31 -05:00
private IBase myParentInstance;
private PreResourceState myPreResourceState;
2014-02-26 17:13:49 -05:00
2014-12-10 22:02:31 -05:00
public DeclaredExtensionState(PreResourceState thePreResourceState, RuntimeChildDeclaredExtensionDefinition theDefinition, IBase theParentInstance) {
super(thePreResourceState);
2014-03-22 12:33:07 -04:00
myPreResourceState = thePreResourceState;
2014-02-26 17:13:49 -05:00
myDefinition = theDefinition;
myParentInstance = theParentInstance;
}
@Override
public void endingElement() throws DataFormatException {
2014-02-26 17:13:49 -05:00
pop();
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-02-26 17:13:49 -05:00
BaseRuntimeElementDefinition<?> target = myDefinition.getChildByName(theLocalPart);
if (target == null) {
throw new DataFormatException("Unknown extension element name: " + theLocalPart);
}
switch (target.getChildType()) {
case COMPOSITE_DATATYPE: {
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
2015-04-13 08:32:49 -04:00
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(myDefinition.getInstanceConstructorArguments());
2014-02-26 17:13:49 -05:00
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
ElementCompositeState newState = new ElementCompositeState(myPreResourceState, compositeTarget, newChildInstance);
2014-02-26 17:13:49 -05:00
push(newState);
return;
}
case PRIMITIVE_DATATYPE: {
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
2015-03-11 09:11:36 -04:00
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance(myDefinition.getInstanceConstructorArguments());
2014-02-26 17:13:49 -05:00
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
2014-02-26 17:13:49 -05:00
push(newState);
return;
}
case RESOURCE_REF: {
2015-02-16 11:33:46 -05:00
IBase newChildInstance = newResourceReferenceDt(myPreResourceState.myInstance);
2014-02-26 17:13:49 -05:00
myDefinition.getMutator().addValue(myParentInstance, newChildInstance);
2015-02-16 11:33:46 -05:00
BaseState newState = createResourceReferenceState(getPreResourceState(), newChildInstance);
2014-02-26 17:13:49 -05:00
push(newState);
return;
}
case PRIMITIVE_XHTML:
case RESOURCE:
case RESOURCE_BLOCK:
case UNDECL_EXT:
case EXTENSION_DECLARED:
default:
break;
}
}
@Override
2014-03-10 18:17:30 -04:00
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
2014-02-26 17:13:49 -05:00
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getChildExtensionForUrl(theUrlAttr);
if (declaredExtension != null) {
if (myChildInstance == null) {
myChildInstance = myDefinition.newInstance();
myDefinition.getMutator().addValue(myParentInstance, myChildInstance);
}
BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myChildInstance);
2014-02-26 17:13:49 -05:00
push(newState);
} else {
2014-03-10 18:17:30 -04:00
super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier);
2014-02-26 17:13:49 -05:00
}
}
@Override
2014-12-10 22:02:31 -05:00
protected IBase getCurrentElement() {
2014-02-26 17:13:49 -05:00
return myParentInstance;
}
2014-02-20 12:13:05 -05:00
}
2014-02-19 11:59:12 -05:00
2015-02-16 11:33:46 -05:00
private BaseState createResourceReferenceState(ParserState<T>.PreResourceState thePreResourceState, IBase newChildInstance) {
BaseState newState;
2015-05-01 12:27:56 -07:00
if (newChildInstance instanceof IBaseReference) {
newState = new ResourceReferenceStateHl7Org(thePreResourceState, (IBaseReference) newChildInstance);
2015-02-16 11:33:46 -05:00
} else {
newState = new ResourceReferenceStateHapi(thePreResourceState, (BaseResourceReferenceDt) newChildInstance);
}
return newState;
}
2015-03-11 09:11:36 -04:00
private class ElementCompositeState extends BaseState {
2014-02-19 11:59:12 -05:00
private BaseRuntimeElementCompositeDefinition<?> myDefinition;
public BaseRuntimeElementCompositeDefinition<?> getDefinition() {
return myDefinition;
}
2015-03-11 09:11:36 -04:00
private IBase myInstance;
2014-02-18 08:26:49 -05:00
2015-03-11 09:11:36 -04:00
public ElementCompositeState(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IBase theInstance) {
super(thePreResourceState);
2014-02-19 11:59:12 -05:00
myDefinition = theDef;
2014-02-18 08:26:49 -05:00
myInstance = theInstance;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("id".equals(theName)) {
2014-07-04 09:27:36 -04:00
if (myInstance instanceof IIdentifiableElement) {
((IIdentifiableElement) myInstance).setElementSpecificId((theValue));
2015-02-16 11:33:46 -05:00
} else if (myInstance instanceof IBaseElement) {
((IBaseElement) myInstance).setId(theValue);
2014-12-10 17:40:47 -05:00
} else if (myInstance instanceof IBaseResource) {
2014-12-10 22:02:31 -05:00
new IdDt(theValue).applyTo((IBaseResource) myInstance);
2014-07-04 09:27:36 -04:00
}
2014-05-28 16:07:53 -04:00
} else if ("url".equals(theName) && myInstance instanceof ExtensionDt) {
2014-07-04 09:27:36 -04:00
((ExtensionDt) myInstance).setUrl(theValue);
}
}
2014-02-27 07:39:36 -05:00
@SuppressWarnings("unchecked")
2014-02-18 08:26:49 -05:00
@Override
public void endingElement() {
2014-02-21 21:06:11 -05:00
pop();
if (myState == null) {
2014-02-27 07:39:36 -05:00
myObject = (T) myInstance;
2014-02-21 21:06:11 -05:00
}
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespace, String theChildName) throws DataFormatException {
2014-03-28 17:11:56 -04:00
BaseRuntimeChildDefinition child;
try {
child = myDefinition.getChildByNameOrThrowDataFormatException(theChildName);
} catch (DataFormatException e) {
if (false) {// TODO: make this configurable
throw e;
}
ourLog.warn(e.getMessage());
push(new SwallowChildrenWholeState(getPreResourceState()));
return;
}
2014-02-19 11:59:12 -05:00
BaseRuntimeElementDefinition<?> target = child.getChildByName(theChildName);
2014-02-26 09:03:43 -05:00
if (target == null) {
throw new DataFormatException("Found unexpected element '" + theChildName + "' in parent element '" + myDefinition.getName() + "'. Valid names are: " + child.getValidChildNames());
}
2014-02-26 17:13:49 -05:00
2014-02-19 11:59:12 -05:00
switch (target.getChildType()) {
case COMPOSITE_DATATYPE: {
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
2015-02-16 11:33:46 -05:00
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance(child.getInstanceConstructorArguments());
2014-02-19 11:59:12 -05:00
child.getMutator().addValue(myInstance, newChildInstance);
2015-03-11 09:11:36 -04:00
ParserState<T>.ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
2014-02-19 11:59:12 -05:00
push(newState);
2014-02-20 12:13:05 -05:00
return;
2014-02-19 11:59:12 -05:00
}
2015-04-13 08:32:49 -04:00
case ID_DATATYPE:
2014-02-19 11:59:12 -05:00
case PRIMITIVE_DATATYPE: {
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
2014-12-10 22:02:31 -05:00
IPrimitiveType<?> newChildInstance;
newChildInstance = primitiveTarget.newInstance(child.getInstanceConstructorArguments());
2014-02-19 11:59:12 -05:00
child.getMutator().addValue(myInstance, newChildInstance);
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
2014-02-19 11:59:12 -05:00
push(newState);
2014-02-20 12:13:05 -05:00
return;
2014-02-19 11:59:12 -05:00
}
2014-02-19 17:33:46 -05:00
case RESOURCE_REF: {
2015-02-16 11:33:46 -05:00
IBase newChildInstance = newResourceReferenceDt(getPreResourceState().myInstance);
2014-02-19 17:33:46 -05:00
child.getMutator().addValue(myInstance, newChildInstance);
2015-02-16 11:33:46 -05:00
BaseState newState = createResourceReferenceState(getPreResourceState(), newChildInstance);
2014-02-19 17:33:46 -05:00
push(newState);
2014-02-20 12:13:05 -05:00
return;
}
case RESOURCE_BLOCK: {
RuntimeResourceBlockDefinition blockTarget = (RuntimeResourceBlockDefinition) target;
2015-02-16 11:33:46 -05:00
IBase newBlockInstance = blockTarget.newInstance();
2014-02-20 12:13:05 -05:00
child.getMutator().addValue(myInstance, newBlockInstance);
2015-03-11 09:11:36 -04:00
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), blockTarget, newBlockInstance);
2014-02-20 12:13:05 -05:00
push(newState);
return;
2014-02-19 11:59:12 -05:00
}
2014-02-22 15:33:02 -05:00
case PRIMITIVE_XHTML: {
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
XhtmlDt newDt = xhtmlTarget.newInstance();
child.getMutator().addValue(myInstance, newDt);
XhtmlState state = new XhtmlState(getPreResourceState(), newDt, true);
2014-02-22 15:33:02 -05:00
push(state);
return;
}
2015-04-13 08:32:49 -04:00
case PRIMITIVE_XHTML_HL7ORG: {
RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition xhtmlTarget = (RuntimePrimitiveDatatypeXhtmlHl7OrgDefinition) target;
IBaseXhtml newDt = xhtmlTarget.newInstance();
child.getMutator().addValue(myInstance, newDt);
XhtmlStateHl7Org state = new XhtmlStateHl7Org(getPreResourceState(), newDt);
push(state);
return;
}
2014-03-17 08:57:57 -04:00
case CONTAINED_RESOURCES: {
2014-12-10 22:02:31 -05:00
List<? extends IBase> values = child.getAccessor().getValues(myInstance);
2015-02-16 11:33:46 -05:00
Object newDt;
2014-03-22 12:33:07 -04:00
if (values == null || values.isEmpty() || values.get(0) == null) {
2015-02-16 11:33:46 -05:00
newDt = newContainedDt((IResource) getPreResourceState().myInstance);
child.getMutator().addValue(myInstance, (IBase) newDt);
2014-04-14 08:40:30 -04:00
} else {
2015-02-16 11:33:46 -05:00
newDt = values.get(0);
2014-03-22 12:33:07 -04:00
}
2015-02-16 11:33:46 -05:00
ContainedResourcesStateHapi state = new ContainedResourcesStateHapi(getPreResourceState());
push(state);
return;
}
2015-04-13 08:32:49 -04:00
case CONTAINED_RESOURCE_LIST: {
ContainedResourcesStateHl7Org state = new ContainedResourcesStateHl7Org(getPreResourceState());
push(state);
return;
}
2015-02-16 11:33:46 -05:00
case RESOURCE: {
if (myInstance instanceof IResource || myInstance instanceof IElement) {
ParserState<T>.PreResourceStateHapi state = new PreResourceStateHapi(myInstance, child.getMutator(), null);
push(state);
} else {
ParserState<T>.PreResourceStateHl7Org state = new PreResourceStateHl7Org(myInstance, child.getMutator(), null);
push(state);
}
2014-03-17 08:57:57 -04:00
return;
}
2014-02-22 15:33:02 -05:00
case UNDECL_EXT:
2014-07-04 09:27:36 -04:00
case EXTENSION_DECLARED: {
2014-02-20 12:13:05 -05:00
// Throw an exception because this shouldn't happen here
break;
2014-02-19 11:59:12 -05:00
}
2014-02-22 15:33:02 -05:00
}
throw new DataFormatException("Illegal resource position: " + target.getChildType());
}
@Override
2014-03-10 18:17:30 -04:00
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
2014-02-26 17:13:49 -05:00
RuntimeChildDeclaredExtensionDefinition declaredExtension = myDefinition.getDeclaredExtension(theUrlAttr);
if (declaredExtension != null) {
BaseState newState = new DeclaredExtensionState(getPreResourceState(), declaredExtension, myInstance);
2014-02-26 17:13:49 -05:00
push(newState);
} else {
2014-03-10 18:17:30 -04:00
super.enteringNewElementExtension(theElement, theUrlAttr, theIsModifier);
2014-02-26 17:13:49 -05:00
}
2014-02-22 15:33:02 -05:00
}
2014-02-19 11:59:12 -05:00
2014-02-22 15:33:02 -05:00
@Override
2015-03-11 09:11:36 -04:00
protected IBase getCurrentElement() {
2014-02-22 15:33:02 -05:00
return myInstance;
}
}
private class ExtensionState extends BaseState {
private IBaseExtension<?> myExtension;
2014-02-22 15:33:02 -05:00
public ExtensionState(PreResourceState thePreResourceState, IBaseExtension<?> theExtension) {
super(thePreResourceState);
2014-02-22 15:33:02 -05:00
myExtension = theExtension;
}
@Override
public void endingElement() throws DataFormatException {
if (myExtension.getValue() != null && myExtension.getExtension().size() > 0) {
2014-02-22 15:33:02 -05:00
throw new DataFormatException("Extension must not have both a value and other contained extensions");
2014-02-18 18:10:50 -05:00
}
2014-02-22 15:33:02 -05:00
pop();
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-02-22 15:33:02 -05:00
BaseRuntimeElementDefinition<?> target = myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(theLocalPart);
if (target == null) {
throw new DataFormatException("Unknown extension element name: " + theLocalPart);
2014-02-21 21:06:11 -05:00
}
2014-02-22 15:33:02 -05:00
switch (target.getChildType()) {
case COMPOSITE_DATATYPE: {
BaseRuntimeElementCompositeDefinition<?> compositeTarget = (BaseRuntimeElementCompositeDefinition<?>) target;
2015-04-20 07:31:45 -04:00
ICompositeType newChildInstance = (ICompositeType) compositeTarget.newInstance();
2014-02-22 15:33:02 -05:00
myExtension.setValue(newChildInstance);
2015-03-11 09:11:36 -04:00
ElementCompositeState newState = new ElementCompositeState(getPreResourceState(), compositeTarget, newChildInstance);
2014-02-22 15:33:02 -05:00
push(newState);
return;
}
case PRIMITIVE_DATATYPE: {
RuntimePrimitiveDatatypeDefinition primitiveTarget = (RuntimePrimitiveDatatypeDefinition) target;
2014-12-10 22:02:31 -05:00
IPrimitiveType<?> newChildInstance = primitiveTarget.newInstance();
myExtension.setValue(newChildInstance);
PrimitiveState newState = new PrimitiveState(getPreResourceState(), newChildInstance);
2014-02-22 15:33:02 -05:00
push(newState);
return;
}
case RESOURCE_REF: {
2015-04-13 08:32:49 -04:00
ICompositeType newChildInstance = (ICompositeType) newResourceReferenceDt(getPreResourceState().myInstance);
2014-02-22 15:33:02 -05:00
myExtension.setValue(newChildInstance);
2015-04-13 08:32:49 -04:00
if (myContext.getVersion().getVersion().equals(FhirVersionEnum.DSTU2_HL7ORG)) {
2015-05-01 12:27:56 -07:00
ParserState<T>.ResourceReferenceStateHl7Org newState = new ResourceReferenceStateHl7Org(getPreResourceState(), (IBaseReference) newChildInstance);
2015-04-13 08:32:49 -04:00
push(newState);
} else {
ResourceReferenceStateHapi newState = new ResourceReferenceStateHapi(getPreResourceState(), (BaseResourceReferenceDt) newChildInstance);
push(newState);
}
2014-02-22 15:33:02 -05:00
return;
}
case PRIMITIVE_XHTML:
case RESOURCE:
case RESOURCE_BLOCK:
case UNDECL_EXT:
case EXTENSION_DECLARED:
case CONTAINED_RESOURCES:
2015-04-20 07:31:45 -04:00
case CONTAINED_RESOURCE_LIST:
case ID_DATATYPE:
case PRIMITIVE_XHTML_HL7ORG:
2014-02-22 15:33:02 -05:00
break;
}
}
2014-02-26 17:13:49 -05:00
@Override
protected IBaseExtension<?> getCurrentElement() {
2014-02-26 17:13:49 -05:00
return myExtension;
}
}
2015-03-11 09:11:36 -04:00
private class SecurityLabelElementStateHapi extends ElementCompositeState {
2015-04-09 07:25:09 -06:00
public SecurityLabelElementStateHapi(ParserState<T>.PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, BaseCodingDt codingDt) {
super(thePreResourceState, theDef, codingDt);
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
}
2014-12-01 08:13:32 -05:00
private class MetaElementState extends BaseState {
private ResourceMetadataMap myMap;
2014-02-27 16:51:43 -05:00
2014-12-01 08:13:32 -05:00
public MetaElementState(ParserState<T>.PreResourceState thePreResourceState, ResourceMetadataMap theMap) {
super(thePreResourceState);
myMap = theMap;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (theLocalPart.equals("versionId")) {
push(new MetaVersionElementState(getPreResourceState(), myMap));
// } else if (theLocalPart.equals("profile")) {
//
2014-12-01 08:13:32 -05:00
} else if (theLocalPart.equals("lastUpdated")) {
InstantDt updated = new InstantDt();
push(new PrimitiveState(getPreResourceState(), updated));
myMap.put(ResourceMetadataKeyEnum.UPDATED, updated);
} else if (theLocalPart.equals("security")) {
@SuppressWarnings("unchecked")
List<BaseCodingDt> securityLabels = (List<BaseCodingDt>) myMap.get(ResourceMetadataKeyEnum.SECURITY_LABELS);
if (securityLabels == null) {
securityLabels = new ArrayList<BaseCodingDt>();
myMap.put(ResourceMetadataKeyEnum.SECURITY_LABELS, securityLabels);
}
2015-04-09 07:25:09 -06:00
BaseCodingDt securityLabel = myContext.getVersion().newCodingDt();
BaseRuntimeElementCompositeDefinition<?> codinfDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(securityLabel.getClass());
push(new SecurityLabelElementStateHapi(getPreResourceState(), codinfDef, securityLabel));
securityLabels.add(securityLabel);
} else if (theLocalPart.equals("profile")) {
@SuppressWarnings("unchecked")
List<IdDt> profiles = (List<IdDt>) myMap.get(ResourceMetadataKeyEnum.PROFILES);
if (profiles == null) {
profiles = new ArrayList<IdDt>();
myMap.put(ResourceMetadataKeyEnum.PROFILES, profiles);
}
IdDt profile = new IdDt();
push(new PrimitiveState(getPreResourceState(), profile));
profiles.add(profile);
} else if (theLocalPart.equals("tag")) {
TagList tagList = (TagList) myMap.get(ResourceMetadataKeyEnum.TAG_LIST);
if (tagList == null) {
tagList = new TagList();
myMap.put(ResourceMetadataKeyEnum.TAG_LIST, tagList);
}
push(new TagState(tagList));
2014-12-01 08:13:32 -05:00
} else {
throw new DataFormatException("Unexpected element '" + theLocalPart + "' found in 'meta' element");
}
}
}
private class MetaVersionElementState extends BaseState {
private ResourceMetadataMap myMap;
public MetaVersionElementState(ParserState<T>.PreResourceState thePreResourceState, ResourceMetadataMap theMap) {
super(thePreResourceState);
myMap = theMap;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
myMap.put(ResourceMetadataKeyEnum.VERSION, theValue);
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new DataFormatException("Unexpected child element '" + theLocalPart + "' in element 'meta'");
}
}
private class PreAtomState extends BasePreAtomOrBundleState {
2014-02-26 17:13:49 -05:00
2014-12-10 17:40:47 -05:00
public PreAtomState(Class<? extends IBaseResource> theResourceType) {
2014-12-01 08:13:32 -05:00
super(theResourceType);
}
2014-02-26 17:13:49 -05:00
@Override
public void endingElement() throws DataFormatException {
2014-02-26 17:13:49 -05:00
// ignore
}
2014-02-27 16:51:43 -05:00
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (!"feed".equals(theLocalPart)) {
throw new DataFormatException("Expecting outer element called 'feed', found: " + theLocalPart);
}
2014-12-01 08:13:32 -05:00
setInstance(new Bundle());
push(new AtomState(getInstance(), getResourceType()));
2014-02-27 16:51:43 -05:00
}
2014-12-01 08:13:32 -05:00
}
private class PreBundleState extends BasePreAtomOrBundleState {
public PreBundleState(Class<? extends IBaseResource> theResourceType) {
2014-12-01 08:13:32 -05:00
super(theResourceType);
2014-02-27 16:51:43 -05:00
}
@Override
2014-12-01 08:13:32 -05:00
public void endingElement() throws DataFormatException {
// ignore
}
2014-12-01 08:13:32 -05:00
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (!"Bundle".equals(theLocalPart)) {
throw new DataFormatException("Expecting outer element called 'Bundle', found: " + theLocalPart);
}
2014-12-01 08:13:32 -05:00
setInstance(new Bundle());
push(new BundleState(getInstance(), getResourceType()));
2014-02-27 16:51:43 -05:00
}
}
2014-03-22 12:33:07 -04:00
2015-02-16 11:33:46 -05:00
private class PreResourceStateHapi extends PreResourceState {
private BundleEntry myEntry;
private Object myTarget;
private IMutator myMutator;
2015-02-16 11:33:46 -05:00
public PreResourceStateHapi(BundleEntry theEntry, Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
myEntry = theEntry;
}
public PreResourceStateHapi(Object theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
myTarget = theTarget;
myMutator = theMutator;
}
2015-02-16 11:33:46 -05:00
public PreResourceStateHapi(Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
}
@SuppressWarnings("unchecked")
@Override
public void wereBack() {
super.wereBack();
if (myEntry == null && myMutator == null) {
2015-02-16 11:33:46 -05:00
myObject = (T) getCurrentElement();
}
2015-02-16 23:02:50 -05:00
IResource nextResource = (IResource) getCurrentElement();
String version = ResourceMetadataKeyEnum.VERSION.get(nextResource);
String resourceName = myContext.getResourceDefinition(nextResource).getName();
String bundleIdPart = nextResource.getId().getIdPart();
if (isNotBlank(bundleIdPart)) {
// if (isNotBlank(entryBaseUrl)) {
// nextResource.setId(new IdDt(entryBaseUrl, resourceName, bundleIdPart, version));
// } else {
nextResource.setId(new IdDt(null, resourceName, bundleIdPart, version));
// }
2015-02-16 23:02:50 -05:00
}
2015-02-16 11:33:46 -05:00
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
super.enteringNewElement(theNamespaceURI, theLocalPart);
if (myEntry != null) {
myEntry.setResource((IResource) getCurrentElement());
}
if (myMutator != null) {
myMutator.addValue(myTarget, getCurrentElement());
}
2015-02-16 11:33:46 -05:00
}
}
private class PreResourceStateHl7Org extends PreResourceState {
private IMutator myMutator;
private Object myTarget;
public PreResourceStateHl7Org(Object theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
myMutator = theMutator;
myTarget = theTarget;
}
public PreResourceStateHl7Org(Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
}
@SuppressWarnings("unchecked")
@Override
public void wereBack() {
super.wereBack();
if (myTarget == null) {
myObject = (T) getCurrentElement();
}
2015-04-20 07:31:45 -04:00
if (getCurrentElement() instanceof IDomainResource) {
IDomainResource elem = (IDomainResource) getCurrentElement();
String resourceName = myContext.getResourceDefinition(elem).getName();
String versionId = elem.getMeta().getVersionId();
2015-05-01 11:09:29 -04:00
if (StringUtils.isBlank(elem.getId().getIdPart())) {
// Resource has no ID
2015-05-01 11:09:29 -04:00
} else if (StringUtils.isNotBlank(versionId)) {
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart() + "/_history/" + versionId);
2015-04-20 07:31:45 -04:00
} else {
elem.getIdElement().setValue(resourceName + "/" + elem.getId().getIdPart());
}
}
}
2015-02-16 11:33:46 -05:00
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
super.enteringNewElement(theNamespaceURI, theLocalPart);
if (myMutator != null) {
myMutator.addValue(myTarget, getCurrentElement());
}
}
}
private abstract class PreResourceState extends BaseState {
2014-02-27 16:51:43 -05:00
2014-12-10 17:40:47 -05:00
private Map<String, IBaseResource> myContainedResources = new HashMap<String, IBaseResource>();
2015-02-16 11:33:46 -05:00
private IBaseResource myInstance;
private FhirVersionEnum myParentVersion;
2014-12-10 17:40:47 -05:00
private Class<? extends IBaseResource> myResourceType;
2014-02-27 16:51:43 -05:00
2015-02-16 11:33:46 -05:00
public PreResourceState(Class<? extends IBaseResource> theResourceType) {
super(null);
myResourceType = theResourceType;
if (theResourceType != null) {
myParentVersion = myContext.getResourceDefinition(theResourceType).getStructureVersion();
} else {
myParentVersion = myContext.getVersion().getVersion();
}
}
public PreResourceState(PreResourceState thePreResourcesState, FhirVersionEnum theParentVersion) {
super(thePreResourcesState);
Validate.notNull(theParentVersion);
myParentVersion = theParentVersion;
2014-02-27 16:51:43 -05:00
}
2014-02-26 17:13:49 -05:00
@Override
public void endingElement() throws DataFormatException {
2014-02-27 16:51:43 -05:00
pop();
2014-02-26 17:13:49 -05:00
}
2014-07-04 09:27:36 -04:00
2014-02-26 17:13:49 -05:00
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-03-07 16:23:49 -05:00
BaseRuntimeElementDefinition<?> definition;
if (myResourceType == null) {
definition = myContext.getResourceDefinition(myParentVersion, theLocalPart);
2014-08-27 08:55:00 -04:00
if ((definition == null)) {
throw new DataFormatException("Element '" + theLocalPart + "' is not a known resource type, expected a resource at this position");
2014-03-07 16:23:49 -05:00
}
} else {
definition = myContext.getResourceDefinition(myResourceType);
if (!StringUtils.equals(theLocalPart, definition.getName())) {
2014-06-23 09:04:48 -04:00
definition = myContext.getResourceDefinition(theLocalPart);
if (!(definition instanceof RuntimeResourceDefinition)) {
throw new DataFormatException("Element '" + theLocalPart + "' is not a resource, expected a resource at this position");
}
2014-03-07 16:23:49 -05:00
}
2014-02-26 17:13:49 -05:00
}
RuntimeResourceDefinition def = (RuntimeResourceDefinition) definition;
2015-02-16 11:33:46 -05:00
myInstance = def.newInstance();
2014-02-26 17:13:49 -05:00
2014-12-01 08:13:32 -05:00
String resourceName = def.getName();
2014-12-18 08:21:07 -05:00
if ("Binary".equals(resourceName) && myContext.getVersion().getVersion() == FhirVersionEnum.DSTU1) {
2015-03-04 08:44:31 -05:00
push(new BinaryResourceStateForDstu1(getRootPreResourceState(), (IBaseBinary) myInstance));
2015-02-16 11:33:46 -05:00
} else if (myInstance instanceof IResource) {
push(new ResourceStateHapi(getRootPreResourceState(), def, (IResource) myInstance));
2014-05-28 07:30:40 -04:00
} else {
2015-02-16 11:33:46 -05:00
push(new ResourceStateHl7Org(getRootPreResourceState(), def, myInstance));
2014-05-28 07:30:40 -04:00
}
}
2014-12-10 17:40:47 -05:00
public Map<String, IBaseResource> getContainedResources() {
return myContainedResources;
}
@Override
2014-12-10 17:40:47 -05:00
protected IBaseResource getCurrentElement() {
return myInstance;
}
private PreResourceState getRootPreResourceState() {
if (getPreResourceState() != null) {
return getPreResourceState();
2014-07-04 09:27:36 -04:00
} else {
return this;
}
}
@Override
public boolean isPreResource() {
return true;
}
2014-02-22 15:33:02 -05:00
@Override
2014-02-27 16:51:43 -05:00
public void wereBack() {
final boolean bundle = "Bundle".equals(myContext.getResourceDefinition(myInstance).getName());
FhirTerser terser = myContext.newTerser();
terser.visit(myInstance, new IModelVisitor() {
2014-08-27 08:55:00 -04:00
@Override
public void acceptElement(IBase theElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
if (theElement instanceof BaseResourceReferenceDt) {
BaseResourceReferenceDt nextRef = (BaseResourceReferenceDt) theElement;
String ref = nextRef.getReference().getValue();
if (isNotBlank(ref)) {
if (ref.startsWith("#")) {
2014-12-10 22:02:31 -05:00
IResource target = (IResource) myContainedResources.get(ref.substring(1));
if (target != null) {
nextRef.setResource(target);
} else {
ourLog.warn("Resource contains unknown local ref: " + ref);
}
}
}
2015-05-01 12:27:56 -07:00
}else if (theElement instanceof IBaseReference) {
IBaseReference nextRef = (IBaseReference) theElement;
2015-04-13 08:32:49 -04:00
String ref = nextRef.getReference().getValue();
if (isNotBlank(ref)) {
if (ref.startsWith("#")) {
IBaseResource target = myContainedResources.get(ref.substring(1));
if (target != null) {
nextRef.setResource(target);
} else {
ourLog.warn("Resource contains unknown local ref: " + ref);
}
}
}
}
}
2014-12-01 08:13:32 -05:00
@Override
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, List<String> thePathToElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
acceptElement(theNextExt.getValue(), null, null, null);
2014-12-01 08:13:32 -05:00
}
});
2014-08-27 08:55:00 -04:00
if (bundle) {
/*
* Stitch together resource references
*/
Map<IdDt, IResource> idToResource = new HashMap<IdDt, IResource>();
FhirTerser t = myContext.newTerser();
List<IResource> resources = t.getAllPopulatedChildElementsOfType(myInstance, IResource.class);
for (IResource next : resources) {
IdDt id = next.getId();
if (id != null && id.isEmpty() == false) {
String resName = myContext.getResourceDefinition(next).getName();
idToResource.put(id.withResourceType(resName).toUnqualifiedVersionless(), next);
}
}
for (IResource next : resources) {
List<BaseResourceReferenceDt> refs = myContext.newTerser().getAllPopulatedChildElementsOfType(next, BaseResourceReferenceDt.class);
for (BaseResourceReferenceDt nextRef : refs) {
if (nextRef.isEmpty() == false && nextRef.getReference() != null) {
IResource target = idToResource.get(nextRef.getReference().toUnqualifiedVersionless());
if (target != null) {
nextRef.setResource(target);
}
}
}
}
}
2014-02-26 17:13:49 -05:00
}
2014-02-18 08:26:49 -05:00
}
private class PreTagListState extends BaseState {
private TagList myTagList;
public PreTagListState() {
super(null);
myTagList = new TagList();
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (!TagList.ELEMENT_NAME_LC.equals(theLocalPart.toLowerCase())) {
throw new DataFormatException("resourceType does not appear to be 'TagList', found: " + theLocalPart);
}
push(new TagListState(myTagList));
}
@Override
protected IBase getCurrentElement() {
return myTagList;
}
@Override
public boolean isPreResource() {
return true;
}
@SuppressWarnings("unchecked")
@Override
public void wereBack() {
myObject = (T) myTagList;
}
}
2014-02-19 11:59:12 -05:00
private class PrimitiveState extends BaseState {
2014-12-10 22:02:31 -05:00
private IPrimitiveType<?> myInstance;
2014-02-19 11:59:12 -05:00
2014-12-10 22:02:31 -05:00
public PrimitiveState(PreResourceState thePreResourceState, IPrimitiveType<?> theInstance) {
super(thePreResourceState);
2014-02-19 11:59:12 -05:00
myInstance = theInstance;
}
@Override
2014-02-27 16:51:43 -05:00
public void attributeValue(String theName, String theValue) throws DataFormatException {
if ("value".equals(theName)) {
myInstance.setValueAsString(theValue);
2014-03-22 12:33:07 -04:00
} else if ("id".equals(theName)) {
2014-07-04 09:27:36 -04:00
if (myInstance instanceof IIdentifiableElement) {
((IIdentifiableElement) myInstance).setElementSpecificId(theValue);
2015-02-16 11:33:46 -05:00
} else if (myInstance instanceof IBaseElement) {
((IBaseElement) myInstance).setId(theValue);
2014-12-10 17:40:47 -05:00
} else if (myInstance instanceof IBaseResource) {
2014-12-10 22:02:31 -05:00
new IdDt(theValue).applyTo((org.hl7.fhir.instance.model.IBaseResource) myInstance);
2014-07-04 09:27:36 -04:00
}
2014-02-27 16:51:43 -05:00
}
2014-02-19 11:59:12 -05:00
}
@Override
public void endingElement() {
2014-02-21 21:06:11 -05:00
pop();
2014-02-19 11:59:12 -05:00
}
2014-03-06 17:12:05 -05:00
// @Override
// public void enteringNewElementExtension(StartElement theElement,
// String theUrlAttr) {
2014-03-06 17:12:05 -05:00
// if (myInstance instanceof ISupportsUndeclaredExtensions) {
// UndeclaredExtension ext = new UndeclaredExtension(theUrlAttr);
// ((ISupportsUndeclaredExtensions)
// myInstance).getUndeclaredExtensions().add(ext);
2014-03-06 17:12:05 -05:00
// push(new ExtensionState(ext));
// }
// }
2014-02-28 13:27:35 -05:00
2014-02-19 11:59:12 -05:00
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-12-21 18:13:37 -05:00
if (false) {// TODO: make this configurable
throw new Error("Element " + theLocalPart + " in primitive!"); // TODO:
}
ourLog.warn("Ignoring element {} in primitive tag", theLocalPart);
push(new SwallowChildrenWholeState(getPreResourceState()));
return;
2014-02-19 11:59:12 -05:00
}
2014-02-22 15:33:02 -05:00
@Override
2014-12-10 22:02:31 -05:00
protected IBase getCurrentElement() {
2014-02-26 17:13:49 -05:00
return myInstance;
2014-02-22 15:33:02 -05:00
}
2014-02-19 11:59:12 -05:00
}
2015-02-16 11:33:46 -05:00
private class ResourceReferenceStateHl7Org extends BaseState {
2015-05-01 12:27:56 -07:00
private IBaseReference myInstance;
2015-02-16 11:33:46 -05:00
private ResourceReferenceSubState mySubState;
2015-05-01 12:27:56 -07:00
public ResourceReferenceStateHl7Org(PreResourceState thePreResourceState, IBaseReference theInstance) {
2015-02-16 11:33:46 -05:00
super(thePreResourceState);
myInstance = theInstance;
mySubState = ResourceReferenceSubState.INITIAL;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if (!"value".equals(theName)) {
return;
}
switch (mySubState) {
case DISPLAY:
myInstance.setDisplay(theValue);
break;
case INITIAL:
throw new DataFormatException("Unexpected attribute: " + theValue);
case REFERENCE:
myInstance.setReference(theValue);
break;
}
}
@Override
public void endingElement() {
switch (mySubState) {
case INITIAL:
pop();
break;
case DISPLAY:
case REFERENCE:
mySubState = ResourceReferenceSubState.INITIAL;
}
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
switch (mySubState) {
case INITIAL:
if ("display".equals(theLocalPart)) {
mySubState = ResourceReferenceSubState.DISPLAY;
break;
} else if ("reference".equals(theLocalPart)) {
mySubState = ResourceReferenceSubState.REFERENCE;
break;
} else if ("resource".equals(theLocalPart)) {
mySubState = ResourceReferenceSubState.REFERENCE;
break;
}
//$FALL-THROUGH$
case DISPLAY:
case REFERENCE:
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
}
@Override
2015-05-01 12:27:56 -07:00
protected IBaseReference getCurrentElement() {
2015-02-16 11:33:46 -05:00
return myInstance;
}
}
private class ResourceReferenceStateHapi extends BaseState {
2014-02-21 21:06:11 -05:00
private BaseResourceReferenceDt myInstance;
2014-02-21 21:06:11 -05:00
private ResourceReferenceSubState mySubState;
2015-02-16 11:33:46 -05:00
public ResourceReferenceStateHapi(PreResourceState thePreResourceState, BaseResourceReferenceDt theInstance) {
super(thePreResourceState);
2014-02-21 21:06:11 -05:00
myInstance = theInstance;
mySubState = ResourceReferenceSubState.INITIAL;
}
@Override
2014-02-27 16:51:43 -05:00
public void attributeValue(String theName, String theValue) throws DataFormatException {
if (!"value".equals(theName)) {
return;
}
2014-03-06 17:12:05 -05:00
2014-02-21 21:06:11 -05:00
switch (mySubState) {
case DISPLAY:
myInstance.getDisplayElement().setValue(theValue);
2014-02-21 21:06:11 -05:00
break;
case INITIAL:
throw new DataFormatException("Unexpected attribute: " + theValue);
case REFERENCE:
myInstance.getReference().setValue(theValue);
2014-02-21 21:06:11 -05:00
break;
}
}
@Override
public void endingElement() {
2014-02-21 21:06:11 -05:00
switch (mySubState) {
case INITIAL:
pop();
break;
case DISPLAY:
case REFERENCE:
mySubState = ResourceReferenceSubState.INITIAL;
}
}
@Override
2014-02-27 11:57:50 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-02-21 21:06:11 -05:00
switch (mySubState) {
case INITIAL:
if ("display".equals(theLocalPart)) {
mySubState = ResourceReferenceSubState.DISPLAY;
break;
} else if ("reference".equals(theLocalPart)) {
mySubState = ResourceReferenceSubState.REFERENCE;
break;
2014-03-22 12:33:07 -04:00
} else if ("resource".equals(theLocalPart)) {
mySubState = ResourceReferenceSubState.REFERENCE;
break;
2014-02-21 21:06:11 -05:00
}
//$FALL-THROUGH$
case DISPLAY:
case REFERENCE:
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
}
2014-02-22 15:33:02 -05:00
@Override
2014-02-26 17:13:49 -05:00
protected IElement getCurrentElement() {
return myInstance;
2014-02-22 15:33:02 -05:00
}
2014-02-18 08:26:49 -05:00
}
2014-02-19 11:59:12 -05:00
2014-02-21 21:06:11 -05:00
private enum ResourceReferenceSubState {
DISPLAY, INITIAL, REFERENCE
2014-02-19 11:59:12 -05:00
}
2015-03-11 09:11:36 -04:00
private class ResourceStateHapi extends ElementCompositeState {
private IResource myInstance;
2015-02-16 11:33:46 -05:00
public ResourceStateHapi(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IResource theInstance) {
super(thePreResourceState, theDef, theInstance);
2015-03-11 09:11:36 -04:00
myInstance = theInstance;
}
@Override
public void enteringNewElement(String theNamespace, String theChildName) throws DataFormatException {
if ("id".equals(theChildName)) {
2015-03-11 09:11:36 -04:00
push(new PrimitiveState(getPreResourceState(), myInstance.getId()));
} else if ("meta".equals(theChildName)) {
2015-03-11 09:11:36 -04:00
push(new MetaElementState(getPreResourceState(), myInstance.getResourceMetadata()));
} else {
super.enteringNewElement(theNamespace, theChildName);
}
}
}
2015-03-11 09:11:36 -04:00
private class ResourceStateHl7Org extends ElementCompositeState {
2015-02-16 11:33:46 -05:00
public ResourceStateHl7Org(PreResourceState thePreResourceState, BaseRuntimeElementCompositeDefinition<?> theDef, IBaseResource theInstance) {
super(thePreResourceState, theDef, theInstance);
}
}
private class SwallowChildrenWholeState extends BaseState {
private int myDepth;
public SwallowChildrenWholeState(PreResourceState thePreResourceState) {
super(thePreResourceState);
}
@Override
public void endingElement() throws DataFormatException {
myDepth--;
if (myDepth < 0) {
pop();
}
}
2014-10-24 15:43:35 -04:00
@Override
2014-12-01 08:13:32 -05:00
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
2014-10-24 15:43:35 -04:00
myDepth++;
}
@Override
2014-12-01 08:13:32 -05:00
public void enteringNewElementExtension(StartElement theElement, String theUrlAttr, boolean theIsModifier) {
myDepth++;
}
}
private class TagListState extends BaseState {
private TagList myTagList;
public TagListState(TagList theTagList) {
super(null);
myTagList = theTagList;
}
@Override
public void endingElement() throws DataFormatException {
pop();
}
@Override
protected IBase getCurrentElement() {
return myTagList;
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (TagList.ATTR_CATEGORY.equals(theLocalPart)) {
push(new TagState(myTagList));
} else {
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
}
}
private class TagState extends BaseState {
private static final int LABEL = 2;
private static final int NONE = 0;
private static final int SCHEME = 3;
private static final int TERM = 1;
private String myLabel;
private String myScheme;
private int mySubState = 0;
private TagList myTagList;
private String myTerm;
public TagState(TagList theTagList) {
super(null);
myTagList = theTagList;
}
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
String value = defaultIfBlank(theValue, null);
switch (mySubState) {
case TERM:
myTerm = (value);
break;
case LABEL:
myLabel = (value);
break;
case SCHEME:
myScheme = (value);
break;
case NONE:
// This handles JSON encoding, which is a bit weird
enteringNewElement(null, theName);
attributeValue(null, value);
endingElement();
break;
}
}
@Override
public void endingElement() throws DataFormatException {
if (mySubState != NONE) {
mySubState = NONE;
} else {
if (isNotEmpty(myScheme) || isNotBlank(myTerm) || isNotBlank(myLabel)) {
myTagList.addTag(myScheme, myTerm, myLabel);
}
pop();
}
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
/*
* We allow for both the DSTU1 and DSTU2 names here
*/
if (Tag.ATTR_TERM.equals(theLocalPart) || "code".equals(theLocalPart)) {
mySubState = TERM;
} else if (Tag.ATTR_SCHEME.equals(theLocalPart) || "system".equals(theLocalPart)) {
mySubState = SCHEME;
} else if (Tag.ATTR_LABEL.equals(theLocalPart) || "display".equals(theLocalPart)) {
mySubState = LABEL;
} else {
throw new DataFormatException("Unexpected element: " + theLocalPart);
}
}
}
2015-04-13 08:32:49 -04:00
private class XhtmlStateHl7Org extends XhtmlState {
private IBaseXhtml myHl7OrgDatatype;
private XhtmlStateHl7Org(PreResourceState thePreResourceState, IBaseXhtml theHl7OrgDatatype) {
super(thePreResourceState, new XhtmlDt(), true);
myHl7OrgDatatype = theHl7OrgDatatype;
}
@Override
public void doPop() {
// TODO: this is not very efficient
String value = getDt().getValueAsString();
myHl7OrgDatatype.setValueAsString(value);
2015-04-13 08:32:49 -04:00
super.doPop();
}
2015-04-13 08:32:49 -04:00
}
2014-02-21 21:06:11 -05:00
private class XhtmlState extends BaseState {
2014-02-22 15:33:02 -05:00
private int myDepth;
private XhtmlDt myDt;
private List<XMLEvent> myEvents = new ArrayList<XMLEvent>();
2014-02-27 16:51:43 -05:00
private boolean myIncludeOuterEvent;
2014-02-22 15:33:02 -05:00
private XhtmlState(PreResourceState thePreResourceState, XhtmlDt theXhtmlDt, boolean theIncludeOuterEvent) throws DataFormatException {
super(thePreResourceState);
2014-02-27 16:51:43 -05:00
myDepth = 0;
2014-02-22 15:33:02 -05:00
myDt = theXhtmlDt;
2014-02-27 16:51:43 -05:00
myIncludeOuterEvent = theIncludeOuterEvent;
2014-02-21 21:06:11 -05:00
}
2015-04-13 08:32:49 -04:00
public XhtmlDt getDt() {
return myDt;
}
2014-03-22 12:33:07 -04:00
@Override
public void attributeValue(String theName, String theValue) throws DataFormatException {
if (myJsonMode) {
myDt.setValueAsString(theValue);
return;
}
super.attributeValue(theName, theValue);
}
2015-04-13 08:32:49 -04:00
protected void doPop() {
pop();
}
2014-03-22 12:33:07 -04:00
@Override
public void endingElement() throws DataFormatException {
2014-03-22 12:33:07 -04:00
if (myJsonMode) {
2015-04-13 08:32:49 -04:00
doPop();
2014-03-22 12:33:07 -04:00
return;
}
super.endingElement();
2014-03-22 12:33:07 -04:00
}
@Override
protected IElement getCurrentElement() {
return myDt;
}
2014-02-21 21:06:11 -05:00
@Override
2014-02-27 11:57:50 -05:00
public void xmlEvent(XMLEvent theEvent) {
2014-02-27 16:51:43 -05:00
if (theEvent.isEndElement()) {
myDepth--;
}
if (myIncludeOuterEvent || myDepth > 0) {
myEvents.add(theEvent);
}
2014-02-22 15:33:02 -05:00
2014-02-27 11:57:50 -05:00
if (theEvent.isStartElement()) {
myDepth++;
}
2014-03-06 17:12:05 -05:00
2014-02-27 11:57:50 -05:00
if (theEvent.isEndElement()) {
if (myDepth == 0) {
myDt.setValue(myEvents);
2015-04-13 08:32:49 -04:00
doPop();
2014-02-27 11:57:50 -05:00
}
2014-02-21 21:06:11 -05:00
}
}
2014-02-19 11:59:12 -05:00
}
2014-02-18 08:26:49 -05:00
}