More Atom parsing work

This commit is contained in:
jamesagnew 2014-02-27 11:57:50 -05:00
parent b92cc66804
commit bec9a51351
5 changed files with 204 additions and 167 deletions

View File

@ -9,7 +9,7 @@ import ca.uhn.fhir.model.primitive.StringDt;
public class Bundle implements IElement { public class Bundle implements IElement {
private StringDt myAuthorDevice; private StringDt myAuthorUri;
private StringDt myAuthorName; private StringDt myAuthorName;
private List<BundleEntry> myEntries; private List<BundleEntry> myEntries;
private StringDt myId; private StringDt myId;
@ -24,11 +24,11 @@ public class Bundle implements IElement {
private IntegerDt myTotalResults; private IntegerDt myTotalResults;
private InstantDt myUpdated; private InstantDt myUpdated;
public StringDt getAuthorDevice() { public StringDt getAuthorUri() {
if (myAuthorDevice == null) { if (myAuthorUri == null) {
myAuthorDevice = new StringDt(); myAuthorUri = new StringDt();
} }
return myAuthorDevice; return myAuthorUri;
} }
public StringDt getAuthorName() { public StringDt getAuthorName() {

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.model.api; package ca.uhn.fhir.model.api;
import org.apache.commons.lang3.StringUtils;
public class ResourceReference implements IElement { public class ResourceReference implements IElement {
@ -22,4 +24,8 @@ public class ResourceReference implements IElement {
myReference = theReference; myReference = theReference;
} }
public boolean hasContent() {
return StringUtils.isNotBlank(myDisplay) || StringUtils.isNotBlank(myReference);
}
} }

View File

@ -83,4 +83,8 @@ public class XhtmlDt implements IPrimitiveDatatype<List<XMLEvent>> {
myValue = theValue; myValue = theValue;
} }
public boolean hasContent() {
return myValue != null && myValue.size() > 0;
}
} }

View File

@ -9,6 +9,8 @@ import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement; import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent; import javax.xml.stream.events.XMLEvent;
import org.apache.commons.lang3.StringUtils;
import com.ctc.wstx.sw.BaseStreamWriter; import com.ctc.wstx.sw.BaseStreamWriter;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition; import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
@ -36,6 +38,34 @@ import ca.uhn.fhir.model.primitive.XhtmlDt;
class ParserState<T extends IElement> { class ParserState<T extends IElement> {
public class AtomAuthorState extends BaseState {
private Bundle myInstance;
public AtomAuthorState(Bundle theInstance) {
myInstance = theInstance;
}
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
}
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
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);
}
}
}
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class);
private FhirContext myContext; private FhirContext myContext;
@ -54,8 +84,8 @@ class ParserState<T extends IElement> {
myState.endingElement(theElem); myState.endingElement(theElem);
} }
public void enteringNewElement(StartElement theElement, String theName) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theName) throws DataFormatException {
myState.enteringNewElement(theElement, theName); myState.enteringNewElement(theNamespaceURI, theName);
} }
public void enteringNewElementExtension(StartElement theElem, String theUrlAttr) { public void enteringNewElementExtension(StartElement theElem, String theUrlAttr) {
@ -70,10 +100,6 @@ class ParserState<T extends IElement> {
return myObject != null; return myObject != null;
} }
public void otherEvent(XMLEvent theEvent) throws DataFormatException {
myState.otherEvent(theEvent);
}
private void pop() { private void pop() {
myState = myState.myStack; myState = myState.myStack;
myState.wereBack(); myState.wereBack();
@ -105,10 +131,6 @@ class ParserState<T extends IElement> {
myPrimitive = thePrimitive; myPrimitive = thePrimitive;
} }
@Override
public void attributeValue(Attribute theAttribute, String theValue) throws DataFormatException {
// ignore
}
@Override @Override
public void endingElement(EndElement theElem) throws DataFormatException { public void endingElement(EndElement theElem) throws DataFormatException {
@ -117,7 +139,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new DataFormatException("Unexpected nested element in atom tag "); throw new DataFormatException("Unexpected nested element in atom tag ");
} }
@ -127,49 +149,65 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException { public void string(String theData) {
if (theEvent.isCharacters()) { if (myData == null) {
String data = theEvent.asCharacters().getData(); myData = theData;
if (myData == null) { } else {
myData = data; // this shouldn't generally happen so it's ok that it's inefficient
} else { myData = myData + theData;
// this shouldn't generally happen so it's ok that it's inefficient
myData = myData + data;
}
} }
} }
} }
private class ExpectEndElementState extends BaseState { private class AtomLinkState extends BaseState {
private String myRel;
private String myHref;
private Bundle myInstance;
public AtomLinkState(Bundle theInstance) {
myInstance = theInstance;
}
@Override @Override
public void attributeValue(Attribute theAttribute, String theValue) throws DataFormatException { public void attributeValue(Attribute theAttribute, String theValue) throws DataFormatException {
throw new DataFormatException("Found unexpected element content"); String name = theAttribute.getName().getLocalPart();
if ("rel".equals(name)) {
myRel = theValue;
} else if ("href".equals(name)) {
myHref = theValue;
}
} }
@Override @Override
public void endingElement(EndElement theElem) throws DataFormatException { public void endingElement(EndElement theElem) throws DataFormatException {
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);
}
pop(); pop();
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new DataFormatException("Found unexpected element content"); throw new DataFormatException("Found unexpected element content");
} }
@Override
protected IElement getCurrentElement() {
return null;
}
@Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException {
throw new DataFormatException("Found unexpected element content");
}
} }
private static final QName ATOM_LINK_REL_ATTRIBUTE = new QName("rel"); private static final QName ATOM_LINK_REL_ATTRIBUTE = new QName("rel");
private static final QName ATOM_LINK_HREF_ATTRIBUTE = new QName("href"); private static final QName ATOM_LINK_HREF_ATTRIBUTE = new QName("href");
@ -193,36 +231,22 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (theLocalPart.equals("title")) { if (theLocalPart.equals("title")) {
push(new AtomPrimitiveState(myInstance.getTitle())); push(new AtomPrimitiveState(myInstance.getTitle()));
} else if ("id".equals(theLocalPart)) { } else if ("id".equals(theLocalPart)) {
push(new AtomPrimitiveState(myInstance.getId())); push(new AtomPrimitiveState(myInstance.getId()));
} else if ("link".equals(theLocalPart)) { } else if ("link".equals(theLocalPart)) {
Attribute rel = theElement.getAttributeByName(ATOM_LINK_REL_ATTRIBUTE); push(new AtomLinkState(myInstance));
Attribute href = theElement.getAttributeByName(ATOM_LINK_HREF_ATTRIBUTE); } else if ("totalresults".equals(theLocalPart) && verifyNamespace(XmlParser.OPENSEARCH_NS, theNamespaceURI)) {
if (rel != null && href != null) { push(new AtomPrimitiveState(myInstance.getTotalResults()));
if ("self".equals(rel.getValue())) { } else if ("updated".equals(theLocalPart)) {
myInstance.getLinkSelf().setValueAsString(href.getValue()); push(new AtomPrimitiveState(myInstance.getUpdated()));
push(new ExpectEndElementState()); } else if ("author".equals(theLocalPart)) {
} else if ("first".equals(rel.getValue())) { push(new AtomAuthorState(myInstance));
myInstance.getLinkFirst().setValueAsString(href.getValue()); }
push(new ExpectEndElementState());
} else if ("previous".equals(rel.getValue())) { // TODO: handle category and DSig
myInstance.getLinkPrevious().setValueAsString(href.getValue());
push(new ExpectEndElementState());
} else if ("next".equals(rel.getValue())) {
myInstance.getLinkNext().setValueAsString(href.getValue());
push(new ExpectEndElementState());
} else if ("last".equals(rel.getValue())) {
myInstance.getLinkLast().setValueAsString(href.getValue());
push(new ExpectEndElementState());
} else if ("fhir-base".equals(rel.getValue())) {
myInstance.getLinkBase().setValueAsString(href.getValue());
push(new ExpectEndElementState());
}
}
}
} }
@Override @Override
@ -230,11 +254,6 @@ class ParserState<T extends IElement> {
return myInstance; return myInstance;
} }
@Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException {
// ignore
}
} }
private class PreAtomState extends BaseState { private class PreAtomState extends BaseState {
@ -252,7 +271,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
if (!"feed".equals(theLocalPart)) { if (!"feed".equals(theLocalPart)) {
throw new DataFormatException("Expecting outer element called 'feed', found: " + theLocalPart); throw new DataFormatException("Expecting outer element called 'feed', found: " + theLocalPart);
} }
@ -274,22 +293,26 @@ class ParserState<T extends IElement> {
myObject = (T) myInstance; myObject = (T) myInstance;
} }
@Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException {
// ignore
}
} }
private abstract class BaseState { private abstract class BaseState {
private BaseState myStack; private BaseState myStack;
public abstract void attributeValue(Attribute theAttribute, String theValue) throws DataFormatException; @SuppressWarnings("unused")
public void attributeValue(Attribute theAttribute, String theValue) throws DataFormatException {
// ignore by default
}
public abstract void endingElement(EndElement theElem) throws DataFormatException; @SuppressWarnings("unused")
public void endingElement(EndElement theElem) throws DataFormatException {
// ignore by default
}
public abstract void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException; @SuppressWarnings("unused")
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
// ignore by default
}
/** /**
* Default implementation just handles undeclared extensions * Default implementation just handles undeclared extensions
@ -305,9 +328,9 @@ class ParserState<T extends IElement> {
} }
} }
protected abstract IElement getCurrentElement(); protected IElement getCurrentElement() {
return null;
public abstract void otherEvent(XMLEvent theEvent) throws DataFormatException; }
public void setStack(BaseState theState) { public void setStack(BaseState theState) {
myStack = theState; myStack = theState;
@ -317,6 +340,14 @@ class ParserState<T extends IElement> {
// allow an implementor to override // allow an implementor to override
} }
public void string(@SuppressWarnings("unused") String theData) {
// ignore by default
}
public void xmlEvent(@SuppressWarnings("unused") XMLEvent theNextEvent) {
// ignore
}
} }
private class DeclaredExtensionState extends BaseState { private class DeclaredExtensionState extends BaseState {
@ -341,7 +372,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
BaseRuntimeElementDefinition<?> target = myDefinition.getChildByName(theLocalPart); BaseRuntimeElementDefinition<?> target = myDefinition.getChildByName(theLocalPart);
if (target == null) { if (target == null) {
throw new DataFormatException("Unknown extension element name: " + theLocalPart); throw new DataFormatException("Unknown extension element name: " + theLocalPart);
@ -402,11 +433,6 @@ class ParserState<T extends IElement> {
return myParentInstance; return myParentInstance;
} }
@Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException {
// ignore
}
} }
private class ElementCompositeState extends BaseState { private class ElementCompositeState extends BaseState {
@ -434,7 +460,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theChildName) throws DataFormatException { public void enteringNewElement(String theNamespace, String theChildName) throws DataFormatException {
BaseRuntimeChildDefinition child = myDefinition.getChildByNameOrThrowDataFormatException(theChildName); BaseRuntimeChildDefinition child = myDefinition.getChildByNameOrThrowDataFormatException(theChildName);
BaseRuntimeElementDefinition<?> target = child.getChildByName(theChildName); BaseRuntimeElementDefinition<?> target = child.getChildByName(theChildName);
if (target == null) { if (target == null) {
@ -478,7 +504,7 @@ class ParserState<T extends IElement> {
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target; RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
XhtmlDt newDt = xhtmlTarget.newInstance(); XhtmlDt newDt = xhtmlTarget.newInstance();
child.getMutator().addValue(myInstance, newDt); child.getMutator().addValue(myInstance, newDt);
XhtmlState state = new XhtmlState(newDt, theElement); XhtmlState state = new XhtmlState(newDt);
push(state); push(state);
return; return;
} }
@ -508,11 +534,6 @@ class ParserState<T extends IElement> {
return myInstance; return myInstance;
} }
@Override
public void otherEvent(XMLEvent theEvent) {
// ignore
}
} }
private class ExtensionState extends BaseState { private class ExtensionState extends BaseState {
@ -537,7 +558,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
BaseRuntimeElementDefinition<?> target = myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(theLocalPart); BaseRuntimeElementDefinition<?> target = myContext.getRuntimeChildUndeclaredExtensionDefinition().getChildByName(theLocalPart);
if (target == null) { if (target == null) {
throw new DataFormatException("Unknown extension element name: " + theLocalPart); throw new DataFormatException("Unknown extension element name: " + theLocalPart);
@ -581,11 +602,6 @@ class ParserState<T extends IElement> {
return myExtension; return myExtension;
} }
@Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException {
// ignore
}
} }
private class PreResourceState extends BaseState { private class PreResourceState extends BaseState {
@ -603,7 +619,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
BaseRuntimeElementDefinition<?> definition = myContext.getNameToResourceDefinition().get(theLocalPart); BaseRuntimeElementDefinition<?> definition = myContext.getNameToResourceDefinition().get(theLocalPart);
if (!(definition instanceof RuntimeResourceDefinition)) { if (!(definition instanceof RuntimeResourceDefinition)) {
throw new DataFormatException("Element '" + theLocalPart + "' is not a resource, expected a resource at this position"); throw new DataFormatException("Element '" + theLocalPart + "' is not a resource, expected a resource at this position");
@ -620,11 +636,6 @@ class ParserState<T extends IElement> {
return myInstance; return myInstance;
} }
@Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException {
// ignore
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public void wereBack() { public void wereBack() {
@ -652,7 +663,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElement, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
throw new Error("?? can this happen?"); // TODO: can this happen? throw new Error("?? can this happen?"); // TODO: can this happen?
} }
@ -661,11 +672,6 @@ class ParserState<T extends IElement> {
return myInstance; return myInstance;
} }
@Override
public void otherEvent(XMLEvent theEvent) {
// ignore
}
} }
private class ResourceReferenceState extends BaseState { private class ResourceReferenceState extends BaseState {
@ -707,7 +713,7 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void enteringNewElement(StartElement theElem, String theLocalPart) throws DataFormatException { public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
switch (mySubState) { switch (mySubState) {
case INITIAL: case INITIAL:
if ("display".equals(theLocalPart)) { if ("display".equals(theLocalPart)) {
@ -729,11 +735,6 @@ class ParserState<T extends IElement> {
return myInstance; return myInstance;
} }
@Override
public void otherEvent(XMLEvent theEvent) {
// ignore
}
} }
private enum ResourceReferenceSubState { private enum ResourceReferenceSubState {
@ -745,32 +746,9 @@ class ParserState<T extends IElement> {
private XhtmlDt myDt; private XhtmlDt myDt;
private List<XMLEvent> myEvents = new ArrayList<XMLEvent>(); private List<XMLEvent> myEvents = new ArrayList<XMLEvent>();
private XhtmlState(XhtmlDt theXhtmlDt, StartElement theXhtmlStartElement) throws DataFormatException { private XhtmlState(XhtmlDt theXhtmlDt) throws DataFormatException {
myDepth = 1; myDepth = 1;
myDt = theXhtmlDt; myDt = theXhtmlDt;
myEvents.add(theXhtmlStartElement);
}
@Override
public void attributeValue(Attribute theAttr, String theValue) throws DataFormatException {
myEvents.add(theAttr);
}
@Override
public void endingElement(EndElement theElement) throws DataFormatException {
myEvents.add(theElement);
myDepth--;
if (myDepth == 0) {
myDt.setValue(myEvents);
pop();
}
}
@Override
public void enteringNewElement(StartElement theElem, String theLocalPart) throws DataFormatException {
myDepth++;
myEvents.add(theElem);
} }
@Override @Override
@ -779,9 +757,36 @@ class ParserState<T extends IElement> {
} }
@Override @Override
public void otherEvent(XMLEvent theEvent) throws DataFormatException { public void xmlEvent(XMLEvent theEvent) {
myEvents.add(theEvent); myEvents.add(theEvent);
if (theEvent.isStartElement()) {
myDepth++;
}
if (theEvent.isEndElement()) {
myDepth--;
if (myDepth == 0) {
myDt.setValue(myEvents);
pop();
}
}
} }
}
public void string(String theData) {
myState.string(theData);
}
public boolean verifyNamespace(String theExpect, String theActual) {
return StringUtils.equals(theExpect, theActual);
}
/**
* Invoked after any new XML event is individually processed, containing a copy of the XML event. This is basically intended for embedded XHTML content
*/
public void xmlEvent(XMLEvent theNextEvent) {
myState.xmlEvent(theNextEvent);
} }
} }

