diff --git a/hapi-fhir-base/.classpath b/hapi-fhir-base/.classpath
index 42f0d694287..29fce1ef7fd 100644
--- a/hapi-fhir-base/.classpath
+++ b/hapi-fhir-base/.classpath
@@ -1,86 +1,69 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/hapi-fhir-base/.project b/hapi-fhir-base/.project
index 22f076c3eef..a75380b92e5 100644
--- a/hapi-fhir-base/.project
+++ b/hapi-fhir-base/.project
@@ -1,3 +1,4 @@
+
hapi-fhir-base
NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.
diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml
index caa552954f2..33091f7c6c0 100644
--- a/hapi-fhir-base/pom.xml
+++ b/hapi-fhir-base/pom.xml
@@ -61,7 +61,12 @@
org.apache.httpcomponents
httpclient
- 4.2.3
+ 4.3.3
+
+
+ org.apache.httpcomponents
+ httpcore
+ 4.3.2
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java
index 5bb849a77b2..fa8fa7c75a4 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/context/FhirContext.java
@@ -8,7 +8,9 @@ import java.util.Set;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource;
+import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.parser.XmlParser;
+import ca.uhn.fhir.rest.client.RestfulClientFactory;
public class FhirContext {
@@ -47,8 +49,12 @@ public class FhirContext {
return (RuntimeResourceDefinition) myClassToElementDefinition.get(theResource.getClass());
}
- public XmlParser newXmlParser() {
+ public IParser newXmlParser() {
return new XmlParser(this);
}
+
+ public RestfulClientFactory newClientFactory() {
+ return new RestfulClientFactory(this);
+ }
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/Bundle.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/Bundle.java
index ba294ad7f1e..c1ac1241b45 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/Bundle.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/Bundle.java
@@ -20,7 +20,16 @@ public class Bundle extends BaseBundle implements IElement {
private InstantDt myPublished;
private StringDt myTitle;
private IntegerDt myTotalResults;
- private InstantDt myUpdated;
+ private InstantDt myUpdated;
+
+ /**
+ * Adds and returns a new bundle entry
+ */
+ public BundleEntry addEntry() {
+ BundleEntry retVal = new BundleEntry();
+ getEntries().add(retVal);
+ return retVal;
+ }
public List getEntries() {
if (myEntries == null) {
@@ -87,25 +96,39 @@ public class Bundle extends BaseBundle implements IElement {
public StringDt getTitle() {
if (myTitle == null) {
- myTitle= new StringDt();
+ myTitle = new StringDt();
}
return myTitle;
}
public IntegerDt getTotalResults() {
- if (myTotalResults== null) {
- myTotalResults= new IntegerDt();
+ if (myTotalResults == null) {
+ myTotalResults = new IntegerDt();
}
return myTotalResults;
}
public InstantDt getUpdated() {
if (myUpdated == null) {
- myUpdated= new InstantDt();
+ myUpdated = new InstantDt();
}
return myUpdated;
}
-
+ public List toListOfResources() {
+ ArrayList retVal = new ArrayList();
+ for (BundleEntry next : getEntries()) {
+ if (next.getResource() != null) {
+ retVal.add(next.getResource());
+ }
+ }
+ return retVal;
+ }
+
+ public static Bundle withSingleResource(IResource theResource) {
+ Bundle retVal = new Bundle();
+ retVal.addEntry().setResource(theResource);
+ return retVal;
+ }
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleCategory.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleCategory.java
new file mode 100644
index 00000000000..1a1b3c03008
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleCategory.java
@@ -0,0 +1,33 @@
+package ca.uhn.fhir.model.api;
+
+public class BundleCategory {
+
+ private String myLabel;
+ private String myScheme;
+ private String myTerm;
+
+ public String getLabel() {
+ return myLabel;
+ }
+
+ public String getScheme() {
+ return myScheme;
+ }
+
+ public String getTerm() {
+ return myTerm;
+ }
+
+ public void setLabel(String theLabel) {
+ myLabel = theLabel;
+ }
+
+ public void setScheme(String theScheme) {
+ myScheme = theScheme;
+ }
+
+ public void setTerm(String theTerm) {
+ myTerm = theTerm;
+ }
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java
index 77c8d42967d..31c0c59f2ed 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java
@@ -1,5 +1,8 @@
package ca.uhn.fhir.model.api;
+import java.util.ArrayList;
+import java.util.List;
+
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
@@ -12,6 +15,7 @@ public class BundleEntry extends BaseBundle {
private StringDt myTitle;
private InstantDt myUpdated;
private XhtmlDt mySummary;
+ private List myCategories;
public StringDt getId() {
if (myId == null) {
@@ -70,4 +74,17 @@ public class BundleEntry extends BaseBundle {
return mySummary;
}
+ public BundleCategory addCategory() {
+ BundleCategory retVal = new BundleCategory();
+ getCategories().add(retVal);
+ return retVal;
+ }
+
+ public List getCategories() {
+ if (myCategories == null) {
+ myCategories = new ArrayList();
+ }
+ return myCategories;
+ }
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ICompositeDatatype.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ICompositeDatatype.java
index a23ffbeb211..85e67f4abf8 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ICompositeDatatype.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/ICompositeDatatype.java
@@ -1,6 +1,7 @@
package ca.uhn.fhir.model.api;
-public interface ICompositeDatatype extends IDatatype, ICompositeElement {
+public interface ICompositeDatatype extends IDatatype, ICompositeElement {
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IQueryParameterType.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IQueryParameterType.java
new file mode 100644
index 00000000000..54271e08021
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/IQueryParameterType.java
@@ -0,0 +1,26 @@
+package ca.uhn.fhir.model.api;
+
+public interface IQueryParameterType {
+
+ /**
+ * Sets the value of this type using the token format. This
+ * format is used in HTTP queries as a parameter format.
+ *
+ * @see See FHIR specification
+ * 2.2.2 Search Parameter Types
+ * for information on the token format
+ */
+ public void setValueAsQueryToken(String theParameter);
+
+ /**
+ * Returns the value of this type using the token format. This
+ * format is used in HTTP queries as a parameter format.
+ *
+ * @see See FHIR specification
+ * 2.2.2 Search Parameter Types
+ * for information on the token format
+ */
+ public String getValueAsQueryToken();
+
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/dstu/composite/IdentifierDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/dstu/composite/IdentifierDt.java
index f7dca33053d..e99bfe0315b 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/dstu/composite/IdentifierDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/dstu/composite/IdentifierDt.java
@@ -17,6 +17,7 @@
package ca.uhn.fhir.model.dstu.composite;
import java.util.*;
+
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.model.primitive.*;
@@ -38,7 +39,7 @@ import ca.uhn.fhir.model.dstu.resource.*;
*
*/
@DatatypeDef(name="Identifier")
-public class IdentifierDt extends BaseElement implements ICompositeDatatype {
+public class IdentifierDt extends BaseElement implements ICompositeDatatype, IQueryParameterType {
@Child(name="use", type=CodeDt.class, order=0, min=0, max=1)
private BoundCodeDt myUse;
@@ -61,6 +62,21 @@ public class IdentifierDt extends BaseElement implements ICompositeDatatype {
})
private ResourceReference myAssigner;
+ /**
+ * Creates a new identifier
+ */
+ public IdentifierDt() {
+ // nothing
+ }
+
+ /**
+ * Creates a new identifier with the given system and value
+ */
+ public IdentifierDt(String theSystem, String theValue) {
+ setSystem(theSystem);
+ setValue(theValue);
+ }
+
/**
* Gets the value(s) for use (usual | official | temp | secondary (If known)
).
@@ -303,13 +319,21 @@ public class IdentifierDt extends BaseElement implements ICompositeDatatype {
}
/**
- * Sets the value of this IdentifierDt
using the token format. This
- * format is used in HTTP queries as a parameter format.
- *
- * @see See FHIR specification
- * 2.2.2 Search Parameter Types
- * for information on the token format
+ * {@inheritDoc}
*/
+ @Override
+ public String getValueAsQueryToken() {
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(getSystem().getValueAsString())) {
+ return getSystem().getValueAsString() + '|' + getValue().getValueAsString();
+ } else {
+ return getValue().getValueAsString();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void setValueAsQueryToken(String theParameter) {
int barIndex = theParameter.indexOf('|');
if (barIndex != -1) {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/StringDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/StringDt.java
index 6c12b64a5e7..3b22b54545b 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/StringDt.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/StringDt.java
@@ -4,12 +4,13 @@ import org.apache.commons.lang3.StringUtils;
import ca.uhn.fhir.model.api.BaseElement;
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
+import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
import ca.uhn.fhir.model.api.annotation.SimpleSetter;
import ca.uhn.fhir.parser.DataFormatException;
@DatatypeDef(name = "string")
-public class StringDt extends BaseElement implements IPrimitiveDatatype {
+public class StringDt extends BaseElement implements IPrimitiveDatatype, IQueryParameterType {
private String myValue;
@@ -84,6 +85,22 @@ public class StringDt extends BaseElement implements IPrimitiveDatatype
return false;
return true;
}
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValueAsQueryToken(String theParameter) {
+ setValue(theParameter);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getValueAsQueryToken() {
+ return getValue();
+ }
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/IParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/IParser.java
new file mode 100644
index 00000000000..34e8043bbd7
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/IParser.java
@@ -0,0 +1,36 @@
+package ca.uhn.fhir.parser;
+
+import java.io.Reader;
+import java.io.Writer;
+
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.model.api.Bundle;
+import ca.uhn.fhir.model.api.IResource;
+
+public interface IParser {
+
+ String encodeBundleToString(Bundle theBundle) throws DataFormatException;
+
+ void encodeBundleToWriter(Bundle theBundle, Writer theWriter);
+
+ String encodeResourceToString(IResource theResource) throws DataFormatException;
+
+ void encodeResourceToWriter(IResource theResource, Writer stringWriter);
+
+ void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter eventWriter) throws XMLStreamException, DataFormatException;
+
+ Bundle parseBundle(Reader theReader);
+
+ Bundle parseBundle(String theXml) throws ConfigurationException, DataFormatException;
+
+ IResource parseResource(String theXml) throws ConfigurationException, DataFormatException;
+
+ IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException;
+
+ IResource parseResource(XMLEventReader theStreamReader);
+
+}
\ No newline at end of file
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java
index 77e41277adc..1d9517f9618 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/ParserState.java
@@ -15,7 +15,6 @@ import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeChildDeclaredExtensionDefinition;
-import ca.uhn.fhir.context.RuntimeChildPrimitiveBoundCodeDatatypeDefinition;
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeDefinition;
import ca.uhn.fhir.context.RuntimePrimitiveDatatypeNarrativeDefinition;
import ca.uhn.fhir.context.RuntimeResourceBlockDefinition;
@@ -23,6 +22,7 @@ import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeResourceReferenceDefinition;
import ca.uhn.fhir.model.api.BaseBundle;
import ca.uhn.fhir.model.api.Bundle;
+import ca.uhn.fhir.model.api.BundleCategory;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.ICompositeElement;
@@ -84,9 +84,7 @@ class ParserState {
}
/**
- * Invoked after any new XML event is individually processed, containing a
- * copy of the XML event. This is basically intended for embedded XHTML
- * content
+ * 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);
@@ -140,6 +138,37 @@ class ParserState {
}
+ public class AtomCategoryState extends BaseState {
+
+ private BundleCategory myInstance;
+
+ public AtomCategoryState(BundleCategory theEntry) {
+ myInstance = theEntry;
+ }
+
+ @Override
+ public void endingElement(EndElement theElem) throws DataFormatException {
+ pop();
+ }
+
+ @Override
+ public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
+ throw new DataFormatException("Unexpected element: " + theLocalPart);
+ }
+
+ @Override
+ public void attributeValue(String theName, String theValue) throws DataFormatException {
+ if ("term".equals(theName)) {
+ myInstance.setTerm(theValue);
+ } else if ("label".equals(theName)) {
+ myInstance.setLabel(theValue);
+ } else if ("scheme".equals(theName)) {
+ myInstance.setScheme(theValue);
+ }
+ }
+
+ }
+
public class AtomEntryState extends BaseState {
private BundleEntry myEntry;
@@ -171,7 +200,9 @@ class ParserState {
} else if ("content".equals(theLocalPart)) {
push(new PreResourceState(myEntry));
} else if ("summary".equals(theLocalPart)) {
- push(new XhtmlState(myEntry.getSummary(),false));
+ push(new XhtmlState(myEntry.getSummary(), false));
+ } else if ("category".equals(theLocalPart)) {
+ push(new AtomCategoryState(myEntry.addCategory()));
} else {
throw new DataFormatException("Unexpected element in entry: " + theLocalPart);
}
@@ -281,8 +312,6 @@ class ParserState {
myInstance = theInstance;
}
-
-
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
@@ -307,7 +336,7 @@ class ParserState {
} else if ("author".equals(theLocalPart)) {
push(new AtomAuthorState(myInstance));
} else {
- throw new DataFormatException("Unexpected element: "+ theLocalPart);
+ throw new DataFormatException("Unexpected element: " + theLocalPart);
}
// TODO: handle category and DSig
@@ -387,7 +416,6 @@ class ParserState {
myParentInstance = theParentInstance;
}
-
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
@@ -522,7 +550,7 @@ class ParserState {
RuntimePrimitiveDatatypeNarrativeDefinition xhtmlTarget = (RuntimePrimitiveDatatypeNarrativeDefinition) target;
XhtmlDt newDt = xhtmlTarget.newInstance();
child.getMutator().addValue(myInstance, newDt);
- XhtmlState state = new XhtmlState(newDt,true);
+ XhtmlState state = new XhtmlState(newDt, true);
push(state);
return;
}
@@ -562,7 +590,6 @@ class ParserState {
myExtension = theExtension;
}
-
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
if (myExtension.getValue() != null && myExtension.getUndeclaredExtensions().size() > 0) {
@@ -622,7 +649,6 @@ class ParserState {
private Bundle myInstance;
-
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
// ignore
@@ -666,7 +692,6 @@ class ParserState {
myEntry = theEntry;
}
-
@Override
public void endingElement(EndElement theElem) throws DataFormatException {
pop();
@@ -723,14 +748,14 @@ class ParserState {
pop();
}
-// @Override
-// public void enteringNewElementExtension(StartElement theElement, String theUrlAttr) {
-// if (myInstance instanceof ISupportsUndeclaredExtensions) {
-// UndeclaredExtension ext = new UndeclaredExtension(theUrlAttr);
-// ((ISupportsUndeclaredExtensions) myInstance).getUndeclaredExtensions().add(ext);
-// push(new ExtensionState(ext));
-// }
-// }
+ // @Override
+ // public void enteringNewElementExtension(StartElement theElement, String theUrlAttr) {
+ // if (myInstance instanceof ISupportsUndeclaredExtensions) {
+ // UndeclaredExtension ext = new UndeclaredExtension(theUrlAttr);
+ // ((ISupportsUndeclaredExtensions) myInstance).getUndeclaredExtensions().add(ext);
+ // push(new ExtensionState(ext));
+ // }
+ // }
@Override
public void enteringNewElement(String theNamespaceURI, String theLocalPart) throws DataFormatException {
@@ -761,7 +786,7 @@ class ParserState {
if (!"value".equals(theName)) {
return;
}
-
+
switch (mySubState) {
case DISPLAY:
myInstance.setDisplay(theValue);
@@ -840,7 +865,7 @@ class ParserState {
if (theEvent.isStartElement()) {
myDepth++;
}
-
+
if (theEvent.isEndElement()) {
if (myDepth == 0) {
myDt.setValue(myEvents);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
index a1ecec60309..1d31e5b7e8d 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/parser/XmlParser.java
@@ -3,6 +3,7 @@ package ca.uhn.fhir.parser;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
@@ -48,7 +49,7 @@ import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.util.PrettyPrintWriterWrapper;
-public class XmlParser {
+public class XmlParser implements IParser {
static final String ATOM_NS = "http://www.w3.org/2005/Atom";
static final String FHIR_NS = "http://hl7.org/fhir";
static final String OPENSEARCH_NS = "http://a9.com/-/spec/opensearch/1.1/";
@@ -139,6 +140,10 @@ public class XmlParser {
}
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#encodeBundleToString(ca.uhn.fhir.model.api.Bundle)
+ */
+ @Override
public String encodeBundleToString(Bundle theBundle) throws DataFormatException {
StringWriter stringWriter = new StringWriter();
encodeBundleToWriter(theBundle, stringWriter);
@@ -146,6 +151,10 @@ public class XmlParser {
return stringWriter.toString();
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#encodeBundleToWriter(ca.uhn.fhir.model.api.Bundle, java.io.Writer)
+ */
+ @Override
public void encodeBundleToWriter(Bundle theBundle, Writer theWriter) {
try {
XMLStreamWriter eventWriter;
@@ -336,12 +345,20 @@ public class XmlParser {
}
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#encodeResourceToString(ca.uhn.fhir.model.api.IResource)
+ */
+ @Override
public String encodeResourceToString(IResource theResource) throws DataFormatException {
Writer stringWriter = new StringWriter();
encodeResourceToWriter(theResource, stringWriter);
return stringWriter.toString();
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#encodeResourceToWriter(ca.uhn.fhir.model.api.IResource, java.io.Writer)
+ */
+ @Override
public void encodeResourceToWriter(IResource theResource, Writer stringWriter) {
XMLStreamWriter eventWriter;
try {
@@ -354,6 +371,10 @@ public class XmlParser {
}
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#encodeResourceToXmlStreamWriter(ca.uhn.fhir.model.api.IResource, javax.xml.stream.XMLStreamWriter)
+ */
+ @Override
public void encodeResourceToXmlStreamWriter(IResource theResource, XMLStreamWriter eventWriter) throws XMLStreamException, DataFormatException {
RuntimeResourceDefinition resDef = myContext.getResourceDefinition(theResource);
eventWriter.writeStartElement(resDef.getName());
@@ -411,13 +432,22 @@ public class XmlParser {
StartElement se = event.asStartElement();
if (firstEvent) {
theEventWriter.writeStartElement(se.getName().getLocalPart());
- theEventWriter.writeNamespace(se.getName().getPrefix(), se.getName().getNamespaceURI());
+ if (StringUtils.isBlank(se.getName().getPrefix())) {
+ theEventWriter.writeDefaultNamespace(se.getName().getNamespaceURI());
+ }else {
+ theEventWriter.writeNamespace(se.getName().getPrefix(), se.getName().getNamespaceURI());
+ }
} else {
if (isBlank(se.getName().getPrefix())) {
if (isBlank(se.getName().getNamespaceURI())) {
theEventWriter.writeStartElement(se.getName().getLocalPart());
} else {
+ if (StringUtils.isBlank(se.getName().getPrefix())) {
+ theEventWriter.writeStartElement(se.getName().getLocalPart());
+ theEventWriter.writeDefaultNamespace(se.getName().getNamespaceURI());
+ }else {
theEventWriter.writeStartElement(se.getName().getNamespaceURI(), se.getName().getLocalPart());
+ }
}
} else {
theEventWriter.writeStartElement(se.getName().getPrefix(), se.getName().getLocalPart(), se.getName().getNamespaceURI());
@@ -437,17 +467,13 @@ public class XmlParser {
}
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#parseBundle(java.lang.String)
+ */
+ @Override
public Bundle parseBundle(String theXml) throws ConfigurationException, DataFormatException {
- XMLEventReader streamReader;
- try {
- streamReader = myXmlInputFactory.createXMLEventReader(new StringReader(theXml));
- } catch (XMLStreamException e) {
- throw new DataFormatException(e);
- } catch (FactoryConfigurationError e) {
- throw new ConfigurationException("Failed to initialize STaX event factory", e);
- }
-
- return parseBundle(streamReader);
+ StringReader reader = new StringReader(theXml);
+ return parseBundle(reader);
}
private Bundle parseBundle(XMLEventReader theStreamReader) {
@@ -455,19 +481,19 @@ public class XmlParser {
return doXmlLoop(theStreamReader, parserState);
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#parseResource(java.lang.String)
+ */
+ @Override
public IResource parseResource(String theXml) throws ConfigurationException, DataFormatException {
- XMLEventReader streamReader;
- try {
- streamReader = myXmlInputFactory.createXMLEventReader(new StringReader(theXml));
- } catch (XMLStreamException e) {
- throw new DataFormatException(e);
- } catch (FactoryConfigurationError e) {
- throw new ConfigurationException("Failed to initialize STaX event factory", e);
- }
-
- return parseResource(streamReader);
+ StringReader reader = new StringReader(theXml);
+ return parseResource(reader);
}
+ /* (non-Javadoc)
+ * @see ca.uhn.fhir.parser.IParser#parseResource(javax.xml.stream.XMLEventReader)
+ */
+ @Override
public IResource parseResource(XMLEventReader theStreamReader) {
ParserState parserState = ParserState.getPreResourceInstance(myContext);
return doXmlLoop(theStreamReader, parserState);
@@ -504,4 +530,32 @@ public class XmlParser {
}
theEventWriter.writeEndElement();
}
+
+ @Override
+ public Bundle parseBundle(Reader theReader) {
+ XMLEventReader streamReader;
+ try {
+ streamReader = myXmlInputFactory.createXMLEventReader(theReader);
+ } catch (XMLStreamException e) {
+ throw new DataFormatException(e);
+ } catch (FactoryConfigurationError e) {
+ throw new ConfigurationException("Failed to initialize STaX event factory", e);
+ }
+
+ return parseBundle(streamReader);
+ }
+
+ @Override
+ public IResource parseResource(Reader theReader) throws ConfigurationException, DataFormatException {
+ XMLEventReader streamReader;
+ try {
+ streamReader = myXmlInputFactory.createXMLEventReader(theReader);
+ } catch (XMLStreamException e) {
+ throw new DataFormatException(e);
+ } catch (FactoryConfigurationError e) {
+ throw new ConfigurationException("Failed to initialize STaX event factory", e);
+ }
+
+ return parseResource(streamReader);
+ }
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/BaseClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/BaseClientInvocation.java
new file mode 100644
index 00000000000..6e0bfa8be17
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/BaseClientInvocation.java
@@ -0,0 +1,14 @@
+package ca.uhn.fhir.rest.client;
+
+import org.apache.http.client.methods.HttpRequestBase;
+
+public abstract class BaseClientInvocation {
+
+ /**
+ * Create an HTTP request out of this client request
+ *
+ * @param theUrlBase The FHIR server base url (with a trailing "/")
+ */
+ public abstract HttpRequestBase asHttpRequest(String theUrlBase);
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientInvocation.java
deleted file mode 100644
index b3c257c1757..00000000000
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientInvocation.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package ca.uhn.fhir.rest.client;
-
-public class ClientInvocation {
-
-}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientInvocationHandler.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientInvocationHandler.java
index 6793e99d446..74827a5630e 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientInvocationHandler.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/ClientInvocationHandler.java
@@ -1,35 +1,117 @@
package ca.uhn.fhir.rest.client;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringReader;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.nio.charset.Charset;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.http.entity.ContentType;
import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.model.api.Bundle;
+import ca.uhn.fhir.model.api.IResource;
+import ca.uhn.fhir.parser.IParser;
+import ca.uhn.fhir.rest.client.exceptions.InvalidResponseException;
+import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
import ca.uhn.fhir.rest.common.BaseMethodBinding;
+import ca.uhn.fhir.rest.server.Constants;
public class ClientInvocationHandler implements InvocationHandler {
- private HttpClient myClient;
- private Map myBindings = new HashMap();
- private FhirContext myContext;
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ClientInvocationHandler.class);
+ private final Map myBindings = new HashMap();
+ private final HttpClient myClient;
+ private final FhirContext myContext;
+ private final String myUrlBase;
- public ClientInvocationHandler(HttpClient theClient, FhirContext theContext) {
+ public ClientInvocationHandler(HttpClient theClient, FhirContext theContext, String theUrlBase) {
myClient = theClient;
myContext = theContext;
- }
-
- @Override
- public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
- BaseMethodBinding binding = myBindings.get(theMethod);
- ClientInvocation clientInvocation = binding.invokeClient(theArgs);
- return null;
+ myUrlBase = theUrlBase;
}
public void addBinding(Method theMethod, BaseMethodBinding theBinding) {
myBindings.put(theMethod, theBinding);
}
+ @Override
+ public Object invoke(Object theProxy, Method theMethod, Object[] theArgs) throws Throwable {
+ BaseMethodBinding binding = myBindings.get(theMethod);
+ GetClientInvocation clientInvocation = binding.invokeClient(theArgs);
+ HttpRequestBase httpRequest = clientInvocation.asHttpRequest(myUrlBase);
+ HttpResponse response = myClient.execute(httpRequest);
+
+ ContentType ct = ContentType.get(response.getEntity());
+ Charset charset = ct.getCharset();
+
+ if (charset == null) {
+ ourLog.warn("Response did not specify a charset.");
+ charset = Charset.forName("UTF-8");
+ }
+
+ Reader reader = new InputStreamReader(response.getEntity().getContent(), charset);
+
+ if (ourLog.isTraceEnabled()) {
+ String responseString = IOUtils.toString(reader);
+ ourLog.trace("FHIR response:\n{}\n{}", response, responseString);
+ reader = new StringReader(responseString);
+ }
+
+ IParser parser;
+ String mimeType = ct.getMimeType();
+ if (Constants.CT_ATOM_XML.equals(mimeType)) {
+ parser = myContext.newXmlParser();
+ } else if (Constants.CT_FHIR_XML.equals(mimeType)) {
+ parser = myContext.newXmlParser();
+ } else {
+ throw new NonFhirResponseException("Response contains non-FHIR content-type: " + mimeType, mimeType, response.getStatusLine().getStatusCode(), IOUtils.toString(reader));
+ }
+
+ switch (binding.getReturnType()) {
+ case BUNDLE: {
+ Bundle bundle = parser.parseBundle(reader);
+ switch (binding.getMethodReturnType()) {
+ case BUNDLE:
+ return bundle;
+ case LIST_OF_RESOURCES:
+ return bundle.toListOfResources();
+ case RESOURCE:
+ List list = bundle.toListOfResources();
+ if (list.size() == 0) {
+ return null;
+ } else if (list.size() == 1) {
+ return list.get(1);
+ } else {
+ throw new InvalidResponseException("FHIR server call returned a bundle with multiple resources, but this method is only able to returns one.");
+ }
+ }
+ break;
+ }
+ case RESOURCE: {
+ IResource resource = parser.parseResource(reader);
+ switch (binding.getMethodReturnType()) {
+ case BUNDLE:
+ return Bundle.withSingleResource(resource);
+ case LIST_OF_RESOURCES:
+ return Collections.singletonList(resource);
+ case RESOURCE:
+ return resource;
+ }
+ break;
+ }
+ }
+
+ throw new IllegalStateException("Should not get here!");
+ }
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GetClientInvocation.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GetClientInvocation.java
new file mode 100644
index 00000000000..da4874c6c32
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/GetClientInvocation.java
@@ -0,0 +1,41 @@
+package ca.uhn.fhir.rest.client;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpRequestBase;
+
+import ca.uhn.fhir.rest.common.BaseMethodBinding;
+
+public class GetClientInvocation extends BaseClientInvocation {
+
+ private final Map myParameters;
+ private final String myUrlPath;
+
+ public GetClientInvocation(Map theParameters, String... theUrlFragments) {
+ myParameters = theParameters;
+ myUrlPath = StringUtils.join(theUrlFragments, '/');
+ }
+
+ public GetClientInvocation(String... theUrlFragments) {
+ myParameters = Collections.emptyMap();
+ myUrlPath = StringUtils.join(theUrlFragments, '/');
+ }
+
+
+ public Map getParameters() {
+ return myParameters;
+ }
+
+ public String getUrlPath() {
+ return myUrlPath;
+ }
+
+ @Override
+ public HttpRequestBase asHttpRequest(String theUrlBase) {
+ return new HttpGet(theUrlBase + myUrlPath);
+ }
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java
index d1590313cdf..d857bbe3c02 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/RestfulClientFactory.java
@@ -6,8 +6,11 @@ import java.lang.reflect.Proxy;
import java.util.concurrent.TimeUnit;
import org.apache.http.client.HttpClient;
+import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingClientConnectionManager;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.impl.conn.SchemeRegistryFactory;
import ca.uhn.fhir.context.ConfigurationException;
@@ -46,10 +49,12 @@ public class RestfulClientFactory {
throw new ConfigurationException(theClientType.getCanonicalName() + " is not an interface");
}
- PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager(SchemeRegistryFactory.createDefault(), 5000, TimeUnit.MILLISECONDS);
- HttpClient client = new DefaultHttpClient(connectionManager);
-
- ClientInvocationHandler theInvocationHandler = new ClientInvocationHandler(client, myContext);
+ PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
+ HttpClientBuilder builder = HttpClientBuilder.create();
+ builder.setConnectionManager(connectionManager);
+ CloseableHttpClient client = builder.build();
+
+ ClientInvocationHandler theInvocationHandler = new ClientInvocationHandler(client, myContext, theServerBase);
for (Method nextMethod : theClientType.getMethods()) {
BaseMethodBinding binding = BaseMethodBinding.bindMethod(nextMethod);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/BaseServerResponseException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/BaseServerResponseException.java
new file mode 100644
index 00000000000..e9c7e95ba9a
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/BaseServerResponseException.java
@@ -0,0 +1,39 @@
+package ca.uhn.fhir.rest.client.exceptions;
+
+public abstract class BaseServerResponseException extends RuntimeException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+ *
+ * @param theMessage
+ * The message
+ */
+ public BaseServerResponseException(String theMessage) {
+ super(theMessage);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param theMessage
+ * The message
+ * @param theCause The cause
+ */
+ public BaseServerResponseException(String theMessage, Throwable theCause) {
+ super(theMessage, theCause);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param theCause
+ * The underlying cause exception
+ */
+ public BaseServerResponseException(Throwable theCause) {
+ super(theCause.toString(), theCause);
+ }
+
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/InvalidResponseException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/InvalidResponseException.java
new file mode 100644
index 00000000000..b60afe5cdc4
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/InvalidResponseException.java
@@ -0,0 +1,38 @@
+package ca.uhn.fhir.rest.client.exceptions;
+
+public class InvalidResponseException extends BaseServerResponseException {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+ *
+ * @param theMessage
+ * The message
+ */
+ public InvalidResponseException(String theMessage) {
+ super(theMessage);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param theMessage
+ * The message
+ * @param theCause The cause
+ */
+ public InvalidResponseException(String theMessage, Throwable theCause) {
+ super(theMessage, theCause);
+ }
+
+ /**
+ * Constructor
+ *
+ * @param theCause
+ * The underlying cause exception
+ */
+ public InvalidResponseException(Throwable theCause) {
+ super(theCause.toString(), theCause);
+ }
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/NonFhirResponseException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/NonFhirResponseException.java
new file mode 100644
index 00000000000..6173fc01f4a
--- /dev/null
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/client/exceptions/NonFhirResponseException.java
@@ -0,0 +1,40 @@
+package ca.uhn.fhir.rest.client.exceptions;
+
+public class NonFhirResponseException extends BaseServerResponseException {
+
+ private static final long serialVersionUID = 1L;
+ private final String myContentType;
+ private final int myStatusCode;
+ private final String myResponseText;
+
+ /**
+ * Constructor
+ *
+ * @param theMessage
+ * The message
+ * @param theResponseText
+ * @param theStatusCode
+ * @param theContentType
+ */
+ public NonFhirResponseException(String theMessage, String theContentType, int theStatusCode, String theResponseText) {
+ super(theMessage);
+ myContentType=theContentType;
+ myStatusCode=theStatusCode;
+ myResponseText=theResponseText;
+ }
+
+ public String getContentType() {
+ return myContentType;
+ }
+
+ public int getStatusCode() {
+ return myStatusCode;
+ }
+
+ public String getResponseText() {
+ return myResponseText;
+ }
+
+
+
+}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/BaseMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/BaseMethodBinding.java
index 86fb07ee9cd..33e6b1dc5d4 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/BaseMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/BaseMethodBinding.java
@@ -9,11 +9,12 @@ import java.util.Map;
import java.util.Set;
import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Read;
-import ca.uhn.fhir.rest.client.ClientInvocation;
+import ca.uhn.fhir.rest.client.GetClientInvocation;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.Resource;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@@ -23,23 +24,23 @@ import ca.uhn.fhir.rest.server.operations.Search;
public abstract class BaseMethodBinding {
private String myResourceName;
+ private MethodReturnTypeEnum myMethodReturnType;
- public BaseMethodBinding(Class extends IResource> theAnnotatedResourceType) {
+ public BaseMethodBinding(MethodReturnTypeEnum theMethodReturnType, Class extends IResource> theAnnotatedResourceType) {
ResourceDef resourceDefAnnotation = theAnnotatedResourceType.getAnnotation(ResourceDef.class);
if (resourceDefAnnotation == null) {
- throw new ConfigurationException(theAnnotatedResourceType.getCanonicalName() + " has no @" + ResourceDef.class.getSimpleName()+ " annotation");
+ throw new ConfigurationException(theAnnotatedResourceType.getCanonicalName() + " has no @" + ResourceDef.class.getSimpleName() + " annotation");
}
myResourceName = resourceDefAnnotation.name();
+ myMethodReturnType = theMethodReturnType;
}
public abstract ReturnTypeEnum getReturnType();
- public ClientInvocation invokeClient(Object[] theArgs) {
- // TODO Auto-generated method stub
- return null;
- }
+ public abstract GetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException;
- public abstract List invokeServer(IResourceProvider theResourceProvider, IdDt theId, IdDt theVersionId, Map theParameterValues) throws InvalidRequestException, InternalErrorException;
+ public abstract List invokeServer(IResourceProvider theResourceProvider, IdDt theId, IdDt theVersionId, Map theParameterValues) throws InvalidRequestException,
+ InternalErrorException;
public abstract boolean matches(String theResourceName, IdDt theId, IdDt theVersion, Set theParameterNames);
@@ -60,11 +61,21 @@ public abstract class BaseMethodBinding {
}
Class> methodReturnType = theMethod.getReturnType();
-
+ MethodReturnTypeEnum methodReturnTypeEnum;
+ if (methodReturnType.equals(List.class)) {
+ methodReturnTypeEnum = MethodReturnTypeEnum.LIST_OF_RESOURCES;
+ } else if (methodReturnType.isAssignableFrom(annotatedResourceType)) {
+ methodReturnTypeEnum = MethodReturnTypeEnum.RESOURCE;
+ } else if (Bundle.class.isAssignableFrom(methodReturnType)) {
+ methodReturnTypeEnum = MethodReturnTypeEnum.LIST_OF_RESOURCES;
+ } else {
+ throw new ConfigurationException("Invalid return type '" + methodReturnType.getCanonicalName() + "' on method '" + theMethod.getName() + "' on type: " + theMethod.getDeclaringClass().getCanonicalName());
+ }
+
if (read != null) {
- return new ReadMethodBinding(annotatedResourceType, theMethod);
+ return new ReadMethodBinding(methodReturnTypeEnum, annotatedResourceType, theMethod);
} else if (search != null) {
- return new SearchMethodBinding(annotatedResourceType, theMethod);
+ return new SearchMethodBinding(methodReturnTypeEnum, annotatedResourceType, theMethod);
} else {
throw new ConfigurationException("Did not detect any FHIR annotations on method '" + theMethod.getName() + "' on type: " + theMethod.getDeclaringClass().getCanonicalName());
}
@@ -98,8 +109,8 @@ public abstract class BaseMethodBinding {
if (obj1 == null) {
obj1 = object;
} else {
- throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @" + obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName()
- + ". Can not have both.");
+ throw new ConfigurationException("Method " + theNextMethod.getName() + " on type '" + theNextMethod.getDeclaringClass().getSimpleName() + " has annotations @"
+ + obj1.getClass().getSimpleName() + " and @" + object.getClass().getSimpleName() + ". Can not have both.");
}
}
@@ -125,7 +136,15 @@ public abstract class BaseMethodBinding {
}
}
+ public enum MethodReturnTypeEnum {
+ RESOURCE, BUNDLE, LIST_OF_RESOURCES
+ }
+
public enum ReturnTypeEnum {
BUNDLE, RESOURCE
}
+
+ public MethodReturnTypeEnum getMethodReturnType() {
+ return myMethodReturnType;
+ }
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/ReadMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/ReadMethodBinding.java
index 465c78fc471..af5ffda5bac 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/ReadMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/ReadMethodBinding.java
@@ -10,6 +10,8 @@ import org.apache.commons.lang3.Validate;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
+import ca.uhn.fhir.rest.client.GetClientInvocation;
+import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.Util;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@@ -22,8 +24,8 @@ public class ReadMethodBinding extends BaseMethodBinding {
private Integer myVersionIdIndex;
private int myParameterCount;
- public ReadMethodBinding(Class extends IResource> theAnnotatedResourceType, Method theMethod) {
- super(theAnnotatedResourceType);
+ public ReadMethodBinding(MethodReturnTypeEnum theMethodReturnType, Class extends IResource> theAnnotatedResourceType, Method theMethod) {
+ super(theMethodReturnType, theAnnotatedResourceType);
Validate.notNull(theMethod, "Method must not be null");
@@ -86,4 +88,15 @@ public class ReadMethodBinding extends BaseMethodBinding {
return toResourceList(response);
}
+ @Override
+ public GetClientInvocation invokeClient(Object[] theArgs) {
+ String id = ((IdDt)theArgs[myIdIndex]).getValue();
+ if (myVersionIdIndex == null) {
+ return new GetClientInvocation(getResourceName(), id);
+ }else {
+ String vid = ((IdDt)theArgs[myVersionIdIndex]).getValue();
+ return new GetClientInvocation(getResourceName(), id, Constants.URL_TOKEN_HISTORY, vid);
+ }
+ }
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/SearchMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/SearchMethodBinding.java
index 9ccb161e7b0..01cb1de63b7 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/SearchMethodBinding.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/common/SearchMethodBinding.java
@@ -2,6 +2,7 @@ package ca.uhn.fhir.rest.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -9,9 +10,9 @@ import java.util.Set;
import org.apache.commons.lang3.StringUtils;
-import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
+import ca.uhn.fhir.rest.client.GetClientInvocation;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.Parameter;
import ca.uhn.fhir.rest.server.Util;
@@ -26,14 +27,14 @@ public class SearchMethodBinding extends BaseMethodBinding {
private Method method;
- private List parameters;
+ private List myParameters;
private RequestType requestType;
private Class> myDeclaredResourceType;
- public SearchMethodBinding(Class extends IResource> theAnnotatedResourceType, Method theMethod) {
- super(theAnnotatedResourceType);
+ public SearchMethodBinding(MethodReturnTypeEnum theMethodReturnTypeEnum, Class extends IResource> theAnnotatedResourceType, Method theMethod) {
+ super(theMethodReturnTypeEnum, theAnnotatedResourceType);
this.method = theMethod;
- this.parameters = Util.getResourceParameters(theMethod);
+ this.myParameters = Util.getResourceParameters(theMethod);
this.myDeclaredResourceType = theMethod.getReturnType();
}
@@ -43,7 +44,7 @@ public class SearchMethodBinding extends BaseMethodBinding {
}
public List getParameters() {
- return parameters;
+ return myParameters;
}
public RequestType getRequestType() {
@@ -64,9 +65,9 @@ public class SearchMethodBinding extends BaseMethodBinding {
assert theId == null;
assert theVersionId == null;
- Object[] params = new Object[parameters.size()];
- for (int i = 0; i < parameters.size(); i++) {
- Parameter param = parameters.get(i);
+ Object[] params = new Object[myParameters.size()];
+ for (int i = 0; i < myParameters.size(); i++) {
+ Parameter param = myParameters.get(i);
String[] value = parameterValues.get(param.getName());
if (value == null || value.length == 0 || StringUtils.isBlank(value[0])) {
continue;
@@ -104,8 +105,8 @@ public class SearchMethodBinding extends BaseMethodBinding {
}
Set methodParamsTemp = new HashSet();
- for (int i = 0; i < this.parameters.size(); i++) {
- Parameter temp = this.parameters.get(i);
+ for (int i = 0; i < this.myParameters.size(); i++) {
+ Parameter temp = this.myParameters.get(i);
methodParamsTemp.add(temp.getName());
if (temp.isRequired() && !theParameterNames.contains(temp.getName())) {
ourLog.trace("Method {} doesn't match param '{}' is not present", method.getName(), temp.getName());
@@ -124,7 +125,7 @@ public class SearchMethodBinding extends BaseMethodBinding {
}
public void setParameters(List parameters) {
- this.parameters = parameters;
+ this.myParameters = parameters;
}
public void setRequestType(RequestType requestType) {
@@ -139,4 +140,20 @@ public class SearchMethodBinding extends BaseMethodBinding {
DELETE, GET, POST, PUT
}
+ @Override
+ public GetClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
+ assert theArgs.length == myParameters.size() : "Wrong number of arguments: " + theArgs.length;
+
+ Map args = new HashMap();
+
+ for (int idx = 0; idx < theArgs.length; idx++) {
+ Object object = theArgs[idx];
+ Parameter nextParam = myParameters.get(idx);
+ String value = nextParam.encode(object);
+ args.put(nextParam.getName(), value);
+ }
+
+ return new GetClientInvocation(args, getResourceName());
+ }
+
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Constants.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Constants.java
index 2e03db8218e..3868f075ca3 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Constants.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Constants.java
@@ -4,5 +4,7 @@ public class Constants {
public static final String CT_FHIR_XML = "application/xml+fhir";
public static final String PARAM_FORMAT = "_format";
+ public static final String URL_TOKEN_HISTORY = "_history";
+ public static final String CT_ATOM_XML = "application/atom+xml";
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Parameter.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Parameter.java
index 7cd3c20c6a3..12d94a28eeb 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Parameter.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/Parameter.java
@@ -1,88 +1,104 @@
package ca.uhn.fhir.rest.server;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
import ca.uhn.fhir.context.ConfigurationException;
+import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class Parameter {
- private String name;
+
+ private String name;
+ private IParamBinder parser;
private boolean required;
private Class> type;
- private IParser parser;
-
- public Parameter(){}
+ public Parameter(){}
public Parameter(String name, boolean required) {
this.name = name;
this.required = required;
}
- public Class> getType() {
- return type;
- }
-
- public void setType(final Class> type) {
- this.type = type;
- if (type.getSimpleName().equals("IdentifierDt")) {
- this.parser = new IParser() {
- @Override
- public Object parse(String theString) throws InternalErrorException {
- Object dt;
- try {
- dt = type.newInstance();
-
- Method method = dt.getClass().getMethod("setValueAsQueryToken", String.class);
- method.invoke(dt, theString);
-
- } catch (InstantiationException e) {
- throw new InternalErrorException(e);
- } catch (IllegalAccessException e) {
- throw new InternalErrorException(e);
- } catch (NoSuchMethodException e) {
- throw new InternalErrorException(e);
- } catch (SecurityException e) {
- throw new InternalErrorException(e);
- } catch (IllegalArgumentException e) {
- throw new InternalErrorException(e);
- } catch (InvocationTargetException e) {
- throw new InternalErrorException(e);
- }
- return dt;
- }
- };
- } else {
- throw new ConfigurationException("Unsupported data type for parameter: " + type.getCanonicalName());
- }
- }
-
public String getName() {
return name;
}
- public void setName(String name) {
- this.name = name;
+ public Class> getType() {
+ return type;
}
public boolean isRequired() {
return required;
}
+ public Object parse(String theString) throws InternalErrorException {
+ return parser.parse(theString);
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
public void setRequired(boolean required) {
this.required = required;
}
- public Object parse(String theString) throws InternalErrorException {
- return parser.parse(theString);
- }
+ @SuppressWarnings("unchecked")
+ public void setType(final Class> type) {
+ this.type = type;
+ if (IQueryParameterType.class.isAssignableFrom(type)) {
+ this.parser = new IdentifierParamBinder((Class extends IQueryParameterType>) type);
+ } else {
+ throw new ConfigurationException("Unsupported data type for parameter: " + type.getCanonicalName());
+ }
+ }
+
+
- private interface IParser
+ private final class IdentifierParamBinder implements IParamBinder {
+ private final Class extends IQueryParameterType> myType;
+
+ private IdentifierParamBinder(Class extends IQueryParameterType> theType) {
+ myType = theType;
+ }
+
+ @Override
+ public Object parse(String theString) throws InternalErrorException {
+ IQueryParameterType dt;
+ try {
+ dt = myType.newInstance();
+ dt.setValueAsQueryToken(theString);
+ } catch (InstantiationException e) {
+ throw new InternalErrorException(e);
+ } catch (IllegalAccessException e) {
+ throw new InternalErrorException(e);
+ } catch (SecurityException e) {
+ throw new InternalErrorException(e);
+ }
+ return dt;
+ }
+
+ @Override
+ public String encode(Object theString) throws InternalErrorException {
+ return ((IQueryParameterType)theString).getValueAsQueryToken();
+ }
+ }
+
+
+
+ private interface IParamBinder
{
Object parse(String theString) throws InternalErrorException;
+
+ String encode(Object theString) throws InternalErrorException;
+
+ }
+
+
+
+ public String encode(Object theObject) throws InternalErrorException {
+ return parser.encode(theObject);
}
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
index 682a327ad73..df849858046 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java
@@ -26,7 +26,7 @@ import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.common.BaseMethodBinding;
import ca.uhn.fhir.rest.common.SearchMethodBinding;
-import ca.uhn.fhir.rest.server.exceptions.AbstractResponseException;
+import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.MethodNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@@ -174,7 +174,7 @@ public abstract class RestfulServer extends HttpServlet {
}
// resourceMethod.get
- } catch (AbstractResponseException e) {
+ } catch (BaseServerResponseException e) {
if (e instanceof InternalErrorException) {
ourLog.error("Failure during REST processing", e);
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java.orig b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java.orig
deleted file mode 100644
index 55e899d66f6..00000000000
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java.orig
+++ /dev/null
@@ -1,331 +0,0 @@
-package ca.uhn.fhir.server;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.UUID;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import ca.uhn.fhir.context.FhirContext;
-import ca.uhn.fhir.context.RuntimeResourceDefinition;
-import ca.uhn.fhir.model.api.Bundle;
-import ca.uhn.fhir.model.api.BundleEntry;
-import ca.uhn.fhir.model.api.IResource;
-import ca.uhn.fhir.parser.XmlParser;
-import ca.uhn.fhir.server.exceptions.AbstractResponseException;
-import ca.uhn.fhir.server.exceptions.InternalErrorException;
-import ca.uhn.fhir.server.exceptions.MethodNotFoundException;
-import ca.uhn.fhir.server.exceptions.ResourceNotFoundException;
-import ca.uhn.fhir.server.operations.DELETE;
-import ca.uhn.fhir.server.operations.GET;
-import ca.uhn.fhir.server.operations.POST;
-import ca.uhn.fhir.server.operations.PUT;
-
-public abstract class RestfulServer extends HttpServlet {
-
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(RestfulServer.class);
-
- private static final long serialVersionUID = 1L;
-
-<<<<<<< HEAD:hapi-fhir-base/src/main/java/ca/uhn/fhir/server/RestfulServer.java
- private FhirContext myFhirContext;
-
- private Map, IResourceProvider>> myTypeToProvider = new HashMap, IResourceProvider>>();
-=======
- private Map, IResourceProvider>> myTypeToProvider = new HashMap, IResourceProvider>>();
-
- private FhirContext myFhirContext;
-
- public abstract Collection> getResourceProviders();
-
- @Override
- public void init() throws ServletException {
- try {
- ourLog.info("Initializing HAPI FHIR restful server");
-
- Collection> resourceProvider = getResourceProviders();
- for (IResourceProvider> nextProvider : resourceProvider) {
- if (myTypeToProvider.containsKey(nextProvider.getResourceType())) {
- throw new ServletException("Multiple providers for type: " + nextProvider.getResourceType().getCanonicalName());
- }
- myTypeToProvider.put(nextProvider.getResourceType(), nextProvider);
- }
-
- ourLog.info("Got {} resource providers",myTypeToProvider.size());
-
- myFhirContext = new FhirContext(myTypeToProvider.keySet());
-
-// findResourceMethods(nextProvider.getClass());
->>>>>>> b15504ab6af00727419d4888cd3a1c5215f5b5e3:hapi-fhir-base/src/main/java/ca/uhn/fhir/ws/RestfulServer.java
-
- // map of request handler resources keyed by resource name
- private Map resources = new HashMap();
-
- private boolean addResourceMethod(Resource resource, Method method) throws Exception {
-
- ResourceMethod rm = new ResourceMethod();
-
- // each operation name must have a request type annotation and be unique
- if (null != method.getAnnotation(GET.class)) {
- rm.setRequestType(ResourceMethod.RequestType.GET);
- } else if (null != method.getAnnotation(PUT.class)) {
- rm.setRequestType(ResourceMethod.RequestType.PUT);
- } else if (null != method.getAnnotation(POST.class)) {
- rm.setRequestType(ResourceMethod.RequestType.POST);
- } else if (null != method.getAnnotation(DELETE.class)) {
- rm.setRequestType(ResourceMethod.RequestType.DELETE);
- } else {
- return false;
- }
-
- rm.setMethod(method);
- rm.setResourceType(method.getReturnType());
- rm.setParameters(Util.getResourceParameters(method));
-
- resource.addMethod(rm);
- return true;
- }
-
- @SuppressWarnings("unused")
- private EncodingUtil determineResponseEncoding(Map theParams) {
- String[] format = theParams.remove(Constants.PARAM_FORMAT);
- // TODO: handle this once we support JSON
- return EncodingUtil.XML;
- }
-
- @Override
- protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- handleRequest(ResourceMethod.RequestType.DELETE, request, response);
- }
-
- @Override
- protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- handleRequest(ResourceMethod.RequestType.GET, request, response);
- }
-
- @Override
- protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- handleRequest(ResourceMethod.RequestType.POST, request, response);
- }
-
- @Override
- protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- handleRequest(ResourceMethod.RequestType.PUT, request, response);
- }
-
- private void findResourceMethods(IResourceProvider extends IResource> theProvider) throws Exception {
-
- Class extends IResource> resourceType = theProvider.getResourceType();
- RuntimeResourceDefinition definition = myFhirContext.getResourceDefinition(resourceType);
-
- Resource r = new Resource();
- r.setResourceProvider(theProvider);
- r.setResourceName(definition.getName());
- resources.put(definition.getName(), r);
-
- Class> clazz = theProvider.getClass();
- for (Method m : clazz.getDeclaredMethods()) {
- if (Modifier.isPublic(m.getModifiers())) {
-
- boolean foundMethod = addResourceMethod(r, m);
- if (foundMethod) {
- ourLog.debug("found handler: " + m.getName());
- }
- }
- }
- }
-
- public abstract Collection> getResourceProviders();
-
- protected void handleRequest(ResourceMethod.RequestType requestType, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- try {
- String resourceName = null;
- Long identity = null;
-
- Map params = new HashMap(request.getParameterMap());
- EncodingUtil responseEncoding = determineResponseEncoding(params);
-
- StringTokenizer tok = new StringTokenizer(request.getRequestURI(), "/");
- if (!tok.hasMoreTokens()) {
- throw new MethodNotFoundException("No resource name specified");
- }
- resourceName = tok.nextToken();
-
- Resource resourceBinding = resources.get(resourceName);
- if (resourceBinding == null) {
- throw new MethodNotFoundException("Unknown resource type: " + resourceBinding);
- }
-
- if (tok.hasMoreTokens()) {
- String identityString = tok.nextToken();
- try {
- identity = Long.parseLong(identityString);
- } catch (NumberFormatException e) {
- throw new NumberFormatException("Invalid identity token: " + identity);
- }
- }
-
- if (identity != null && !tok.hasMoreTokens()) {
- if (params == null || params.isEmpty()) {
- IResource resource = resourceBinding.getResourceProvider().getResourceById(identity);
- if (resource == null) {
- throw new ResourceNotFoundException(identity);
- }
- streamResponseAsResource(response, resource, resourceBinding, responseEncoding);
- return;
- }
- }
-
- ResourceMethod resourceMethod = resourceBinding.getMethod(params.keySet());
- if (null == resourceMethod) {
- throw new MethodNotFoundException("No resource method available for the supplied parameters " + params);
- }
-
- List result = resourceMethod.invoke(resourceBinding.getResourceProvider(), params);
- streamResponseAsBundle(response, result, responseEncoding);
-// resourceMethod.get
-
- } catch (AbstractResponseException e) {
-
- response.setStatus(e.getStatusCode());
- response.setContentType("text/plain");
- response.setCharacterEncoding("UTF-8");
- response.getWriter().append(e.getMessage());
- response.getWriter().close();
-
- } catch (Throwable t) {
- // TODO: handle this better
- ourLog.error("Failed to process invocation", t);
- throw new ServletException(t);
- }
-
- }
-
- @Override
- public void init() throws ServletException {
- try {
- ourLog.info("Initializing HAPI FHIR restful server");
-
- Collection> resourceProvider = getResourceProviders();
- for (IResourceProvider> nextProvider : resourceProvider) {
- if (myTypeToProvider.containsKey(nextProvider.getResourceType())) {
- throw new ServletException("Multiple providers for type: " + nextProvider.getResourceType().getCanonicalName());
- }
- myTypeToProvider.put(nextProvider.getResourceType(), nextProvider);
- }
-
- ourLog.info("Got {} resource providers",myTypeToProvider.size());
-
- myFhirContext = new FhirContext(myTypeToProvider.keySet());
-
- for (IResourceProvider> provider : myTypeToProvider.values()) {
- findResourceMethods(provider);
- }
-
-
- } catch (Exception ex) {
- ourLog.error("An error occurred while loading request handlers!", ex);
- throw new ServletException("Failed to initialize FHIR Restful server", ex);
- }
- }
-
- private void streamResponseAsBundle(HttpServletResponse theHttpResponse, List theResult, EncodingUtil theResponseEncoding) throws IOException {
- theHttpResponse.setStatus(200);
- theHttpResponse.setContentType(Constants.CT_FHIR_XML);
- theHttpResponse.setCharacterEncoding("UTF-8");
-
- Bundle bundle = new Bundle();
- bundle.getAuthorName().setValue(getClass().getCanonicalName());
- bundle.getId().setValue(UUID.randomUUID().toString());
- bundle.getPublished().setToCurrentTimeInLocalTimeZone();
-
- for (IResource next : theResult) {
- BundleEntry entry = new BundleEntry();
- bundle.getEntries().add(entry);
-
- entry.setResource(next);
- }
-
- bundle.getTotalResults().setValue(theResult.size());
-
- PrintWriter writer = theHttpResponse.getWriter();
- myFhirContext.newXmlParser().encodeBundleToWriter(bundle, writer);
- writer.close();
- }
-
- private void streamResponseAsResource(HttpServletResponse theHttpResponse, IResource theResource, Resource theResourceBinding, EncodingUtil theResponseEncoding) throws IOException {
-
- theHttpResponse.setStatus(200);
- theHttpResponse.setContentType(Constants.CT_FHIR_XML);
- theHttpResponse.setCharacterEncoding("UTF-8");
-
- PrintWriter writer = theHttpResponse.getWriter();
- myFhirContext.newXmlParser().encodeResourceToWriter(theResource, writer);
- writer.close();
-
- }
-
- /**
- * Recursive method used to find all classes in a given directory and
- * subdirs.
- *
- * @param directory
- * The base directory
- * @param packageName
- * The package name for classes found inside the base directory
- * @return The classes
- * @throws ClassNotFoundException
- */
- private static List> findClasses(File directory, String packageName) throws ClassNotFoundException {
- List> classes = new ArrayList>();
- if (!directory.exists()) {
- return classes;
- }
- File[] files = directory.listFiles();
- for (File file : files) {
- if (file.isDirectory()) {
- assert !file.getName().contains(".");
- classes.addAll(findClasses(file, packageName + "." + file.getName()));
- } else if (file.getName().endsWith(".class")) {
- classes.add(Class.forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
- }
- }
- return classes;
- }
-
- private static List> getClasses(String packageName) throws ClassNotFoundException, IOException {
-
- if (null == packageName)
- throw new ClassNotFoundException("package name must be specified for JSON operations");
-
- ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
- assert classLoader != null;
- String path = packageName.replace('.', '/');
- Enumeration resources = classLoader.getResources(path);
- List dirs = new ArrayList();
- while (resources.hasMoreElements()) {
- URL resource = resources.nextElement();
- dirs.add(new File(resource.getFile()));
- }
-
- ArrayList> classes = new ArrayList>();
- for (File directory : dirs) {
- classes.addAll(findClasses(directory, packageName));
- }
- return classes;
- }
-}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/AbstractResponseException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/BaseServerResponseException.java
similarity index 76%
rename from hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/AbstractResponseException.java
rename to hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/BaseServerResponseException.java
index f5165d78ce2..9bce258a9d5 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/AbstractResponseException.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/BaseServerResponseException.java
@@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions;
-public abstract class AbstractResponseException extends Exception {
+public abstract class BaseServerResponseException extends Exception {
private static final long serialVersionUID = 1L;
@@ -14,7 +14,7 @@ public abstract class AbstractResponseException extends Exception {
* @param theMessage
* The message
*/
- public AbstractResponseException(int theStatusCode, String theMessage) {
+ public BaseServerResponseException(int theStatusCode, String theMessage) {
super(theMessage);
myStatusCode = theStatusCode;
}
@@ -28,7 +28,7 @@ public abstract class AbstractResponseException extends Exception {
* The message
* @param theCause The cause
*/
- public AbstractResponseException(int theStatusCode, String theMessage, Throwable theCause) {
+ public BaseServerResponseException(int theStatusCode, String theMessage, Throwable theCause) {
super(theMessage, theCause);
myStatusCode = theStatusCode;
}
@@ -41,7 +41,7 @@ public abstract class AbstractResponseException extends Exception {
* @param theCause
* The underlying cause exception
*/
- public AbstractResponseException(int theStatusCode, Throwable theCause) {
+ public BaseServerResponseException(int theStatusCode, Throwable theCause) {
super(theCause.toString(), theCause);
myStatusCode = theStatusCode;
}
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InternalErrorException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InternalErrorException.java
index 5048a78d110..bcef3f570a0 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InternalErrorException.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InternalErrorException.java
@@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions;
-public class InternalErrorException extends AbstractResponseException {
+public class InternalErrorException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java
index 8a26a81034d..a9f00026dd8 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/InvalidRequestException.java
@@ -1,6 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions;
-public class InvalidRequestException extends AbstractResponseException {
+public class InvalidRequestException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/MethodNotFoundException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/MethodNotFoundException.java
index 00356c9c288..ed536853b39 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/MethodNotFoundException.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/MethodNotFoundException.java
@@ -3,7 +3,7 @@ package ca.uhn.fhir.rest.server.exceptions;
/**
* Created by dsotnikov on 2/27/2014.
*/
-public class MethodNotFoundException extends AbstractResponseException {
+public class MethodNotFoundException extends BaseServerResponseException {
private static final long serialVersionUID = 1L;
public MethodNotFoundException(String error) {
diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/ResourceNotFoundException.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/ResourceNotFoundException.java
index 5799a604433..c7ea30f8aa2 100644
--- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/ResourceNotFoundException.java
+++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/exceptions/ResourceNotFoundException.java
@@ -2,7 +2,7 @@ package ca.uhn.fhir.rest.server.exceptions;
import ca.uhn.fhir.model.primitive.IdDt;
-public class ResourceNotFoundException extends AbstractResponseException {
+public class ResourceNotFoundException extends BaseServerResponseException {
public ResourceNotFoundException(IdDt theId) {
super(404, "Resource " + (theId != null ? theId.getValue() : "") + " is not known");
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java
index 584deac2df6..971349ca58f 100644
--- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/XmlParserTest.java
@@ -20,10 +20,20 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Observation;
+import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.resource.ValueSet;
public class XmlParserTest {
+ @Test
+ public void testParseBundleLarge() throws IOException {
+
+ String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/atom-document-large.xml"));
+ IParser p = new FhirContext(Patient.class).newXmlParser();
+ Bundle bundle = p.parseBundle(msg);
+
+ }
+
@Test
public void testParseBundle() {
@@ -85,7 +95,7 @@ public class XmlParserTest {
"";
//@formatter:on
- XmlParser p = new FhirContext(ValueSet.class).newXmlParser();
+ IParser p = new FhirContext(ValueSet.class).newXmlParser();
Bundle bundle = p.parseBundle(msg);
assertEquals("FHIR Core Valuesets", bundle.getTitle().getValue());
@@ -105,7 +115,7 @@ public class XmlParserTest {
@Test
public void testLoadAndEncodeExtensions() throws ConfigurationException, DataFormatException, SAXException, IOException {
FhirContext ctx = new FhirContext(ResourceWithExtensionsA.class);
- XmlParser p = new XmlParser(ctx);
+ IParser p = new XmlParser(ctx);
//@formatter:off
String msg = "\n" +
@@ -169,7 +179,7 @@ public class XmlParserTest {
public void testLoadObservation() throws ConfigurationException, DataFormatException, IOException {
FhirContext ctx = new FhirContext(Observation.class);
- XmlParser p = new XmlParser(ctx);
+ IParser p = new XmlParser(ctx);
IResource resource = p.parseResource(IOUtils.toString(XmlParserTest.class.getResourceAsStream("/observation-example-eeg.xml")));
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java
index 8ce8648f715..141aebf5e0b 100644
--- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/ITestClient.java
@@ -19,4 +19,6 @@ public interface ITestClient extends IRestfulClient {
@Search(value=Patient.class)
Bundle findPatientByLastName(@Required(name = Patient.SP_FAMILY) IdentifierDt theId);
+
+
}
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/Tester.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/Tester.java
new file mode 100644
index 00000000000..01168b0952f
--- /dev/null
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/client/Tester.java
@@ -0,0 +1,32 @@
+package ca.uhn.fhir.rest.client;
+
+import ca.uhn.fhir.context.FhirContext;
+import ca.uhn.fhir.model.api.Bundle;
+import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
+import ca.uhn.fhir.model.dstu.resource.Patient;
+import ca.uhn.fhir.model.primitive.IdDt;
+import ca.uhn.fhir.rest.client.exceptions.NonFhirResponseException;
+
+public class Tester {
+
+ public static final void main(String[] args) {
+ try {
+
+ FhirContext ctx = new FhirContext(Patient.class);
+ RestfulClientFactory factory = ctx.newClientFactory();
+ ITestClient client = factory.newClient(ITestClient.class, "http://spark.furore.com/fhir/");
+
+// Patient patient = client.getPatientById(new IdDt("1"));
+// System.out.println(ctx.newXmlParser().encodeResourceToString(patient));
+
+ Patient patient2 = client.findPatientByMrn(new IdentifierDt("http://orionhealth.com/mrn", "PRP1660"));
+ System.out.println(ctx.newXmlParser().encodeResourceToString(patient2));
+
+ } catch (NonFhirResponseException e) {
+ e.printStackTrace();
+ System.out.println(e.getResponseText());
+ }
+
+ }
+
+}
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java
index 5d95afeb78a..205feb6584e 100644
--- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/server/ResourceMethodTest.java
@@ -12,6 +12,7 @@ import org.junit.Test;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.rest.common.SearchMethodBinding;
+import ca.uhn.fhir.rest.common.BaseMethodBinding.MethodReturnTypeEnum;
import ca.uhn.fhir.rest.server.Parameter;
public class ResourceMethodTest {
@@ -20,7 +21,7 @@ public class ResourceMethodTest {
@Before
public void before() throws NoSuchMethodException, SecurityException {
- rm = new SearchMethodBinding(Patient.class, ResourceMethodTest.class.getMethod("before"));
+ rm = new SearchMethodBinding(MethodReturnTypeEnum.RESOURCE, Patient.class, ResourceMethodTest.class.getMethod("before"));
}
@Test
diff --git a/hapi-fhir-base/src/test/resources/atom-document-large.xml b/hapi-fhir-base/src/test/resources/atom-document-large.xml
new file mode 100644
index 00000000000..123fd8cee76
--- /dev/null
+++ b/hapi-fhir-base/src/test/resources/atom-document-large.xml
@@ -0,0 +1,838 @@
+
+ Search on resources in collection 'Patient'
+ urn:uuid:8b8428a5-ba56-4fc7-b176-36d13346c1ad
+ 2014-03-06T22:09:58.9121174Z
+
+ Spark MatchBox Search Engine
+
+ 676
+
+
+
+
+
+
+ Patient resource with id 3216379
+ http://spark.furore.com/fhir/Patient/3216379
+ 2014-03-06T18:07:52.2209263Z
+ 2014-03-06T18:07:52.2209263Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient resource with id 3212416
+ http://spark.furore.com/fhir/Patient/3212416
+ 2014-01-18T19:48:05.7634661Z
+ 2014-01-18T19:48:05.747866Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient resource with id 3212417
+ http://spark.furore.com/fhir/Patient/3212417
+ 2014-01-18T19:48:40.9572917Z
+ 2014-01-18T19:48:40.9416916Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient resource with id 3212429
+ http://spark.furore.com/fhir/Patient/3212429
+ 2014-01-18T19:52:14.7410621Z
+ 2014-01-18T19:52:14.6786617Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://spark.furore.com/fhir/Patient/3212430
+ 2014-01-18T19:52:16.6442743Z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ http://spark.furore.com/fhir/Patient/3212433
+ 2014-01-18T19:52:17.5490801Z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient resource with id 3212435
+ http://spark.furore.com/fhir/Patient/3212435
+ 2014-01-18T19:52:18.7658879Z
+ 2014-01-18T19:52:18.7658879Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient Resource
+ http://spark.furore.com/fhir/Patient/3212446
+ 2014-01-18T19:55:50.8346474Z
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+ Patient Resource
+ http://spark.furore.com/fhir/Patient/3212492
+ 2014-01-18T22:09:21.1526936Z
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+ patient record
+ http://spark.furore.com/fhir/Patient/3212516
+ 2014-01-18T22:30:06.8604936Z
+
+
+
+
+
+
+
+ Person DOE, John, M, dob: 27/05/1956
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Person DOE, John, M, dob: 27/05/1956
+
+
+
+ Patient Resource
+ http://spark.furore.com/fhir/Patient/3212576
+ 2014-01-18T22:47:32.8716936Z
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+ Patient Resource
+ http://spark.furore.com/fhir/Composition/3212638
+ 2014-01-18T23:16:43.9026936Z
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+ Patient Resource
+ http://spark.furore.com/fhir/Patient/3212673
+ 2014-01-18T23:43:42.9527548Z
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Parkerson, Parkie
+
+
+
+ Patient resource with id 3212861
+ http://spark.furore.com/fhir/Patient/3212861
+ 2014-01-19T15:06:57.8105834Z
+ 2014-01-19T15:06:57.8105834Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+ BizTalk Test
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ BizTalk Test
+
+
+
+
+ Patient resource with id 3213112
+ http://spark.furore.com/fhir/Patient/3213112
+ 2014-01-19T16:17:08.4218784Z
+ 2014-01-19T16:17:08.4218784Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient resource with id 3213341
+ http://spark.furore.com/fhir/Patient/3213341
+ 2014-01-19T16:29:22.0804724Z
+ 2014-01-19T16:29:22.0648726Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient resource with id 3213417
+ http://spark.furore.com/fhir/Patient/3213417
+ 2014-01-19T16:33:17.1694584Z
+ 2014-01-19T16:33:17.1538586Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient
+ http://spark.furore.com/fhir/Patient/3213445
+ 2014-01-19T16:39:43.3113078Z
+
+
+
+
+
+
+ Isabella Isa Jones
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Isabella Isa Jones
+
+
+
+ Patient resource with id 3213586
+ http://spark.furore.com/fhir/Patient/3213586
+ 2014-01-19T16:41:54.9432766Z
+ 2014-01-19T16:41:54.9432766Z
+
+ (unauthenticated)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Patient
+ http://spark.furore.com/fhir/Patient/3213739
+ 2014-01-19T16:51:12.1772766Z
+
+
+
+
+
+
+ Isabella Isa Jones
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Isabella Isa Jones
+
+
+
\ No newline at end of file
diff --git a/hapi-fhir-base/src/test/resources/logback-test.xml b/hapi-fhir-base/src/test/resources/logback-test.xml
index 88219d4e47b..8a5cde21149 100644
--- a/hapi-fhir-base/src/test/resources/logback-test.xml
+++ b/hapi-fhir-base/src/test/resources/logback-test.xml
@@ -10,6 +10,10 @@
+
+
+
+
diff --git a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ValueSetGenerator.java b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ValueSetGenerator.java
index 3b96bd31889..840c5691c94 100644
--- a/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ValueSetGenerator.java
+++ b/hapi-tinder-plugin/src/main/java/ca/uhn/fhir/tinder/ValueSetGenerator.java
@@ -28,7 +28,7 @@ import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.dstu.resource.ValueSet;
import ca.uhn.fhir.model.dstu.resource.ValueSet.DefineConcept;
-import ca.uhn.fhir.parser.XmlParser;
+import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.tinder.model.ValueSetTm;
import ca.uhn.fhir.tinder.model.ValueSetTm.Code;
@@ -53,7 +53,7 @@ public class ValueSetGenerator {
}
public void parse() throws FileNotFoundException, IOException {
- XmlParser newXmlParser = new FhirContext(ValueSet.class).newXmlParser();
+ IParser newXmlParser = new FhirContext(ValueSet.class).newXmlParser();
ourLog.info("Parsing built-in ValueSets");
String vs = IOUtils.toString(ValueSetGenerator.class.getResourceAsStream("/vs/all-valuesets-bundle.xml"));
diff --git a/hapi-tinder-plugin/src/main/resources/vm/dt_composite.vm b/hapi-tinder-plugin/src/main/resources/vm/dt_composite.vm
index 87ecc0aa956..e8c5246f411 100644
--- a/hapi-tinder-plugin/src/main/resources/vm/dt_composite.vm
+++ b/hapi-tinder-plugin/src/main/resources/vm/dt_composite.vm
@@ -24,7 +24,31 @@ import ${packageBase}.resource.*;
*
*/
@DatatypeDef(name="${className}")
-public class ${className}Dt extends BaseElement implements ICompositeDatatype {
+public class ${className}Dt extends BaseElement implements ICompositeDatatype
+#if ( ${className} == "Identifier" )
+, IQueryParameter
+#end
+{
+
+#########################
+### Type-specific constructors
+#########################
+#if ( ${className} == "Identifier" )
+ /**
+ * Creates a new identifier
+ */
+ public IdentifierDt() {
+ // nothing
+ }
+
+ /**
+ * Creates a new identifier with the given system and value
+ */
+ public IdentifierDt(String theSystem, String theValue) {
+ setSystem(theSystem);
+ setValue(theValue);
+ }
+#end
#childExtensionFields( $childExtensionTypes )
#childVars( $children )
@@ -48,13 +72,21 @@ public class ${className}Dt extends BaseElement implements ICompositeDatatype {
}
/**
- * Sets the value of this IdentifierDt
using the token format. This
- * format is used in HTTP queries as a parameter format.
- *
- * @see See FHIR specification
- * 2.2.2 Search Parameter Types
- * for information on the token format
+ * {@inheritDoc}
*/
+ @Override
+ public String getValueAsQueryToken() {
+ if (org.apache.commons.lang3.StringUtils.isNotBlank(getSystem().getValueAsString())) {
+ return getSystem().getValueAsString() + '|' + getValue().getValueAsString();
+ } else {
+ return getValue().getValueAsString();
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
public void setValueAsQueryToken(String theParameter) {
int barIndex = theParameter.indexOf('|');
if (barIndex != -1) {