View File

@ -49,12 +49,12 @@ import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.util.PrettyPrintWriterWrapper; import ca.uhn.fhir.util.PrettyPrintWriterWrapper;
public class XmlParser { public class XmlParser {
private static final String ATOM_NS = "http://www.w3.org/2005/Atom"; static final String ATOM_NS = "http://www.w3.org/2005/Atom";
private static final String FHIR_NS = "http://hl7.org/fhir"; static final String FHIR_NS = "http://hl7.org/fhir";
private static final String OPENSEARCH_NS = "http://a9.com/-/spec/opensearch/1.1/"; static final String OPENSEARCH_NS = "http://a9.com/-/spec/opensearch/1.1/";
@SuppressWarnings("unused") @SuppressWarnings("unused")
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParser.class); private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParser.class);
private static final String XHTML_NS = "http://www.w3.org/1999/xhtml"; static final String XHTML_NS = "http://www.w3.org/1999/xhtml";
// private static final Set<String> RESOURCE_NAMESPACES; // private static final Set<String> RESOURCE_NAMESPACES;
@ -106,7 +106,7 @@ public class XmlParser {
if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) { if (StringUtils.isNotBlank(theBundle.getAuthorName().getValue())) {
eventWriter.writeStartElement("author"); eventWriter.writeStartElement("author");
writeTagWithTextNode(eventWriter, "name", theBundle.getAuthorName()); writeTagWithTextNode(eventWriter, "name", theBundle.getAuthorName());
writeOptionalTagWithTextNode(eventWriter, "device", theBundle.getAuthorDevice()); writeOptionalTagWithTextNode(eventWriter, "uri", theBundle.getAuthorUri());
} }
for (BundleEntry nextEntry : theBundle.getEntries()) { for (BundleEntry nextEntry : theBundle.getEntries()) {
@ -131,15 +131,21 @@ public class XmlParser {
return stringWriter.toString(); return stringWriter.toString();
} }
private void encodeChildElementToStreamWriter(XMLStreamWriter theEventWriter, IElement nextValue, String childName, BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl) throws XMLStreamException, DataFormatException { private boolean encodeChildElementToStreamWriter(XMLStreamWriter theEventWriter, IElement nextValue, String childName, BaseRuntimeElementDefinition<?> childDef, String theExtensionUrl)
throws XMLStreamException, DataFormatException {
switch (childDef.getChildType()) { switch (childDef.getChildType()) {
case PRIMITIVE_DATATYPE: { case PRIMITIVE_DATATYPE: {
theEventWriter.writeStartElement(childName);
IPrimitiveDatatype<?> pd = (IPrimitiveDatatype<?>) nextValue; IPrimitiveDatatype<?> pd = (IPrimitiveDatatype<?>) nextValue;
theEventWriter.writeAttribute("value", pd.getValueAsString()); String value = pd.getValueAsString();
encodeExtensionsIfPresent(theEventWriter, nextValue); if (value != null) {
theEventWriter.writeEndElement(); theEventWriter.writeStartElement(childName);
break; theEventWriter.writeAttribute("value", value);
encodeExtensionsIfPresent(theEventWriter, nextValue);
theEventWriter.writeEndElement();
return true;
} else {
return false;
}
} }
case RESOURCE_BLOCK: case RESOURCE_BLOCK:
case COMPOSITE_DATATYPE: { case COMPOSITE_DATATYPE: {
@ -151,30 +157,41 @@ public class XmlParser {
encodeCompositeElementToStreamWriter(nextValue, theEventWriter, childCompositeDef); encodeCompositeElementToStreamWriter(nextValue, theEventWriter, childCompositeDef);
encodeExtensionsIfPresent(theEventWriter, nextValue); encodeExtensionsIfPresent(theEventWriter, nextValue);
theEventWriter.writeEndElement(); theEventWriter.writeEndElement();
break; return true;
} }
case RESOURCE_REF: { case RESOURCE_REF: {
theEventWriter.writeStartElement(childName);
ResourceReference ref = (ResourceReference) nextValue; ResourceReference ref = (ResourceReference) nextValue;
encodeResourceReferenceToStreamWriter(theEventWriter, ref); if (ref.hasContent()) {
theEventWriter.writeEndElement(); theEventWriter.writeStartElement(childName);
break; encodeResourceReferenceToStreamWriter(theEventWriter, ref);
theEventWriter.writeEndElement();
return true;
} else {
return false;
}
} }
case RESOURCE: { case RESOURCE: {
throw new IllegalStateException(); // should not happen throw new IllegalStateException(); // should not happen
} }
case PRIMITIVE_XHTML: { case PRIMITIVE_XHTML: {
XhtmlDt dt = (XhtmlDt) nextValue; XhtmlDt dt = (XhtmlDt) nextValue;
encodeXhtml(dt, theEventWriter); if (dt.hasContent()) {
break; encodeXhtml(dt, theEventWriter);
return true;
} else {
return false;
}
} }
case UNDECL_EXT: { case UNDECL_EXT: {
throw new IllegalStateException("should not happen"); throw new IllegalStateException("should not happen");
} }
} }
return false;
} }
private void encodeCompositeElementChildrenToStreamWriter(IElement theElement, XMLStreamWriter theEventWriter, List<? extends BaseRuntimeChildDefinition> children) throws XMLStreamException, DataFormatException { private void encodeCompositeElementChildrenToStreamWriter(IElement theElement, XMLStreamWriter theEventWriter, List<? extends BaseRuntimeChildDefinition> children) throws XMLStreamException,
DataFormatException {
for (BaseRuntimeChildDefinition nextChild : children) { for (BaseRuntimeChildDefinition nextChild : children) {
List<? extends IElement> values = nextChild.getAccessor().getValues(theElement); List<? extends IElement> values = nextChild.getAccessor().getValues(theElement);
if (values == null || values.isEmpty()) { if (values == null || values.isEmpty()) {
@ -205,15 +222,18 @@ public class XmlParser {
} }
} }
private void encodeCompositeElementToStreamWriter(IElement theElement, XMLStreamWriter theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef) throws XMLStreamException, DataFormatException { private void encodeCompositeElementToStreamWriter(IElement theElement, XMLStreamWriter theEventWriter, BaseRuntimeElementCompositeDefinition<?> resDef) throws XMLStreamException,
DataFormatException {
encodeExtensionsIfPresent(theEventWriter, theElement); encodeExtensionsIfPresent(theEventWriter, theElement);
encodeCompositeElementChildrenToStreamWriter(theElement, theEventWriter, resDef.getExtensions()); encodeCompositeElementChildrenToStreamWriter(theElement, theEventWriter, resDef.getExtensions());
encodeCompositeElementChildrenToStreamWriter(theElement, theEventWriter, resDef.getChildren()); encodeCompositeElementChildrenToStreamWriter(theElement, theEventWriter, resDef.getChildren());
} }
private void encodeExtensionsIfPresent(XMLStreamWriter theWriter, IElement theResource) throws XMLStreamException, DataFormatException { private void encodeExtensionsIfPresent(XMLStreamWriter theWriter, IElement theResource) throws XMLStreamException, DataFormatException {
boolean retVal = false;
if (theResource instanceof ISupportsUndeclaredExtensions) { if (theResource instanceof ISupportsUndeclaredExtensions) {
for (UndeclaredExtension next : ((ISupportsUndeclaredExtensions) theResource).getUndeclaredExtensions()) { for (UndeclaredExtension next : ((ISupportsUndeclaredExtensions) theResource).getUndeclaredExtensions()) {
retVal =true;
theWriter.writeStartElement("extension"); theWriter.writeStartElement("extension");
theWriter.writeAttribute("url", next.getUrl()); theWriter.writeAttribute("url", next.getUrl());
@ -388,9 +408,6 @@ public class XmlParser {
StartElement elem = nextEvent.asStartElement(); StartElement elem = nextEvent.asStartElement();
String namespaceURI = elem.getName().getNamespaceURI(); String namespaceURI = elem.getName().getNamespaceURI();
if (!FHIR_NS.equals(namespaceURI) && !XHTML_NS.equals(namespaceURI)) {
continue;
}
if ("extension".equals(elem.getName().getLocalPart())) { if ("extension".equals(elem.getName().getLocalPart())) {
Attribute urlAttr = elem.getAttributeByName(new QName("url")); Attribute urlAttr = elem.getAttributeByName(new QName("url"));
@ -399,7 +416,10 @@ public class XmlParser {
} }
parserState.enteringNewElementExtension(elem, urlAttr.getValue()); parserState.enteringNewElementExtension(elem, urlAttr.getValue());
} else { } else {
parserState.enteringNewElement(elem, elem.getName().getLocalPart());
String elementName = elem.getName().getLocalPart();
parserState.enteringNewElement(namespaceURI, elementName);
} }
for (@SuppressWarnings("unchecked") for (@SuppressWarnings("unchecked")
@ -430,10 +450,12 @@ public class XmlParser {
if (parserState.isComplete()) { if (parserState.isComplete()) {
return parserState.getObject(); return parserState.getObject();
} }
} else { } else if (nextEvent.isCharacters()) {
parserState.otherEvent(nextEvent); parserState.string(nextEvent.asCharacters().getData());
} }
parserState.xmlEvent(nextEvent);
} }
return null; return null;