();
- String[] paragraphs = html.replace("", "").split("<\\/p>|
");
- for (int i=0;i htmlFormattingToPieces(String html) {
- List myPieces = new ArrayList();
- //Todo: At least handle bold and italics and turn them into formatted spans. (Will need to handle nesting though)
- myPieces.add(new Piece(null, html, null));
-
- return myPieces;
- }
+// private List htmlToParagraphPieces(String html) {
+// List myPieces = new ArrayList();
+// String[] paragraphs = html.replace("", "").split("<\\/p>|
");
+// for (int i=0;i htmlFormattingToPieces(String html) {
+// List myPieces = new ArrayList();
+// //Todo: At least handle bold and italics and turn them into formatted spans. (Will need to handle nesting though)
+// myPieces.add(new Piece(null, html, null));
+//
+// return myPieces;
+// }
public void addStyle(String style) {
for (Piece p : pieces)
p.addStyle(style);
@@ -507,8 +507,8 @@ public class HierarchicalTableGenerator {
b.append(new String(Base64.encodeBase64(bytes)));
// files.put(filename, b.toString());
return b.toString();
- } else
- return corePrefix+filename;
+ }
+ return corePrefix+filename;
}
@@ -558,22 +558,22 @@ public class HierarchicalTableGenerator {
b.append(new String(encodeBase64));
files.put(filename, b.toString());
return b.toString();
- } else {
- b.append("tbl_bck");
- for (Boolean i : indents)
- b.append(i ? "0" : "1");
- if (hasChildren)
- b.append("1");
- else
- b.append("0");
- b.append(".png");
- String file = Utilities.path(dest, b.toString());
- if (!new File(file).exists()) {
- FileOutputStream stream = new FileOutputStream(file);
- genImage(indents, hasChildren, stream);
- }
- return b.toString();
}
+ b.append("tbl_bck");
+ for (Boolean i : indents)
+ b.append(i ? "0" : "1");
+ if (hasChildren)
+ b.append("1");
+ else
+ b.append("0");
+ b.append(".png");
+ String file = Utilities.path(dest, b.toString());
+ if (!new File(file).exists()) {
+ //FIXME resource leak
+ FileOutputStream stream = new FileOutputStream(file);
+ genImage(indents, hasChildren, stream);
+ }
+ return b.toString();
}
diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlDocument.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlDocument.java
index 114f187c296..a4c6b19fbdf 100644
--- a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlDocument.java
+++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlDocument.java
@@ -25,7 +25,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
package org.hl7.fhir.utilities.xhtml;
/*
@@ -51,15 +51,17 @@ package org.hl7.fhir.utilities.xhtml;
public class XhtmlDocument extends XhtmlNode {
- public XhtmlDocument() {
- super(NodeType.Document);
- }
+ private static final long serialVersionUID = -5061185698841745693L;
- public XhtmlNode getDocumentElement() {
- for (XhtmlNode n : getChildNodes()) {
- if (n.getNodeType() == NodeType.Element)
- return n;
- }
- return null;
- }
+ public XhtmlDocument() {
+ super(NodeType.Document);
+ }
+
+ public XhtmlNode getDocumentElement() {
+ for (XhtmlNode n : getChildNodes()) {
+ if (n.getNodeType() == NodeType.Element)
+ return n;
+ }
+ return null;
+ }
}
diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java
index 4dac3bc76d5..a263b3d945c 100644
--- a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java
+++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlNode.java
@@ -25,7 +25,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWIS
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-*/
+ */
package org.hl7.fhir.utilities.xhtml;
/*
@@ -62,268 +62,268 @@ import ca.uhn.fhir.model.primitive.XhtmlDt;
@ca.uhn.fhir.model.api.annotation.DatatypeDef(name="xhtml")
public class XhtmlNode implements IBaseXhtml {
- private static final long serialVersionUID = -4362547161441436492L;
+ private static final long serialVersionUID = -4362547161441436492L;
- public static class Location {
- private int line;
- private int column;
- public Location(int line, int column) {
- super();
- this.line = line;
- this.column = column;
- }
- public int getLine() {
- return line;
- }
- public int getColumn() {
- return column;
- }
- @Override
- public String toString() {
- return "Line "+Integer.toString(line)+", column "+Integer.toString(column);
- }
- }
+ public static class Location {
+ private int line;
+ private int column;
+ public Location(int line, int column) {
+ super();
+ this.line = line;
+ this.column = column;
+ }
+ public int getLine() {
+ return line;
+ }
+ public int getColumn() {
+ return column;
+ }
+ @Override
+ public String toString() {
+ return "Line "+Integer.toString(line)+", column "+Integer.toString(column);
+ }
+ }
- public static final String NBSP = Character.toString((char)0xa0);
+ public static final String NBSP = Character.toString((char)0xa0);
private static final String DECL_XMLNS = " xmlns=\"http://www.w3.org/1999/xhtml\"";
-
- private Location location;
- private NodeType nodeType;
- private String name;
- private Map attributes = new HashMap();
- private List childNodes = new ArrayList();
- private String content;
- public XhtmlNode() {
- super();
- }
+ private Location location;
+ private NodeType nodeType;
+ private String name;
+ private Map attributes = new HashMap();
+ private List childNodes = new ArrayList();
+ private String content;
-
- public XhtmlNode(NodeType nodeType, String name) {
- super();
- this.nodeType = nodeType;
- this.name = name;
- }
+ public XhtmlNode() {
+ super();
+ }
- public XhtmlNode(NodeType nodeType) {
- super();
- this.nodeType = nodeType;
- }
- public NodeType getNodeType() {
- return nodeType;
- }
+ public XhtmlNode(NodeType nodeType, String name) {
+ super();
+ this.nodeType = nodeType;
+ this.name = name;
+ }
- public void setNodeType(NodeType nodeType) {
- this.nodeType = nodeType;
- }
+ public XhtmlNode(NodeType nodeType) {
+ super();
+ this.nodeType = nodeType;
+ }
- public String getName() {
- return name;
- }
+ public NodeType getNodeType() {
+ return nodeType;
+ }
- public void setName(String name) {
- assert name.contains(":") == false : "Name should not contain any : but was " + name;
- this.name = name;
- }
+ public void setNodeType(NodeType nodeType) {
+ this.nodeType = nodeType;
+ }
- public Map getAttributes() {
- return attributes;
- }
+ public String getName() {
+ return name;
+ }
- public List getChildNodes() {
- return childNodes;
- }
+ public void setName(String name) {
+ assert name.contains(":") == false : "Name should not contain any : but was " + name;
+ this.name = name;
+ }
- public String getContent() {
- return content;
- }
+ public Map getAttributes() {
+ return attributes;
+ }
- public XhtmlNode setContent(String content) {
- if (!(nodeType != NodeType.Text || nodeType != NodeType.Comment))
- throw new Error("Wrong node type");
- this.content = content;
- return this;
- }
+ public List getChildNodes() {
+ return childNodes;
+ }
- public XhtmlNode addTag(String name)
- {
+ public String getContent() {
+ return content;
+ }
- if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
- throw new Error("Wrong node type. is "+nodeType.toString());
- XhtmlNode node = new XhtmlNode(NodeType.Element);
- node.setName(name);
- childNodes.add(node);
- return node;
- }
+ public XhtmlNode setContent(String content) {
+ if (!(nodeType != NodeType.Text || nodeType != NodeType.Comment))
+ throw new Error("Wrong node type");
+ this.content = content;
+ return this;
+ }
- public XhtmlNode addTag(int index, String name)
- {
+ public XhtmlNode addTag(String name)
+ {
- if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
- throw new Error("Wrong node type. is "+nodeType.toString());
- XhtmlNode node = new XhtmlNode(NodeType.Element);
- node.setName(name);
- childNodes.add(index, node);
- return node;
- }
+ if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
+ throw new Error("Wrong node type. is "+nodeType.toString());
+ XhtmlNode node = new XhtmlNode(NodeType.Element);
+ node.setName(name);
+ childNodes.add(node);
+ return node;
+ }
- public XhtmlNode addComment(String content)
- {
- if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
- throw new Error("Wrong node type");
- XhtmlNode node = new XhtmlNode(NodeType.Comment);
- node.setContent(content);
- childNodes.add(node);
- return node;
- }
+ public XhtmlNode addTag(int index, String name)
+ {
- public XhtmlNode addDocType(String content)
- {
- if (!(nodeType == NodeType.Document))
- throw new Error("Wrong node type");
- XhtmlNode node = new XhtmlNode(NodeType.DocType);
- node.setContent(content);
- childNodes.add(node);
- return node;
- }
+ if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
+ throw new Error("Wrong node type. is "+nodeType.toString());
+ XhtmlNode node = new XhtmlNode(NodeType.Element);
+ node.setName(name);
+ childNodes.add(index, node);
+ return node;
+ }
- public XhtmlNode addInstruction(String content)
- {
- if (!(nodeType == NodeType.Document))
- throw new Error("Wrong node type");
- XhtmlNode node = new XhtmlNode(NodeType.Instruction);
- node.setContent(content);
- childNodes.add(node);
- return node;
- }
+ public XhtmlNode addComment(String content)
+ {
+ if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
+ throw new Error("Wrong node type");
+ XhtmlNode node = new XhtmlNode(NodeType.Comment);
+ node.setContent(content);
+ childNodes.add(node);
+ return node;
+ }
+
+ public XhtmlNode addDocType(String content)
+ {
+ if (!(nodeType == NodeType.Document))
+ throw new Error("Wrong node type");
+ XhtmlNode node = new XhtmlNode(NodeType.DocType);
+ node.setContent(content);
+ childNodes.add(node);
+ return node;
+ }
+
+ public XhtmlNode addInstruction(String content)
+ {
+ if (!(nodeType == NodeType.Document))
+ throw new Error("Wrong node type");
+ XhtmlNode node = new XhtmlNode(NodeType.Instruction);
+ node.setContent(content);
+ childNodes.add(node);
+ return node;
+ }
- public XhtmlNode addText(String content)
- {
- if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
- throw new Error("Wrong node type");
- if (content != null) {
- XhtmlNode node = new XhtmlNode(NodeType.Text);
- node.setContent(content);
- childNodes.add(node);
- return node;
- } else
- return null;
- }
+ public XhtmlNode addText(String content)
+ {
+ if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
+ throw new Error("Wrong node type");
+ if (content != null) {
+ XhtmlNode node = new XhtmlNode(NodeType.Text);
+ node.setContent(content);
+ childNodes.add(node);
+ return node;
+ }
+ return null;
+ }
- public XhtmlNode addText(int index, String content)
- {
- if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
- throw new Error("Wrong node type");
- if (content == null)
- throw new Error("Content cannot be null");
-
- XhtmlNode node = new XhtmlNode(NodeType.Text);
- node.setContent(content);
- childNodes.add(index, node);
- return node;
- }
+ public XhtmlNode addText(int index, String content)
+ {
+ if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
+ throw new Error("Wrong node type");
+ if (content == null)
+ throw new Error("Content cannot be null");
- public boolean allChildrenAreText()
- {
- boolean res = true;
- for (XhtmlNode n : childNodes)
- res = res && n.getNodeType() == NodeType.Text;
- return res;
- }
+ XhtmlNode node = new XhtmlNode(NodeType.Text);
+ node.setContent(content);
+ childNodes.add(index, node);
+ return node;
+ }
- public XhtmlNode getElement(String name)
- {
- for (XhtmlNode n : childNodes)
- if (n.getNodeType() == NodeType.Element && name.equals(n.getName()))
- return n;
- return null;
- }
+ public boolean allChildrenAreText()
+ {
+ boolean res = true;
+ for (XhtmlNode n : childNodes)
+ res = res && n.getNodeType() == NodeType.Text;
+ return res;
+ }
- public XhtmlNode getFirstElement()
- {
- for (XhtmlNode n : childNodes)
- if (n.getNodeType() == NodeType.Element)
- return n;
- return null;
- }
+ public XhtmlNode getElement(String name)
+ {
+ for (XhtmlNode n : childNodes)
+ if (n.getNodeType() == NodeType.Element && name.equals(n.getName()))
+ return n;
+ return null;
+ }
- public String allText() {
- StringBuilder b = new StringBuilder();
- for (XhtmlNode n : childNodes)
- if (n.getNodeType() == NodeType.Text)
- b.append(n.getContent());
- else if (n.getNodeType() == NodeType.Element)
- b.append(n.allText());
- return b.toString();
- }
+ public XhtmlNode getFirstElement()
+ {
+ for (XhtmlNode n : childNodes)
+ if (n.getNodeType() == NodeType.Element)
+ return n;
+ return null;
+ }
- public XhtmlNode attribute(String name, String value) {
- if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
- throw new Error("Wrong node type");
- if (name == null)
- throw new Error("name is null");
- if (value == null)
- throw new Error("value is null");
- attributes.put(name, value);
- return this;
- }
+ public String allText() {
+ StringBuilder b = new StringBuilder();
+ for (XhtmlNode n : childNodes)
+ if (n.getNodeType() == NodeType.Text)
+ b.append(n.getContent());
+ else if (n.getNodeType() == NodeType.Element)
+ b.append(n.allText());
+ return b.toString();
+ }
- public boolean hasAttribute(String name) {
- return getAttributes().containsKey(name);
- }
+ public XhtmlNode attribute(String name, String value) {
+ if (!(nodeType == NodeType.Element || nodeType == NodeType.Document))
+ throw new Error("Wrong node type");
+ if (name == null)
+ throw new Error("name is null");
+ if (value == null)
+ throw new Error("value is null");
+ attributes.put(name, value);
+ return this;
+ }
- public String getAttribute(String name) {
- return getAttributes().get(name);
- }
+ public boolean hasAttribute(String name) {
+ return getAttributes().containsKey(name);
+ }
- public XhtmlNode setAttribute(String name, String value) {
- getAttributes().put(name, value);
- return this;
- }
-
- public XhtmlNode copy() {
- XhtmlNode dst = new XhtmlNode(nodeType);
- dst.name = name;
- for (String n : attributes.keySet()) {
- dst.attributes.put(n, attributes.get(n));
- }
- for (XhtmlNode n : childNodes)
- dst.childNodes.add(n.copy());
- dst.content = content;
- return dst;
- }
+ public String getAttribute(String name) {
+ return getAttributes().get(name);
+ }
+
+ public XhtmlNode setAttribute(String name, String value) {
+ getAttributes().put(name, value);
+ return this;
+ }
+
+ public XhtmlNode copy() {
+ XhtmlNode dst = new XhtmlNode(nodeType);
+ dst.name = name;
+ for (String n : attributes.keySet()) {
+ dst.attributes.put(n, attributes.get(n));
+ }
+ for (XhtmlNode n : childNodes)
+ dst.childNodes.add(n.copy());
+ dst.content = content;
+ return dst;
+ }
@Override
public boolean isEmpty() {
- return (childNodes == null || childNodes.isEmpty()) && content == null;
- }
+ return (childNodes == null || childNodes.isEmpty()) && content == null;
+ }
public boolean equalsDeep(XhtmlNode other) {
- if (other == null) {
- return false;
- }
+ if (other == null) {
+ return false;
+ }
- if (!(nodeType == other.nodeType) || !compare(name, other.name) || !compare(content, other.content))
- return false;
- if (attributes.size() != other.attributes.size())
- return false;
- for (String an : attributes.keySet())
- if (!attributes.get(an).equals(other.attributes.get(an)))
- return false;
- if (childNodes.size() != other.childNodes.size())
- return false;
+ if (!(nodeType == other.nodeType) || !compare(name, other.name) || !compare(content, other.content))
+ return false;
+ if (attributes.size() != other.attributes.size())
+ return false;
+ for (String an : attributes.keySet())
+ if (!attributes.get(an).equals(other.attributes.get(an)))
+ return false;
+ if (childNodes.size() != other.childNodes.size())
+ return false;
for (int i = 0; i < childNodes.size(); i++) {
if (!compareDeep(childNodes.get(i), other.childNodes.get(i)))
return false;
}
return true;
- }
+ }
private boolean compare(String s1, String s2) {
if (s1 == null && s2 == null)
@@ -331,7 +331,7 @@ public class XhtmlNode implements IBaseXhtml {
if (s1 == null || s2 == null)
return false;
return s1.equals(s2);
- }
+ }
private static boolean compareDeep(XhtmlNode e1, XhtmlNode e2) {
if (e1 == null && e2 == null)
@@ -339,18 +339,18 @@ public class XhtmlNode implements IBaseXhtml {
if (e1 == null || e2 == null)
return false;
return e1.equalsDeep(e2);
- }
-
- public String getNsDecl() {
- for (String an : attributes.keySet()) {
- if (an.equals("xmlns")) {
- return attributes.get(an);
- }
- }
- return null;
- }
-
-
+ }
+
+ public String getNsDecl() {
+ for (String an : attributes.keySet()) {
+ if (an.equals("xmlns")) {
+ return attributes.get(an);
+ }
+ }
+ return null;
+ }
+
+
@Override
public String getValueAsString() {
if (isEmpty()) {
@@ -376,9 +376,9 @@ public class XhtmlNode implements IBaseXhtml {
if (isBlank(theValue)) {
return;
}
-
+
String val = theValue.trim();
-
+
if (!val.startsWith("<")) {
val = "" + val + "
";
}
@@ -387,7 +387,7 @@ public class XhtmlNode implements IBaseXhtml {
}
val = XhtmlDt.preprocessXhtmlNamespaceDeclaration(val);
-
+
try {
// TODO: this is ugly
XhtmlNode fragment = new XhtmlParser().parseFragment(val);
@@ -400,61 +400,64 @@ public class XhtmlNode implements IBaseXhtml {
// TODO: composer shouldn't throw exception like this
throw new RuntimeException(e);
}
-
+
}
- public XhtmlNode getElementByIndex(int i) {
- int c = 0;
- for (XhtmlNode n : childNodes)
- if (n.getNodeType() == NodeType.Element) {
- if (c == i)
- return n;
- else
- c++;
- }
- return null;
- }
+ public XhtmlNode getElementByIndex(int i) {
+ int c = 0;
+ for (XhtmlNode n : childNodes)
+ if (n.getNodeType() == NodeType.Element) {
+ if (c == i){
+ return n;
+ }
+ c++;
+ }
+ return null;
+ }
-@Override
-public String getValue() {
- return getValueAsString();
-}
+ @Override
+ public String getValue() {
+ return getValueAsString();
+ }
-@Override
-public XhtmlNode setValue(String theValue) throws IllegalArgumentException {
- setValueAsString(theValue);
- return this;
-}
+ @Override
+ public XhtmlNode setValue(String theValue) throws IllegalArgumentException {
+ setValueAsString(theValue);
+ return this;
+ }
-/**
- * Returns false
- */
-public boolean hasFormatComment() {
- return false;
-}
+ /**
+ * Returns false
+ */
+ @Override
+ public boolean hasFormatComment() {
+ return false;
+ }
-/**
- * NOT SUPPORTED - Throws {@link UnsupportedOperationException}
- */
-public List getFormatCommentsPre() {
- throw new UnsupportedOperationException();
-}
+ /**
+ * NOT SUPPORTED - Throws {@link UnsupportedOperationException}
+ */
+ @Override
+ public List getFormatCommentsPre() {
+ throw new UnsupportedOperationException();
+ }
-/**
- * NOT SUPPORTED - Throws {@link UnsupportedOperationException}
- */
-public List getFormatCommentsPost() {
- throw new UnsupportedOperationException();
-}
+ /**
+ * NOT SUPPORTED - Throws {@link UnsupportedOperationException}
+ */
+ @Override
+ public List getFormatCommentsPost() {
+ throw new UnsupportedOperationException();
+ }
-public Location getLocation() {
- return location;
-}
+ public Location getLocation() {
+ return location;
+ }
-public void setLocation(Location location) {
- this.location = location;
-}
+ public void setLocation(Location location) {
+ this.location = location;
+ }
}
diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java
index 1a54dc7db73..dda22dde031 100644
--- a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java
+++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xhtml/XhtmlParser.java
@@ -227,17 +227,17 @@ public class XhtmlParser {
if (validatorMode)
return true;
boolean ok = attributes.contains(attr) || attributes.contains(elem + "." + attr);
- if (ok)
+ if (ok) {
return true;
- else
- switch (policy) {
- case Accept:
- return true;
- case Drop:
- return false;
- case Reject:
- throw new FHIRFormatError("Illegal HTML attribute " + elem + "." + attr);
- }
+ }
+ switch (policy) {
+ case Accept:
+ return true;
+ case Drop:
+ return false;
+ case Reject:
+ throw new FHIRFormatError("Illegal HTML attribute " + elem + "." + attr);
+ }
if ((elem + "." + attr).equals("img.src") && !(value.startsWith("#") || value.startsWith("http:") || value.startsWith("https:"))) {
switch (policy) {
@@ -306,17 +306,17 @@ public class XhtmlParser {
if (validatorMode)
return true;
boolean ok = elements.contains(name);
- if (ok)
+ if (ok){
return true;
- else
- switch (policy) {
- case Accept:
- return true;
- case Drop:
- return false;
- case Reject:
- throw new FHIRFormatError("Illegal HTML element " + name);
- }
+ }
+ switch (policy) {
+ case Accept:
+ return true;
+ case Drop:
+ return false;
+ case Reject:
+ throw new FHIRFormatError("Illegal HTML element " + name);
+ }
return false;
}
@@ -458,26 +458,25 @@ public class XhtmlParser {
else if (peekChar() == '/') {
readChar();
QName n = new QName(readToTagEnd());
- if (node.getName().equals(n.getName()))
+ if (node.getName().equals(n.getName())){
return;
- else {
- if (mustBeWellFormed)
- throw new FHIRFormatError("Malformed XHTML: Found \"" + n.getName() + ">\" expecting \"" + node.getName() + ">\"" + descLoc());
- for (int i = parents.size() - 1; i >= 0; i--) {
- if (parents.get(i).getName().equals(n))
- unwindPoint = parents.get(i);
- }
- if (unwindPoint != null) {
- for (int i = parents.size(); i > 0; i--) {
- if (i < parents.size() && parents.get(i) == unwindPoint)
- return;
- if (i == parents.size()) {
- parents.get(i - 1).getChildNodes().addAll(node.getChildNodes());
- node.getChildNodes().clear();
- } else {
- parents.get(i - 1).getChildNodes().addAll(parents.get(i).getChildNodes());
- parents.get(i).getChildNodes().clear();
- }
+ }
+ if (mustBeWellFormed)
+ throw new FHIRFormatError("Malformed XHTML: Found \"" + n.getName() + ">\" expecting \"" + node.getName() + ">\"" + descLoc());
+ for (int i = parents.size() - 1; i >= 0; i--) {
+ if (parents.get(i).getName().equals(n))
+ unwindPoint = parents.get(i);
+ }
+ if (unwindPoint != null) {
+ for (int i = parents.size(); i > 0; i--) {
+ if (i < parents.size() && parents.get(i) == unwindPoint)
+ return;
+ if (i == parents.size()) {
+ parents.get(i - 1).getChildNodes().addAll(node.getChildNodes());
+ node.getChildNodes().clear();
+ } else {
+ parents.get(i - 1).getChildNodes().addAll(parents.get(i).getChildNodes());
+ parents.get(i).getChildNodes().clear();
}
}
}
diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLUtil.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLUtil.java
index c943109b184..b36b8d0d704 100644
--- a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLUtil.java
+++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLUtil.java
@@ -275,38 +275,37 @@ public class XMLUtil {
* @return escape string
*/
public static String escapeXML(String rawContent, String charset, boolean isNoLines) {
- if (rawContent == null)
+ if (rawContent == null){
return "";
- else {
- StringBuffer sb = new StringBuffer();
+ }
+ StringBuffer sb = new StringBuffer();
- for (int i = 0; i < rawContent.length(); i++) {
- char ch = rawContent.charAt(i);
- if (ch == '\'')
- sb.append("'");
- else if (ch == '&')
- sb.append("&");
- else if (ch == '"')
- sb.append(""");
- else if (ch == '<')
- sb.append("<");
- else if (ch == '>')
- sb.append(">");
- else if (ch > '~' && charset != null && charSetImpliesAscii(charset))
- // TODO - why is hashcode the only way to get the unicode number for the character
- // in jre 5.0?
- sb.append(""+Integer.toHexString(new Character(ch).hashCode()).toUpperCase()+";");
- else if (isNoLines) {
- if (ch == '\r')
- sb.append("
");
- else if (ch != '\n')
- sb.append(ch);
- }
- else
+ for (int i = 0; i < rawContent.length(); i++) {
+ char ch = rawContent.charAt(i);
+ if (ch == '\'')
+ sb.append("'");
+ else if (ch == '&')
+ sb.append("&");
+ else if (ch == '"')
+ sb.append(""");
+ else if (ch == '<')
+ sb.append("<");
+ else if (ch == '>')
+ sb.append(">");
+ else if (ch > '~' && charset != null && charSetImpliesAscii(charset))
+ // TODO - why is hashcode the only way to get the unicode number for the character
+ // in jre 5.0?
+ sb.append(""+Integer.toHexString(new Character(ch).hashCode()).toUpperCase()+";");
+ else if (isNoLines) {
+ if (ch == '\r')
+ sb.append("
");
+ else if (ch != '\n')
sb.append(ch);
}
- return sb.toString();
+ else
+ sb.append(ch);
}
+ return sb.toString();
}
public static Element getFirstChild(Element e) {
@@ -435,6 +434,7 @@ public class XMLUtil {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
+ //FIXME resource leak
return builder.parse(new FileInputStream(filename));
}
diff --git a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLWriter.java b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLWriter.java
index f66a0915b2c..ab739b9390d 100644
--- a/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLWriter.java
+++ b/hapi-fhir-base/src/main/java/org/hl7/fhir/utilities/xml/XMLWriter.java
@@ -401,10 +401,10 @@ public class XMLWriter extends OutputStreamWriter implements IXMLWriter {
@Override
public String getDefaultNamespace() {
XMLNamespace ns = findDefaultNamespace();
- if (ns == null)
+ if (ns == null) {
return null;
- else
- return ns.getNamespace();
+ }
+ return ns.getNamespace();
}
/* (non-Javadoc)
@@ -519,10 +519,10 @@ public class XMLWriter extends OutputStreamWriter implements IXMLWriter {
writePendingComment();
pendingClose = false;
}
-
- if (name == null) {
- throw new IOException("name is null");
- }
+//death code
+// if (name == null) {
+// throw new IOException("name is null");
+// }
newLevelIfRequired();
levels.current().setName(name);
levels.current().setNamespace(namespace);
@@ -615,23 +615,22 @@ public class XMLWriter extends OutputStreamWriter implements IXMLWriter {
checkStarted();
if (levels.empty()) {
throw new IOException("Called exit one too many times");
+ }
+ if (pendingClose) {
+ write("/>");
+ writePendingComment();
+ pendingClose = false;
} else {
- if (pendingClose) {
- write("/>");
- writePendingComment();
- pendingClose = false;
- } else {
- if (levels.current().hasChildren())
- writePretty();
- write("");
- if (levels.current().getNamespace() == null)
- write(levels.current().getName());
- else
- write(getNSAbbreviation(levels.current().getNamespace())+levels.current().getName());
- write('>');
- }
- levels.pop();
+ if (levels.current().hasChildren())
+ writePretty();
+ write("");
+ if (levels.current().getNamespace() == null)
+ write(levels.current().getName());
+ else
+ write(getNSAbbreviation(levels.current().getNamespace())+levels.current().getName());
+ write('>');
}
+ levels.pop();
}
/* (non-Javadoc)
@@ -830,8 +829,8 @@ public class XMLWriter extends OutputStreamWriter implements IXMLWriter {
for (int i = 0; i < levels.size() - 1; i++)
write(" ");
return (levels.size() - 1) * 2;
- } else
- return 0;
+ }
+ return 0;
}
public int getLineType() {
diff --git a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties
index 636b56fc038..c8aa3a30c30 100644
--- a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties
+++ b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/i18n/hapi-messages.properties
@@ -67,6 +67,7 @@ ca.uhn.fhir.jpa.dao.BaseHapiFhirSystemDao.transactionEntryHasInvalidVerb=Transac
ca.uhn.fhir.jpa.dao.BaseHapiFhirSystemDao.transactionMissingUrl=Unable to perform {0}, no URL provided.
ca.uhn.fhir.jpa.dao.BaseHapiFhirSystemDao.transactionInvalidUrl=Unable to perform {0}, URL provided is invalid: {1}
+ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.cantValidateWithNoResource=No resource supplied for $validate operation (resource is required unless mode is \"delete\")
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.duplicateCreateForcedId=Can not create entity with ID[{0}], a resource with this ID already exists
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.failedToCreateWithInvalidId=Can not process entity with ID[{0}], this is not a valid FHIR ID
ca.uhn.fhir.jpa.dao.BaseHapiFhirResourceDao.incorrectResourceType=Incorrect resource type detected for endpoint, found {0} but expected {1}
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/json/JsonLikeStructureTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/json/JsonLikeStructureTest.java
index 925340ac1b8..bc120a0e2c6 100644
--- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/json/JsonLikeStructureTest.java
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/parser/json/JsonLikeStructureTest.java
@@ -7,11 +7,9 @@ import java.io.StringReader;
import org.junit.Test;
-import ca.uhn.fhir.context.FhirContext;
-
public class JsonLikeStructureTest {
- private static FhirContext ourCtx;
- private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonLikeStructureTest.class);
+// private static FhirContext ourCtx;
+// private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(JsonLikeStructureTest.class);
private static final String TEST_STRUCTURELOADING_DATA =
"{" +
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/param/StringParamTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/param/StringParamTest.java
new file mode 100644
index 00000000000..f19fa54bf58
--- /dev/null
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/rest/param/StringParamTest.java
@@ -0,0 +1,19 @@
+package ca.uhn.fhir.rest.param;
+
+import static org.junit.Assert.*;
+
+import org.junit.Test;
+
+public class StringParamTest {
+
+ @Test
+ public void testEquals() {
+ StringParam input = new StringParam("foo", true);
+
+ assertTrue(input.equals(input));
+ assertFalse(input.equals(null));
+ assertFalse(input.equals(""));
+ assertFalse(input.equals(new StringParam("foo", false)));
+ }
+
+}
diff --git a/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/UrlUtilTest.java b/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/UrlUtilTest.java
index f3b689e29ea..d55b7a9a1cc 100644
--- a/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/UrlUtilTest.java
+++ b/hapi-fhir-base/src/test/java/ca/uhn/fhir/util/UrlUtilTest.java
@@ -1,11 +1,11 @@
package ca.uhn.fhir.util;
-import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import org.junit.Test;
-import ca.uhn.fhir.util.UrlUtil.UrlParts;
-
public class UrlUtilTest {
@Test
diff --git a/hapi-fhir-client-okhttp/.settings/org.eclipse.jdt.core.prefs b/hapi-fhir-client-okhttp/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 60105c1b951..00000000000
--- a/hapi-fhir-client-okhttp/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,5 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/hapi-fhir-jacoco/.settings/org.eclipse.jdt.core.prefs b/hapi-fhir-jacoco/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 60105c1b951..00000000000
--- a/hapi-fhir-jacoco/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,5 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/hapi-fhir-jaxrsserver-base/.settings/org.eclipse.jdt.core.prefs b/hapi-fhir-jaxrsserver-base/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 60105c1b951..00000000000
--- a/hapi-fhir-jaxrsserver-base/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,5 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/hapi-fhir-jaxrsserver-example/.settings/org.eclipse.jdt.core.prefs b/hapi-fhir-jaxrsserver-example/.settings/org.eclipse.jdt.core.prefs
deleted file mode 100644
index 60105c1b951..00000000000
--- a/hapi-fhir-jaxrsserver-example/.settings/org.eclipse.jdt.core.prefs
+++ /dev/null
@@ -1,5 +0,0 @@
-eclipse.preferences.version=1
-org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
-org.eclipse.jdt.core.compiler.compliance=1.6
-org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
-org.eclipse.jdt.core.compiler.source=1.6
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
index 9965a51e88b..22e67de435f 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirDao.java
@@ -11,7 +11,7 @@ import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -335,7 +335,7 @@ public abstract class BaseHapiFhirDao implements IDao {
continue;
}
}
-
+
Class extends IBaseResource> type = resourceDefinition.getImplementingClass();
String id = nextId.getIdPart();
if (StringUtils.isBlank(id)) {
@@ -677,18 +677,19 @@ public abstract class BaseHapiFhirDao implements IDao {
theRequestDetails.getUserData().put(PROCESSING_SUB_REQUEST, Boolean.TRUE);
}
}
-
+
protected void notifyInterceptors(RestOperationTypeEnum theOperationType, ActionRequestDetails theRequestDetails) {
if (theRequestDetails.getId() != null && theRequestDetails.getId().hasResourceType() && isNotBlank(theRequestDetails.getResourceType())) {
if (theRequestDetails.getId().getResourceType().equals(theRequestDetails.getResourceType()) == false) {
- throw new InternalErrorException("Inconsistent server state - Resource types don't match: " + theRequestDetails.getId().getResourceType() + " / " + theRequestDetails.getResourceType());
+ throw new InternalErrorException(
+ "Inconsistent server state - Resource types don't match: " + theRequestDetails.getId().getResourceType() + " / " + theRequestDetails.getResourceType());
}
}
if (theRequestDetails.getUserData().get(PROCESSING_SUB_REQUEST) == Boolean.TRUE) {
theRequestDetails.notifyIncomingRequestPreHandled(theOperationType);
}
-
+
List interceptors = getConfig().getInterceptors();
if (interceptors == null) {
return;
@@ -779,7 +780,7 @@ public abstract class BaseHapiFhirDao implements IDao {
theEntity.setHasTags(true);
}
}
-
+
ArrayList existingTags = new ArrayList();
if (theEntity.isHasTags()) {
existingTags.addAll(theEntity.getTags());
@@ -937,9 +938,9 @@ public abstract class BaseHapiFhirDao implements IDao {
* Subclasses may override to provide behaviour. Called when a resource has been inserted into the database for the first time.
*
* @param theEntity
- * The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
+ * The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
* @param theTag
- * The tag
+ * The tag
* @return Returns true
if the tag should be removed
*/
@SuppressWarnings("unused")
@@ -951,9 +952,9 @@ public abstract class BaseHapiFhirDao implements IDao {
* Subclasses may override to provide behaviour. Called when a pre-existing resource has been updated in the database
*
* @param theEntity
- * The resource
+ * The resource
* @param theResource
- * The resource being persisted
+ * The resource being persisted
*/
protected void postUpdate(ResourceTable theEntity, T theResource) {
// nothing
@@ -1009,9 +1010,9 @@ public abstract class BaseHapiFhirDao implements IDao {
*
*
* @param theEntity
- * The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
+ * The entity being updated (Do not modify the entity! Undefined behaviour will occur!)
* @param theTag
- * The tag
+ * The tag
* @return Retturns true
if the tag should be removed
*/
protected boolean shouldDroppedTagBeRemovedOnUpdate(ResourceTable theEntity, ResourceTag theTag) {
@@ -1072,7 +1073,7 @@ public abstract class BaseHapiFhirDao implements IDao {
}
}
}
-
+
IParser parser = theEntity.getEncoding().newParser(getContext(theEntity.getFhirVersion()));
R retVal;
try {
@@ -1241,7 +1242,8 @@ public abstract class BaseHapiFhirDao implements IDao {
}
/*
- * Handle references within the resource that are match URLs, for example references like "Patient?identifier=foo". These match URLs are resolved and replaced with the ID of the matching
+ * Handle references within the resource that are match URLs, for example references like "Patient?identifier=foo". These match URLs are resolved and replaced with the ID of the
+ * matching
* resource.
*/
if (myConfig.isAllowInlineMatchUrlReferences()) {
@@ -1437,7 +1439,7 @@ public abstract class BaseHapiFhirDao implements IDao {
theEntity.setResourceLinks(links);
theEntity.toString();
-
+
} // if thePerformIndexing
theEntity = myEntityManager.merge(theEntity);
@@ -1538,9 +1540,9 @@ public abstract class BaseHapiFhirDao implements IDao {
* "subsetted" tag and rejects resources which have it. Subclasses should call the superclass implementation to preserve this check.
*
* @param theResource
- * The resource that is about to be persisted
+ * The resource that is about to be persisted
* @param theEntityToSave
- * TODO
+ * TODO
*/
protected void validateResourceForStorage(T theResource, ResourceTable theEntityToSave) {
Object tag = null;
@@ -1747,7 +1749,7 @@ public abstract class BaseHapiFhirDao implements IDao {
paramMap.add(nextParamName, param);
continue;
}
-
+
if (Constants.PARAM_COUNT.equals(nextParamName)) {
if (paramList.size() > 0 && paramList.get(0).size() > 0) {
String intString = paramList.get(0).get(0);
@@ -1772,7 +1774,8 @@ public abstract class BaseHapiFhirDao implements IDao {
} else {
RuntimeSearchParam paramDef = theCallingDao.getSearchParamByName(resourceDef, nextParamName);
if (paramDef == null) {
- throw new InvalidRequestException("Failed to parse match URL[" + theMatchUrl + "] - Resource type " + resourceDef.getName() + " does not have a parameter with name: " + nextParamName);
+ throw new InvalidRequestException(
+ "Failed to parse match URL[" + theMatchUrl + "] - Resource type " + resourceDef.getName() + " does not have a parameter with name: " + nextParamName);
}
IQueryParameterAnd> param = MethodUtil.parseQueryParams(theContext, paramDef, nextParamName, paramList);
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java
index 446534ad694..880cd96e91e 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseHapiFhirResourceDao.java
@@ -192,7 +192,7 @@ public abstract class BaseHapiFhirResourceDao extends B
validateOkToDelete(deleteConflicts, entity);
- preDelete(resourceToDelete);
+ preDelete(resourceToDelete, entity);
// Notify interceptors
if (theRequestDetails != null) {
@@ -722,7 +722,8 @@ public abstract class BaseHapiFhirResourceDao extends B
* Subclasses may override to provide behaviour. Invoked within a delete
* transaction with the resource that is about to be deleted.
*/
- protected void preDelete(T theResourceToDelete) {
+ @SuppressWarnings("unused")
+ protected void preDelete(T theResourceToDelete, ResourceTable theEntityToDelete) {
// nothing by default
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java
index 8b2cb87df03..8608d26e428 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/BaseSearchParamRegistry.java
@@ -10,7 +10,7 @@ package ca.uhn.fhir.jpa.dao;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -27,7 +27,6 @@ import java.util.Map;
import javax.annotation.PostConstruct;
-import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Autowired;
@@ -37,8 +36,6 @@ import ca.uhn.fhir.context.RuntimeSearchParam;
public abstract class BaseSearchParamRegistry implements ISearchParamRegistry {
- private static final Map EMPTY_SP_MAP = Collections.emptyMap();
-
private Map> myBuiltInSearchParams;
@Autowired
@@ -56,27 +53,32 @@ public abstract class BaseSearchParamRegistry implements ISearchParamRegistry {
// nothing by default
}
- public Map> getBuiltInSearchParams() {
+ @Override
+ public Map> getActiveSearchParams() {
return myBuiltInSearchParams;
}
@Override
- public Map getActiveSearchParams(String theResourceName) {
+ public Map getActiveSearchParams(String theResourceName) {
Validate.notBlank(theResourceName, "theResourceName must not be blank or null");
return myBuiltInSearchParams.get(theResourceName);
}
+ public Map> getBuiltInSearchParams() {
+ return myBuiltInSearchParams;
+ }
+
@PostConstruct
public void postConstruct() {
- Map> resourceNameToSearchParams = new HashMap>();
+ Map> resourceNameToSearchParams = new HashMap>();
for (IFhirResourceDao> nextDao : myDaos) {
RuntimeResourceDefinition nextResDef = myCtx.getResourceDefinition(nextDao.getResourceType());
String nextResourceName = nextResDef.getName();
HashMap nameToParam = new HashMap();
resourceNameToSearchParams.put(nextResourceName, nameToParam);
-
+
for (RuntimeSearchParam nextSp : nextResDef.getSearchParams()) {
nameToParam.put(nextSp.getName(), nextSp);
}
@@ -85,13 +87,4 @@ public abstract class BaseSearchParamRegistry implements ISearchParamRegistry {
myBuiltInSearchParams = Collections.unmodifiableMap(resourceNameToSearchParams);
}
- @Override
- public Collection getAllSearchParams(String theResourceName) {
- Validate.notBlank(theResourceName, "theResourceName must not be null or blank");
-
- Map map = myBuiltInSearchParams.get(theResourceName);
- map = ObjectUtils.defaultIfNull(map, EMPTY_SP_MAP);
- return Collections.unmodifiableCollection(map.values());
- }
-
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2.java
index 34b82976b90..62ae1312e66 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirResourceDaoDstu2.java
@@ -56,6 +56,7 @@ import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
+import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.CoverageIgnore;
import ca.uhn.fhir.util.FhirTerser;
@@ -133,8 +134,11 @@ public class FhirResourceDaoDstu2 extends BaseHapiFhirResou
ValidationResult result;
if (isNotBlank(theRawResource)) {
result = validator.validateWithResult(theRawResource);
- } else {
+ } else if (theResource != null) {
result = validator.validateWithResult(theResource);
+ } else {
+ String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "cantValidateWithNoResource");
+ throw new InvalidRequestException(msg);
}
if (result.isSuccessful()) {
@@ -160,11 +164,11 @@ public class FhirResourceDaoDstu2 extends BaseHapiFhirResou
boolean hasId = theCtx.getResource().getIdElement().hasIdPart();
if (myMode == ValidationModeEnum.CREATE) {
if (hasId) {
- throw new InvalidRequestException("Resource has an ID - ID must not be populated for a FHIR create");
+ throw new UnprocessableEntityException("Resource has an ID - ID must not be populated for a FHIR create");
}
} else if (myMode == ValidationModeEnum.UPDATE) {
if (hasId == false) {
- throw new InvalidRequestException("Resource has no ID - ID must be populated for a FHIR update");
+ throw new UnprocessableEntityException("Resource has no ID - ID must be populated for a FHIR update");
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java
index abbbd8b2214..2af6fbc3f04 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/FhirSystemDaoDstu2.java
@@ -492,7 +492,9 @@ public class FhirSystemDaoDstu2 extends BaseHapiFhirSystemDao {
InstantDt deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get(nextResource);
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
boolean shouldUpdate = !nonUpdatedEntities.contains(nextOutcome.getEntity());
- updateEntity(nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, true, shouldUpdate, updateTime);
+ if (shouldUpdate) {
+ updateEntity(nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, true, true, updateTime);
+ }
}
myEntityManager.flush();
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java
index eea349770cd..58a7d489fd0 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/ISearchParamRegistry.java
@@ -1,36 +1,15 @@
package ca.uhn.fhir.jpa.dao;
-/*
- * #%L
- * HAPI FHIR JPA Server
- * %%
- * Copyright (C) 2014 - 2017 University Health Network
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-import java.util.Collection;
import java.util.Map;
import ca.uhn.fhir.context.RuntimeSearchParam;
public interface ISearchParamRegistry {
- Map getActiveSearchParams(String theResourceName);
-
- Collection getAllSearchParams(String theResourceName);
-
void forceRefresh();
+ Map> getActiveSearchParams();
+
+ Map getActiveSearchParams(String theResourceName);
+
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
index 3106f9bc0b8..7cff1643bb2 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/SearchBuilder.java
@@ -2309,6 +2309,11 @@ public class SearchBuilder {
public int size() {
return myPids.size();
}
+
+ @Override
+ public String getUuid() {
+ return null;
+ }
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamCoordsDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamCoordsDao.java
new file mode 100644
index 00000000000..2bf1e05ab6e
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamCoordsDao.java
@@ -0,0 +1,29 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2017 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamCoords;
+
+public interface IResourceIndexedSearchParamCoordsDao extends JpaRepository {
+ // nothing yet
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamDateDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamDateDao.java
new file mode 100644
index 00000000000..d4f05ff8c75
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamDateDao.java
@@ -0,0 +1,29 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2017 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamDate;
+
+public interface IResourceIndexedSearchParamDateDao extends JpaRepository {
+ // nothing yet
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamNumberDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamNumberDao.java
new file mode 100644
index 00000000000..9385dd17529
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamNumberDao.java
@@ -0,0 +1,29 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2017 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamNumber;
+
+public interface IResourceIndexedSearchParamNumberDao extends JpaRepository {
+ // nothing yet
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityDao.java
new file mode 100644
index 00000000000..e6948e48a28
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamQuantityDao.java
@@ -0,0 +1,29 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2017 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamQuantity;
+
+public interface IResourceIndexedSearchParamQuantityDao extends JpaRepository {
+ // nothing yet
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamStringDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamStringDao.java
new file mode 100644
index 00000000000..7c9b13b500e
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamStringDao.java
@@ -0,0 +1,29 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2017 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamString;
+
+public interface IResourceIndexedSearchParamStringDao extends JpaRepository {
+ // nothing yet
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamTokenDao.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamTokenDao.java
new file mode 100644
index 00000000000..03813879786
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/data/IResourceIndexedSearchParamTokenDao.java
@@ -0,0 +1,29 @@
+package ca.uhn.fhir.jpa.dao.data;
+
+/*
+ * #%L
+ * HAPI FHIR JPA Server
+ * %%
+ * Copyright (C) 2014 - 2017 University Health Network
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import ca.uhn.fhir.jpa.entity.ResourceIndexedSearchParamToken;
+
+public interface IResourceIndexedSearchParamTokenDao extends JpaRepository {
+ // nothing yet
+}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3.java
index 571c5e06c99..9da4a0c7c92 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3.java
@@ -54,6 +54,7 @@ import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
+import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor.ActionRequestDetails;
import ca.uhn.fhir.util.CoverageIgnore;
import ca.uhn.fhir.util.FhirTerser;
@@ -143,7 +144,8 @@ public class FhirResourceDaoDstu3 extends BaseHapiFhirRe
if (resourceToValidateById != null) {
result = validator.validateWithResult(resourceToValidateById);
} else {
- throw new InvalidRequestException("No resource supplied for $validate operation (resource is required unless mode is \"delete\")");
+ String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "cantValidateWithNoResource");
+ throw new InvalidRequestException(msg);
}
} else if (isNotBlank(theRawResource)) {
result = validator.validateWithResult(theRawResource);
@@ -180,11 +182,11 @@ public class FhirResourceDaoDstu3 extends BaseHapiFhirRe
boolean hasId = theCtx.getResource().getIdElement().hasIdPart();
if (myMode == ValidationModeEnum.CREATE) {
if (hasId) {
- throw new InvalidRequestException("Resource has an ID - ID must not be populated for a FHIR create");
+ throw new UnprocessableEntityException("Resource has an ID - ID must not be populated for a FHIR create");
}
} else if (myMode == ValidationModeEnum.UPDATE) {
if (hasId == false) {
- throw new InvalidRequestException("Resource has no ID - ID must be populated for a FHIR update");
+ throw new UnprocessableEntityException("Resource has no ID - ID must be populated for a FHIR update");
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java
index f816fe2f6d4..5432daf5206 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoSearchParameterDstu3.java
@@ -2,8 +2,6 @@ package ca.uhn.fhir.jpa.dao.dstu3;
import static org.apache.commons.lang3.StringUtils.isBlank;
-import java.util.List;
-
/*
* #%L
* HAPI FHIR JPA Server
@@ -34,20 +32,23 @@ import org.springframework.scheduling.annotation.Scheduled;
import ca.uhn.fhir.jpa.dao.BaseSearchParamExtractor;
import ca.uhn.fhir.jpa.dao.IFhirResourceDaoSearchParameter;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
+import ca.uhn.fhir.jpa.dao.ISearchParamRegistry;
import ca.uhn.fhir.jpa.entity.ResourceTable;
-import ca.uhn.fhir.jpa.util.DeleteConflict;
import ca.uhn.fhir.parser.DataFormatException;
-import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
+import ca.uhn.fhir.util.ElementUtil;
public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3 implements IFhirResourceDaoSearchParameter {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoSearchParameterDstu3.class);
+ @Autowired
+ private ISearchParamRegistry mySearchParamRegistry;
+
@Autowired
private IFhirSystemDao mySystemDao;
- private void markAffectedResources(SearchParameter theResource) {
+ protected void markAffectedResources(SearchParameter theResource) {
if (theResource != null) {
String expression = theResource.getExpression();
String resourceType = expression.substring(0, expression.indexOf('.'));
@@ -55,8 +56,9 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3
return retVal;
- // ValueSetExpansionComponent expansion = outcome.getValueset().getExpansion();
+ // ValueSetExpansionComponent expansion = outcome.getValueset().getExpansion();
//
- // ValueSet retVal = new ValueSet();
- // retVal.getMeta().setLastUpdated(new Date());
- // retVal.setExpansion(expansion);
- // return retVal;
+ // ValueSet retVal = new ValueSet();
+ // retVal.getMeta().setLastUpdated(new Date());
+ // retVal.setExpansion(expansion);
+ // return retVal;
}
private void validateIncludes(String name, List listToValidate) {
@@ -137,11 +138,11 @@ public class FhirResourceDaoValueSetDstu3 extends FhirResourceDaoDstu3
public ValueSet expand(ValueSet source, String theFilter) {
ValueSet toExpand = new ValueSet();
-// for (UriType next : source.getCompose().getInclude()) {
-// ConceptSetComponent include = toExpand.getCompose().addInclude();
-// include.setSystem(next.getValue());
-// addFilterIfPresent(theFilter, include);
-// }
+ // for (UriType next : source.getCompose().getInclude()) {
+ // ConceptSetComponent include = toExpand.getCompose().addInclude();
+ // include.setSystem(next.getValue());
+ // addFilterIfPresent(theFilter, include);
+ // }
for (ConceptSetComponent next : source.getCompose().getInclude()) {
toExpand.getCompose().addInclude(next);
@@ -155,18 +156,41 @@ public class FhirResourceDaoValueSetDstu3 extends FhirResourceDaoDstu3
toExpand.getCompose().getExclude().addAll(source.getCompose().getExclude());
ValueSet retVal = doExpand(toExpand);
+
+ if (isNotBlank(theFilter)) {
+ applyFilter(retVal.getExpansion().getTotalElement(), retVal.getExpansion().getContains(), theFilter);
+ }
+
return retVal;
}
+ private void applyFilter(IntegerType theTotalElement, List theContains, String theFilter) {
+
+ for (int idx = 0; idx < theContains.size(); idx++) {
+ ValueSetExpansionContainsComponent next = theContains.get(idx);
+ if (isBlank(next.getDisplay()) || !org.apache.commons.lang3.StringUtils.containsIgnoreCase(next.getDisplay(), theFilter)) {
+ theContains.remove(idx);
+ idx--;
+ if (theTotalElement.getValue() != null) {
+ theTotalElement.setValue(theTotalElement.getValue() - 1);
+ }
+ }
+ applyFilter(theTotalElement, next.getContains(), theFilter);
+ }
+ }
+
private void addFilterIfPresent(String theFilter, ConceptSetComponent include) {
- if (isNotBlank(theFilter)) {
- include.addFilter().setProperty("display").setOp(FilterOperator.EQUAL).setValue(theFilter);
+ if (ElementUtil.isEmpty(include.getConcept())) {
+ if (isNotBlank(theFilter)) {
+ include.addFilter().setProperty("display").setOp(FilterOperator.EQUAL).setValue(theFilter);
+ }
}
}
@Override
- public ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCode(IPrimitiveType theValueSetIdentifier, IIdType theId, IPrimitiveType theCode, IPrimitiveType theSystem, IPrimitiveType theDisplay, Coding theCoding,
+ public ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCode(IPrimitiveType theValueSetIdentifier, IIdType theId, IPrimitiveType theCode,
+ IPrimitiveType theSystem, IPrimitiveType theDisplay, Coding theCoding,
CodeableConcept theCodeableConcept, RequestDetails theRequestDetails) {
List valueSetIds = Collections.emptyList();
@@ -226,7 +250,8 @@ public class FhirResourceDaoValueSetDstu3 extends FhirResourceDaoDstu3
return thePrimitive != null ? thePrimitive.getValue() : null;
}
- private ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCodeIsInContains(List contains, String theSystem, String theCode, Coding theCoding, CodeableConcept theCodeableConcept) {
+ private ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult validateCodeIsInContains(List contains, String theSystem, String theCode,
+ Coding theCoding, CodeableConcept theCodeableConcept) {
for (ValueSetExpansionContainsComponent nextCode : contains) {
ca.uhn.fhir.jpa.dao.IFhirResourceDaoValueSet.ValidateCodeResult result = validateCodeIsInContains(nextCode.getContains(), theSystem, theCode, theCoding, theCodeableConcept);
if (result != null) {
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3.java
index 6a38958f9d1..51b3caa17f1 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3.java
@@ -383,7 +383,8 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao {
IFhirResourceDao resourceDao = getDaoOrThrowException(res.getClass());
res.setId((String) null);
DaoMethodOutcome outcome;
- outcome = resourceDao.create(res, nextReqEntry.getRequest().getIfNoneExist(), false, theRequestDetails);
+ String matchUrl = nextReqEntry.getRequest().getIfNoneExist();
+ outcome = resourceDao.create(res, matchUrl, false, theRequestDetails);
handleTransactionCreateOrUpdateOutcome(idSubstitutions, idToPersistedOutcome, nextResourceId, outcome, nextRespEntry, resourceType, res);
entriesToProcess.put(nextRespEntry, outcome.getEntity());
if (outcome.getCreated() == false) {
@@ -489,7 +490,9 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao {
IPrimitiveType deletedInstantOrNull = ResourceMetadataKeyEnum.DELETED_AT.get((IAnyResource) nextResource);
Date deletedTimestampOrNull = deletedInstantOrNull != null ? deletedInstantOrNull.getValue() : null;
boolean shouldUpdate = !nonUpdatedEntities.contains(nextOutcome.getEntity());
- updateEntity(nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, shouldUpdate, shouldUpdate, updateTime);
+ if (shouldUpdate) {
+ updateEntity(nextResource, nextOutcome.getEntity(), deletedTimestampOrNull, shouldUpdate, true, updateTime);
+ }
}
myEntityManager.flush();
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java
index ed6612fc852..d6f631cbebd 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3.java
@@ -50,6 +50,7 @@ import org.hl7.fhir.dstu3.model.ContactPoint;
import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.Duration;
import org.hl7.fhir.dstu3.model.Enumeration;
+import org.hl7.fhir.dstu3.model.Extension;
import org.hl7.fhir.dstu3.model.HumanName;
import org.hl7.fhir.dstu3.model.Identifier;
import org.hl7.fhir.dstu3.model.IntegerType;
@@ -520,7 +521,16 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
// }
for (Object nextObject : extractValues(nextPath, theResource)) {
+
+ if (nextObject instanceof Extension) {
+ Extension nextExtension = (Extension)nextObject;
+ nextObject = nextExtension.getValue();
+ }
+ if (nextObject == null) {
+ continue;
+ }
+
// Patient:language
if (nextObject instanceof PatientCommunicationComponent) {
PatientCommunicationComponent nextValue = (PatientCommunicationComponent) nextObject;
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamRegistryDstu3.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamRegistryDstu3.java
index 9faf743d56e..2b3b967e2a6 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamRegistryDstu3.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamRegistryDstu3.java
@@ -10,7 +10,7 @@ package ca.uhn.fhir.jpa.dao.dstu3;
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
@@ -35,6 +35,7 @@ import org.apache.commons.lang3.time.DateUtils;
import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.SearchParameter;
import org.hl7.fhir.instance.model.api.IBaseResource;
+import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.beans.factory.annotation.Autowired;
import ca.uhn.fhir.context.RuntimeSearchParam;
@@ -50,19 +51,43 @@ import ca.uhn.fhir.rest.server.IBundleProvider;
public class SearchParamRegistryDstu3 extends BaseSearchParamRegistry {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchParamRegistryDstu3.class);
- @Autowired
- private IFhirResourceDao mySpDao;
-
- private long myLastRefresh;
-
private volatile Map> myActiveSearchParams;
@Autowired
private DaoConfig myDaoConfig;
+ private long myLastRefresh;
+
+ @Autowired
+ private IFhirResourceDao mySpDao;
+
+ @Override
+ public void forceRefresh() {
+ myLastRefresh = 0;
+ }
+
+ @Override
+ public Map> getActiveSearchParams() {
+ refreshCacheIfNeccesary();
+ return myActiveSearchParams;
+ }
+
@Override
public Map getActiveSearchParams(String theResourceName) {
+ refreshCacheIfNeccesary();
+ return myActiveSearchParams.get(theResourceName);
+ }
+ private Map getSearchParamMap(Map> searchParams, String theResourceName) {
+ Map retVal = searchParams.get(theResourceName);
+ if (retVal == null) {
+ retVal = new HashMap();
+ searchParams.put(theResourceName, retVal);
+ }
+ return retVal;
+ }
+
+ private void refreshCacheIfNeccesary() {
long refreshInterval = 60 * DateUtils.MILLIS_PER_MINUTE;
if (System.currentTimeMillis() - refreshInterval > myLastRefresh) {
StopWatch sw = new StopWatch();
@@ -91,7 +116,7 @@ public class SearchParamRegistryDstu3 extends BaseSearchParamRegistry {
if (runtimeSp == null) {
continue;
}
-
+
int dotIdx = runtimeSp.getPath().indexOf('.');
if (dotIdx == -1) {
ourLog.warn("Can not determine resource type of {}", runtimeSp.getPath());
@@ -113,14 +138,14 @@ public class SearchParamRegistryDstu3 extends BaseSearchParamRegistry {
if (nextSp.getStatus() != RuntimeSearchParamStatusEnum.ACTIVE) {
nextSp = null;
}
-
+
if (!activeSearchParams.containsKey(nextEntry.getKey())) {
activeSearchParams.put(nextEntry.getKey(), new HashMap());
}
if (activeSearchParams.containsKey(nextEntry.getKey())) {
- ourLog.info("Replacing existing/built in search param {}:{} with new one", nextEntry.getKey(), nextName);
+ ourLog.debug("Replacing existing/built in search param {}:{} with new one", nextEntry.getKey(), nextName);
}
-
+
if (nextSp != null) {
activeSearchParams.get(nextEntry.getKey()).put(nextName, nextSp);
} else {
@@ -134,22 +159,6 @@ public class SearchParamRegistryDstu3 extends BaseSearchParamRegistry {
myLastRefresh = System.currentTimeMillis();
ourLog.info("Refreshed search parameter cache in {}ms", sw.getMillis());
}
-
- return myActiveSearchParams.get(theResourceName);
- }
-
- @Override
- public void forceRefresh() {
- myLastRefresh = 0;
- }
-
- private Map getSearchParamMap(Map> searchParams, String theResourceName) {
- Map retVal = searchParams.get(theResourceName);
- if (retVal == null) {
- retVal = new HashMap();
- searchParams.put(theResourceName, retVal);
- }
- return retVal;
}
private RuntimeSearchParam toRuntimeSp(SearchParameter theNextSp) {
@@ -208,7 +217,9 @@ public class SearchParamRegistryDstu3 extends BaseSearchParamRegistry {
return null;
}
- RuntimeSearchParam retVal = new RuntimeSearchParam(name, description, path, paramType, providesMembershipInCompartments, targets, status);
+ IIdType id = theNextSp.getIdElement();
+ String uri = "";
+ RuntimeSearchParam retVal = new RuntimeSearchParam(id, uri, name, description, path, paramType, null, providesMembershipInCompartments, targets, status);
return retVal;
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/BaseResourceIndexedSearchParam.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/BaseResourceIndexedSearchParam.java
index 3a931961c74..ee4c6286301 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/BaseResourceIndexedSearchParam.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/entity/BaseResourceIndexedSearchParam.java
@@ -70,6 +70,10 @@ public abstract class BaseResourceIndexedSearchParam implements Serializable {
return myResourcePid;
}
+ public String getResourceType() {
+ return myResourceType;
+ }
+
public void setParamName(String theName) {
myParamName = theName;
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java
index 87c51527b57..be65fc85d33 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/DatabaseBackedPagingProvider.java
@@ -22,6 +22,7 @@ package ca.uhn.fhir.jpa.search;
import javax.persistence.EntityManager;
+import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
@@ -30,10 +31,12 @@ import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.IFhirSystemDao;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
+import ca.uhn.fhir.rest.server.BasePagingProvider;
import ca.uhn.fhir.rest.server.FifoMemoryPagingProvider;
import ca.uhn.fhir.rest.server.IBundleProvider;
+import ca.uhn.fhir.rest.server.IPagingProvider;
-public class DatabaseBackedPagingProvider extends FifoMemoryPagingProvider {
+public class DatabaseBackedPagingProvider extends BasePagingProvider implements IPagingProvider {
@Autowired
private PlatformTransactionManager thePlatformTransactionManager;
@@ -46,29 +49,36 @@ public class DatabaseBackedPagingProvider extends FifoMemoryPagingProvider {
@Autowired
private IFhirSystemDao, ?> theDao;
+ /**
+ * Constructor
+ * @deprecated Use {@link DatabaseBackedPagingProvider} as this constructor has no purpose
+ */
+ @Deprecated
public DatabaseBackedPagingProvider(int theSize) {
- super(theSize);
+ this();
+ }
+
+ /**
+ * Constructor
+ */
+ public DatabaseBackedPagingProvider() {
+ super();
}
@Override
public synchronized IBundleProvider retrieveResultList(String theId) {
- IBundleProvider retVal = super.retrieveResultList(theId);
- if (retVal == null) {
- PersistedJpaBundleProvider provider = new PersistedJpaBundleProvider(theId, theDao);
- if (!provider.ensureSearchEntityLoaded()) {
- return null;
- }
- retVal = provider;
+ PersistedJpaBundleProvider provider = new PersistedJpaBundleProvider(theId, theDao);
+ if (!provider.ensureSearchEntityLoaded()) {
+ return null;
}
- return retVal;
+ return provider;
}
@Override
public synchronized String storeResultList(IBundleProvider theList) {
- if (theList instanceof PersistedJpaBundleProvider) {
- return ((PersistedJpaBundleProvider)theList).getSearchUuid();
- }
- return super.storeResultList(theList);
+ String uuid = theList.getUuid();
+ Validate.notNull(uuid);
+ return uuid;
}
}
diff --git a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java
index f9fd48f57af..4d1c15cae53 100644
--- a/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java
+++ b/hapi-fhir-jpaserver-base/src/main/java/ca/uhn/fhir/jpa/search/PersistedJpaBundleProvider.java
@@ -19,13 +19,7 @@ package ca.uhn.fhir.jpa.search;
* limitations under the License.
* #L%
*/
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
@@ -49,11 +43,7 @@ import ca.uhn.fhir.jpa.dao.IDao;
import ca.uhn.fhir.jpa.dao.SearchBuilder;
import ca.uhn.fhir.jpa.dao.data.ISearchDao;
import ca.uhn.fhir.jpa.dao.data.ISearchResultDao;
-import ca.uhn.fhir.jpa.entity.BaseHasResource;
-import ca.uhn.fhir.jpa.entity.ResourceHistoryTable;
-import ca.uhn.fhir.jpa.entity.Search;
-import ca.uhn.fhir.jpa.entity.SearchResult;
-import ca.uhn.fhir.jpa.entity.SearchTypeEnum;
+import ca.uhn.fhir.jpa.entity.*;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.server.IBundleProvider;
@@ -220,7 +210,7 @@ public final class PersistedJpaBundleProvider implements IBundleProvider {
});
}
- public String getSearchUuid() {
+ public String getUuid() {
return myUuid;
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java
index d589746e7a8..00b6ebccd30 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirResourceDaoDstu2ValidateTest.java
@@ -32,6 +32,7 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
+import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.TestUtil;
public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
@@ -161,7 +162,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
try {
myPatientDao.validate(pat, null, null, null, ValidationModeEnum.CREATE, null, mySrd);
fail();
- } catch (InvalidRequestException e) {
+ } catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("ID must not be populated"));
}
@@ -184,7 +185,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
try {
myPatientDao.validate(pat, null, null, null, ValidationModeEnum.UPDATE, null, mySrd);
fail();
- } catch (InvalidRequestException e) {
+ } catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("ID must be populated"));
}
@@ -207,7 +208,7 @@ public class FhirResourceDaoDstu2ValidateTest extends BaseJpaDstu2Test {
try {
myPatientDao.validate(pat, null, null, null, ValidationModeEnum.UPDATE, null, mySrd);
fail();
- } catch (InvalidRequestException e) {
+ } catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("ID must be populated"));
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirSystemDaoDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirSystemDaoDstu2Test.java
index 113709d8c6a..bd77c162878 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirSystemDaoDstu2Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu2/FhirSystemDaoDstu2Test.java
@@ -19,10 +19,12 @@ import static org.mockito.Mockito.verify;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
+import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Test;
@@ -73,6 +75,43 @@ public class FhirSystemDaoDstu2Test extends BaseJpaDstu2SystemTest {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirSystemDaoDstu2Test.class);
+ /**
+ * Per a message on the mailing list
+ */
+ @Test
+ public void testTransactionWithPostDoesntUpdate() throws Exception {
+
+ // First bundle (name is Joshua)
+
+ String input = IOUtils.toString(getClass().getResource("/dstu3-post1.xml"), StandardCharsets.UTF_8);
+ Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
+ Bundle response = mySystemDao.transaction(mySrd, request);
+ ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
+
+ assertEquals(1, response.getEntry().size());
+ assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
+ assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
+ String id = response.getEntry().get(0).getResponse().getLocation();
+
+ // Now the second (name is Adam, shouldn't get used)
+
+ input = IOUtils.toString(getClass().getResource("/dstu3-post2.xml"), StandardCharsets.UTF_8);
+ request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
+ response = mySystemDao.transaction(mySrd, request);
+ ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
+
+ assertEquals(1, response.getEntry().size());
+ assertEquals("200 OK", response.getEntry().get(0).getResponse().getStatus());
+ assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
+ String id2 = response.getEntry().get(0).getResponse().getLocation();
+ assertEquals(id, id2);
+
+ Patient patient = myPatientDao.read(new IdType(id), mySrd);
+ ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
+ assertEquals("Joshua", patient.getNameFirstRep().getGivenAsSingleString());
+ }
+
+
@Test
public void testReindexing() {
Patient p = new Patient();
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java
index 501264d3476..ddfd3744dae 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3SearchCustomSearchParamTest.java
@@ -1,7 +1,6 @@
package ca.uhn.fhir.jpa.dao.dstu3;
import static org.hamcrest.Matchers.contains;
-import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.empty;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
@@ -9,9 +8,11 @@ import static org.junit.Assert.fail;
import java.util.List;
+import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
import org.hl7.fhir.dstu3.model.Patient;
import org.hl7.fhir.dstu3.model.SearchParameter;
+import org.hl7.fhir.dstu3.model.StringType;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.Test;
@@ -19,7 +20,6 @@ import org.junit.Test;
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.IBundleProvider;
-import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.TestUtil;
@@ -29,6 +29,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
@Test
public void testCreateInvalidParamInvalidResourceName() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -43,9 +44,27 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
}
}
+ @Test
+ public void testCreateInvalidNoBase() {
+ SearchParameter fooSp = new SearchParameter();
+ fooSp.setCode("foo");
+ fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
+ fooSp.setTitle("FOO SP");
+ fooSp.setExpression("Patient.gender");
+ fooSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
+ fooSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
+ try {
+ mySearchParameterDao.create(fooSp, mySrd);
+ fail();
+ } catch (UnprocessableEntityException e) {
+ assertEquals("SearchParameter.base is missing", e.getMessage());
+ }
+ }
+
@Test
public void testCreateInvalidParamMismatchedResourceName() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -63,6 +82,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
@Test
public void testCreateInvalidParamNoPath() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -79,6 +99,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
@Test
public void testCreateInvalidParamNoResourceName() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -97,6 +118,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
public void testCreateInvalidParamParamNullStatus() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -112,10 +134,65 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
}
+ @Test
+ public void testExtensionWithNoValueIndexesWithoutFailure() {
+ SearchParameter eyeColourSp = new SearchParameter();
+ eyeColourSp.addBase("Patient");
+ eyeColourSp.setCode("eyecolour");
+ eyeColourSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
+ eyeColourSp.setTitle("Eye Colour");
+ eyeColourSp.setExpression("Patient.extension('http://acme.org/eyecolour')");
+ eyeColourSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
+ eyeColourSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
+ mySearchParameterDao.create(eyeColourSp, mySrd);
+
+ mySearchParamRegsitry.forceRefresh();
+
+ Patient p1 = new Patient();
+ p1.setActive(true);
+ p1.addExtension().setUrl("http://acme.org/eyecolour").addExtension().setUrl("http://foo").setValue(new StringType("VAL"));
+ IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless();
+
+ }
+
+ @Test
+ public void testSearchForExtension() {
+ SearchParameter eyeColourSp = new SearchParameter();
+ eyeColourSp.addBase("Patient");
+ eyeColourSp.setCode("eyecolour");
+ eyeColourSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
+ eyeColourSp.setTitle("Eye Colour");
+ eyeColourSp.setExpression("Patient.extension('http://acme.org/eyecolour')");
+ eyeColourSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
+ eyeColourSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
+ mySearchParameterDao.create(eyeColourSp, mySrd);
+
+ mySearchParamRegsitry.forceRefresh();
+
+ Patient p1 = new Patient();
+ p1.setActive(true);
+ p1.addExtension().setUrl("http://acme.org/eyecolour").setValue(new CodeType("blue"));
+ IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless();
+
+ Patient p2 = new Patient();
+ p2.setActive(true);
+ p2.addExtension().setUrl("http://acme.org/eyecolour").setValue(new CodeType("green"));
+ IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless();
+
+ // Try with custom gender SP
+ SearchParameterMap map = new SearchParameterMap();
+ map.add("eyecolour", new TokenParam(null, "blue"));
+ IBundleProvider results = myPatientDao.search(map);
+ List foundResources = toUnqualifiedVersionlessIdValues(results);
+ assertThat(foundResources, contains(p1id.getValue()));
+
+ }
+
@Test
public void testSearchWithCustomParam() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -154,7 +231,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
// Delete the param
mySearchParameterDao.delete(spId, mySrd);
-
+
mySearchParamRegsitry.forceRefresh();
mySystemDao.performReindexingPass(100);
@@ -169,6 +246,7 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
public void testSearchWithCustomParamDraft() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java
index 414622d3a30..06691b43a41 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3TerminologyTest.java
@@ -16,6 +16,7 @@ import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceCategory;
import org.hl7.fhir.dstu3.model.AllergyIntolerance.AllergyIntoleranceClinicalStatus;
import org.hl7.fhir.dstu3.model.CodeSystem.CodeSystemContentMode;
import org.hl7.fhir.dstu3.model.CodeSystem.ConceptDefinitionComponent;
+import org.hl7.fhir.dstu3.model.ValueSet.ConceptReferenceComponent;
import org.hl7.fhir.dstu3.model.ValueSet.ConceptSetComponent;
import org.hl7.fhir.dstu3.model.ValueSet.FilterOperator;
import org.hl7.fhir.dstu3.model.ValueSet.ValueSetComposeComponent;
@@ -53,6 +54,9 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
public static final String URL_MY_CODE_SYSTEM = "http://example.com/my_code_system";
public static final String URL_MY_VALUE_SET = "http://example.com/my_value_set";
+ @Autowired
+ private IHapiTerminologySvc myHapiTerminologySvc;
+
@After
public void after() {
myDaoConfig.setDeferIndexingForCodesystemsOfSize(new DaoConfig().getDeferIndexingForCodesystemsOfSize());
@@ -116,6 +120,37 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
createLocalVs(codeSystem);
}
+ private CodeSystem createExternalCsDogs() {
+ CodeSystem codeSystem = new CodeSystem();
+ codeSystem.setUrl(URL_MY_CODE_SYSTEM);
+ codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
+ IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
+
+ ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
+
+ TermCodeSystemVersion cs = new TermCodeSystemVersion();
+ cs.setResource(table);
+ cs.setResourceVersionId(table.getVersion());
+
+ TermConcept hello = new TermConcept(cs, "hello").setDisplay("Hello");
+ cs.getConcepts().add(hello);
+
+ TermConcept goodbye = new TermConcept(cs, "goodbye").setDisplay("Goodbye");
+ cs.getConcepts().add(goodbye);
+
+ TermConcept dogs = new TermConcept(cs, "dogs").setDisplay("Dogs");
+ cs.getConcepts().add(dogs);
+
+ TermConcept labrador = new TermConcept(cs, "labrador").setDisplay("Labrador");
+ dogs.addChild(labrador, RelationshipTypeEnum.ISA);
+
+ TermConcept beagle = new TermConcept(cs, "beagle").setDisplay("Beagle");
+ dogs.addChild(beagle, RelationshipTypeEnum.ISA);
+
+ myTermSvc.storeNewCodeSystemVersion(table.getId(), URL_MY_CODE_SYSTEM, cs);
+ return codeSystem;
+ }
+
private void createLocalCsAndVs() {
//@formatter:off
CodeSystem codeSystem = new CodeSystem();
@@ -144,6 +179,22 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
myValueSetDao.create(valueSet, mySrd);
}
+ private void logAndValidateValueSet(ValueSet theResult) {
+ IParser parser = myFhirCtx.newXmlParser().setPrettyPrint(true);
+ String encoded = parser.encodeResourceToString(theResult);
+ ourLog.info(encoded);
+
+ FhirValidator validator = myFhirCtx.newValidator();
+ validator.setValidateAgainstStandardSchema(true);
+ validator.setValidateAgainstStandardSchematron(true);
+ ValidationResult result = validator.validateWithResult(theResult);
+
+ if (!result.isSuccessful()) {
+ ourLog.info(parser.encodeResourceToString(result.toOperationOutcome()));
+ fail(parser.encodeResourceToString(result.toOperationOutcome()));
+ }
+ }
+
@Test
public void testCodeSystemCreateDuplicateFails() {
CodeSystem codeSystem = new CodeSystem();
@@ -162,28 +213,6 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
}
- @Test
- public void testLookupSnomed() {
- CodeSystem codeSystem = new CodeSystem();
- codeSystem.setUrl("http://snomed.info/sct");
- codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
- IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
-
- ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
-
- TermCodeSystemVersion cs = new TermCodeSystemVersion();
- cs.setResource(table);
- cs.setResourceVersionId(table.getVersion());
- TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
- cs.getConcepts().add(parentA);
- myTermSvc.storeNewCodeSystemVersion(table.getId(), "http://snomed.info/sct", cs);
-
- StringType code = new StringType("ParentA");
- StringType system = new StringType("http://snomed.info/sct");
- LookupCodeResult outcome = myCodeSystemDao.lookupCode(code, system, null, mySrd);
- assertEquals(true, outcome.isFound());
- }
-
@Test
public void testCodeSystemWithDefinedCodes() {
//@formatter:off
@@ -207,170 +236,6 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
- @Test
- public void testExpandWithExcludeInExternalValueSet() {
- createExternalCsAndLocalVs();
-
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
-
- ConceptSetComponent exclude = vs.getCompose().addExclude();
- exclude.setSystem(URL_MY_CODE_SYSTEM);
- exclude.addConcept().setCode("childAA");
- exclude.addConcept().setCode("childAAA");
-
- ValueSet result = myValueSetDao.expand(vs, null);
- logAndValidateValueSet(result);
-
- ArrayList codes = toCodesContains(result.getExpansion().getContains());
- assertThat(codes, containsInAnyOrder("ParentA", "ParentB", "childAB", "childAAB", "ParentC", "childBA", "childCA"));
- }
-
- private void logAndValidateValueSet(ValueSet theResult) {
- IParser parser = myFhirCtx.newXmlParser().setPrettyPrint(true);
- String encoded = parser.encodeResourceToString(theResult);
- ourLog.info(encoded);
-
- FhirValidator validator = myFhirCtx.newValidator();
- validator.setValidateAgainstStandardSchema(true);
- validator.setValidateAgainstStandardSchematron(true);
- ValidationResult result = validator.validateWithResult(theResult);
-
- if (!result.isSuccessful()) {
- ourLog.info(parser.encodeResourceToString(result.toOperationOutcome()));
- fail(parser.encodeResourceToString(result.toOperationOutcome()));
- }
- }
-
- @Test
- public void testExpandWithInvalidExclude() {
- createExternalCsAndLocalVs();
-
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
-
- /*
- * No system set on exclude
- */
- ConceptSetComponent exclude = vs.getCompose().addExclude();
- exclude.addConcept().setCode("childAA");
- exclude.addConcept().setCode("childAAA");
- try {
- myValueSetDao.expand(vs, null);
- fail();
- } catch (InvalidRequestException e) {
- assertEquals("ValueSet contains exclude criteria with no system defined", e.getMessage());
- }
- }
-
- @Test
- public void testExpandWithNoResultsInLocalValueSet1() {
- createLocalCsAndVs();
-
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
- include.addConcept().setCode("ZZZZ");
-
- try {
- myValueSetDao.expand(vs, null);
- fail();
- } catch (InvalidRequestException e) {
- assertEquals("Unable to find code 'ZZZZ' in code system http://example.com/my_code_system", e.getMessage());
- }
-
- }
-
- @Test
- public void testReindex() {
- createLocalCsAndVs();
-
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
- include.addConcept().setCode("ZZZZ");
-
- mySystemDao.markAllResourcesForReindexing();
- mySystemDao.performReindexingPass(null);
- myTermSvc.saveDeferred();
- mySystemDao.performReindexingPass(null);
- myTermSvc.saveDeferred();
-
- // Again
- mySystemDao.markAllResourcesForReindexing();
- mySystemDao.performReindexingPass(null);
- myTermSvc.saveDeferred();
- mySystemDao.performReindexingPass(null);
- myTermSvc.saveDeferred();
-
- }
-
- @Test
- public void testExpandWithNoResultsInLocalValueSet2() {
- createLocalCsAndVs();
-
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM + "AA");
- include.addConcept().setCode("A");
-
- try {
- myValueSetDao.expand(vs, null);
- fail();
- } catch (InvalidRequestException e) {
- assertEquals("unable to find code system http://example.com/my_code_systemAA", e.getMessage());
- }
- }
-
- @Test
- public void testExpandWithIsAInExternalValueSet() {
- createExternalCsAndLocalVs();
-
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
- include.addFilter().setOp(FilterOperator.ISA).setValue("childAA").setProperty("concept");
-
- ValueSet result = myValueSetDao.expand(vs, null);
- logAndValidateValueSet(result);
-
- ArrayList codes = toCodesContains(result.getExpansion().getContains());
- assertThat(codes, containsInAnyOrder("childAAA", "childAAB"));
-
- }
-
- @Autowired
- private IHapiTerminologySvc myHapiTerminologySvc;
-
- @Test
- public void testExpandWithIsAInExternalValueSetReindex() {
- BaseHapiTerminologySvc.setForceSaveDeferredAlwaysForUnitTest(true);
-
- createExternalCsAndLocalVs();
-
- mySystemDao.markAllResourcesForReindexing();
-
- mySystemDao.performReindexingPass(100);
- mySystemDao.performReindexingPass(100);
- myHapiTerminologySvc.saveDeferred();
- myHapiTerminologySvc.saveDeferred();
- myHapiTerminologySvc.saveDeferred();
-
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
- include.addFilter().setOp(FilterOperator.ISA).setValue("childAA").setProperty("concept");
-
- ValueSet result = myValueSetDao.expand(vs, null);
- logAndValidateValueSet(result);
-
- ArrayList codes = toCodesContains(result.getExpansion().getContains());
- assertThat(codes, containsInAnyOrder("childAAA", "childAAB"));
-
- }
-
@Test
public void testExpandInvalid() {
createExternalCsAndLocalVs();
@@ -390,43 +255,110 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
@Test
- public void testExpandWithSystemAndCodesInExternalValueSet() {
- createExternalCsAndLocalVs();
+ public void testExpandWithCodesAndDisplayFilterBlank() {
+ CodeSystem codeSystem = createExternalCsDogs();
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
- include.addConcept().setCode("ParentA");
- include.addConcept().setCode("childAA");
- include.addConcept().setCode("childAAA");
+ ValueSet valueSet = new ValueSet();
+ valueSet.setUrl(URL_MY_VALUE_SET);
+ valueSet.getCompose()
+ .addInclude()
+ .setSystem(codeSystem.getUrl())
+ .addConcept(new ConceptReferenceComponent().setCode("hello"))
+ .addConcept(new ConceptReferenceComponent().setCode("goodbye"));
+ valueSet.getCompose()
+ .addInclude()
+ .setSystem(codeSystem.getUrl())
+ .addFilter()
+ .setProperty("concept")
+ .setOp(FilterOperator.ISA)
+ .setValue("dogs");
+
+ myValueSetDao.create(valueSet, mySrd);
- ValueSet result = myValueSetDao.expand(vs, null);
+ ValueSet result = myValueSetDao.expand(valueSet, "");
logAndValidateValueSet(result);
+ assertEquals(4, result.getExpansion().getTotal());
ArrayList codes = toCodesContains(result.getExpansion().getContains());
- assertThat(codes, containsInAnyOrder("ParentA", "childAA", "childAAA"));
+ assertThat(codes, containsInAnyOrder("hello", "goodbye", "labrador", "beagle"));
- int idx = codes.indexOf("childAA");
- assertEquals("childAA", result.getExpansion().getContains().get(idx).getCode());
- assertEquals("Child AA", result.getExpansion().getContains().get(idx).getDisplay());
- assertEquals(URL_MY_CODE_SYSTEM, result.getExpansion().getContains().get(idx).getSystem());
}
@Test
- public void testExpandWithSystemAndFilterInExternalValueSet() {
- createExternalCsAndLocalVs();
+ public void testExpandWithCodesAndDisplayFilterPartialOnFilter() {
+ CodeSystem codeSystem = createExternalCsDogs();
- ValueSet vs = new ValueSet();
- ConceptSetComponent include = vs.getCompose().addInclude();
- include.setSystem(URL_MY_CODE_SYSTEM);
+ ValueSet valueSet = new ValueSet();
+ valueSet.setUrl(URL_MY_VALUE_SET);
+ valueSet.getCompose()
+ .addInclude()
+ .setSystem(codeSystem.getUrl())
+ .addConcept(new ConceptReferenceComponent().setCode("hello"))
+ .addConcept(new ConceptReferenceComponent().setCode("goodbye"));
+ valueSet.getCompose()
+ .addInclude()
+ .setSystem(codeSystem.getUrl())
+ .addFilter()
+ .setProperty("concept")
+ .setOp(FilterOperator.ISA)
+ .setValue("dogs");
+
+ myValueSetDao.create(valueSet, mySrd);
- include.addFilter().setProperty("display").setOp(FilterOperator.EQUAL).setValue("Parent B");
-
- ValueSet result = myValueSetDao.expand(vs, null);
+ ValueSet result = myValueSetDao.expand(valueSet, "lab");
logAndValidateValueSet(result);
+ assertEquals(1, result.getExpansion().getTotal());
ArrayList codes = toCodesContains(result.getExpansion().getContains());
- assertThat(codes, containsInAnyOrder("ParentB"));
+ assertThat(codes, containsInAnyOrder("labrador"));
+
+ }
+
+ @Test
+ public void testExpandWithCodesAndDisplayFilterPartialOnCodes() {
+ CodeSystem codeSystem = createExternalCsDogs();
+
+ ValueSet valueSet = new ValueSet();
+ valueSet.setUrl(URL_MY_VALUE_SET);
+ valueSet.getCompose()
+ .addInclude()
+ .setSystem(codeSystem.getUrl())
+ .addConcept(new ConceptReferenceComponent().setCode("hello"))
+ .addConcept(new ConceptReferenceComponent().setCode("goodbye"));
+ valueSet.getCompose()
+ .addInclude()
+ .setSystem(codeSystem.getUrl())
+ .addFilter()
+ .setProperty("concept")
+ .setOp(FilterOperator.ISA)
+ .setValue("dogs");
+
+ myValueSetDao.create(valueSet, mySrd);
+
+ ValueSet result = myValueSetDao.expand(valueSet, "hel");
+ logAndValidateValueSet(result);
+
+ assertEquals(1, result.getExpansion().getTotal());
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("hello"));
+
+ }
+
+ @Test
+ public void testExpandWithCodesAndDisplayFilterPartialOnExpansion() {
+ CodeSystem codeSystem = createExternalCsDogs();
+
+ ValueSet valueSet = new ValueSet();
+ valueSet.setUrl(URL_MY_VALUE_SET);
+ valueSet.getCompose().addInclude().setSystem(codeSystem.getUrl());
+ myValueSetDao.create(valueSet, mySrd);
+
+ ValueSet result = myValueSetDao.expand(valueSet, "lab");
+ logAndValidateValueSet(result);
+
+ assertEquals(1, result.getExpansion().getTotal());
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("labrador"));
}
@@ -463,6 +395,127 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
+ @Test
+ public void testExpandWithExcludeInExternalValueSet() {
+ createExternalCsAndLocalVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+
+ ConceptSetComponent exclude = vs.getCompose().addExclude();
+ exclude.setSystem(URL_MY_CODE_SYSTEM);
+ exclude.addConcept().setCode("childAA");
+ exclude.addConcept().setCode("childAAA");
+
+ ValueSet result = myValueSetDao.expand(vs, null);
+ logAndValidateValueSet(result);
+
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("ParentA", "ParentB", "childAB", "childAAB", "ParentC", "childBA", "childCA"));
+ }
+
+ @Test
+ public void testExpandWithInvalidExclude() {
+ createExternalCsAndLocalVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+
+ /*
+ * No system set on exclude
+ */
+ ConceptSetComponent exclude = vs.getCompose().addExclude();
+ exclude.addConcept().setCode("childAA");
+ exclude.addConcept().setCode("childAAA");
+ try {
+ myValueSetDao.expand(vs, null);
+ fail();
+ } catch (InvalidRequestException e) {
+ assertEquals("ValueSet contains exclude criteria with no system defined", e.getMessage());
+ }
+ }
+
+ @Test
+ public void testExpandWithIsAInExternalValueSet() {
+ createExternalCsAndLocalVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+ include.addFilter().setOp(FilterOperator.ISA).setValue("childAA").setProperty("concept");
+
+ ValueSet result = myValueSetDao.expand(vs, null);
+ logAndValidateValueSet(result);
+
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("childAAA", "childAAB"));
+
+ }
+
+ @Test
+ public void testExpandWithIsAInExternalValueSetReindex() {
+ BaseHapiTerminologySvc.setForceSaveDeferredAlwaysForUnitTest(true);
+
+ createExternalCsAndLocalVs();
+
+ mySystemDao.markAllResourcesForReindexing();
+
+ mySystemDao.performReindexingPass(100);
+ mySystemDao.performReindexingPass(100);
+ myHapiTerminologySvc.saveDeferred();
+ myHapiTerminologySvc.saveDeferred();
+ myHapiTerminologySvc.saveDeferred();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+ include.addFilter().setOp(FilterOperator.ISA).setValue("childAA").setProperty("concept");
+
+ ValueSet result = myValueSetDao.expand(vs, null);
+ logAndValidateValueSet(result);
+
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("childAAA", "childAAB"));
+
+ }
+
+ @Test
+ public void testExpandWithNoResultsInLocalValueSet1() {
+ createLocalCsAndVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+ include.addConcept().setCode("ZZZZ");
+
+ try {
+ myValueSetDao.expand(vs, null);
+ fail();
+ } catch (InvalidRequestException e) {
+ assertEquals("Unable to find code 'ZZZZ' in code system http://example.com/my_code_system", e.getMessage());
+ }
+
+ }
+
+ @Test
+ public void testExpandWithNoResultsInLocalValueSet2() {
+ createLocalCsAndVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM + "AA");
+ include.addConcept().setCode("A");
+
+ try {
+ myValueSetDao.expand(vs, null);
+ fail();
+ } catch (InvalidRequestException e) {
+ assertEquals("unable to find code system http://example.com/my_code_systemAA", e.getMessage());
+ }
+ }
+
@Test
public void testExpandWithSystemAndCodesAndFilterKeywordInLocalValueSet() {
createLocalCsAndVs();
@@ -493,6 +546,29 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
//
}
+ @Test
+ public void testExpandWithSystemAndCodesInExternalValueSet() {
+ createExternalCsAndLocalVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+ include.addConcept().setCode("ParentA");
+ include.addConcept().setCode("childAA");
+ include.addConcept().setCode("childAAA");
+
+ ValueSet result = myValueSetDao.expand(vs, null);
+ logAndValidateValueSet(result);
+
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("ParentA", "childAA", "childAAA"));
+
+ int idx = codes.indexOf("childAA");
+ assertEquals("childAA", result.getExpansion().getContains().get(idx).getCode());
+ assertEquals("Child AA", result.getExpansion().getContains().get(idx).getDisplay());
+ assertEquals(URL_MY_CODE_SYSTEM, result.getExpansion().getContains().get(idx).getSystem());
+ }
+
@Test
public void testExpandWithSystemAndCodesInLocalValueSet() {
createLocalCsAndVs();
@@ -520,6 +596,43 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
//
}
+ @Test
+ public void testExpandWithSystemAndDisplayFilterBlank() {
+ CodeSystem codeSystem = createExternalCsDogs();
+
+ ValueSet valueSet = new ValueSet();
+ valueSet.setUrl(URL_MY_VALUE_SET);
+ valueSet.getCompose()
+ .addInclude()
+ .setSystem(codeSystem.getUrl());
+
+ ValueSet result = myValueSetDao.expand(valueSet, "");
+ logAndValidateValueSet(result);
+
+ assertEquals(5, result.getExpansion().getTotal());
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("hello", "goodbye", "dogs", "labrador", "beagle"));
+
+ }
+
+ @Test
+ public void testExpandWithSystemAndFilterInExternalValueSet() {
+ createExternalCsAndLocalVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+
+ include.addFilter().setProperty("display").setOp(FilterOperator.EQUAL).setValue("Parent B");
+
+ ValueSet result = myValueSetDao.expand(vs, null);
+ logAndValidateValueSet(result);
+
+ ArrayList codes = toCodesContains(result.getExpansion().getContains());
+ assertThat(codes, containsInAnyOrder("ParentB"));
+
+ }
+
@Test
public void testIndexingIsDeferredForLargeCodeSystems() {
myDaoConfig.setDeferIndexingForCodesystemsOfSize(1);
@@ -560,6 +673,28 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
assertThat(encoded, containsStringIgnoringCase(""));
}
+ @Test
+ public void testLookupSnomed() {
+ CodeSystem codeSystem = new CodeSystem();
+ codeSystem.setUrl("http://snomed.info/sct");
+ codeSystem.setContent(CodeSystemContentMode.NOTPRESENT);
+ IIdType id = myCodeSystemDao.create(codeSystem, mySrd).getId().toUnqualified();
+
+ ResourceTable table = myResourceTableDao.findOne(id.getIdPartAsLong());
+
+ TermCodeSystemVersion cs = new TermCodeSystemVersion();
+ cs.setResource(table);
+ cs.setResourceVersionId(table.getVersion());
+ TermConcept parentA = new TermConcept(cs, "ParentA").setDisplay("Parent A");
+ cs.getConcepts().add(parentA);
+ myTermSvc.storeNewCodeSystemVersion(table.getId(), "http://snomed.info/sct", cs);
+
+ StringType code = new StringType("ParentA");
+ StringType system = new StringType("http://snomed.info/sct");
+ LookupCodeResult outcome = myCodeSystemDao.lookupCode(code, system, null, mySrd);
+ assertEquals(true, outcome.isFound());
+ }
+
/**
* Can't currently abort costly
*/
@@ -594,6 +729,30 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
}
+ @Test
+ public void testReindex() {
+ createLocalCsAndVs();
+
+ ValueSet vs = new ValueSet();
+ ConceptSetComponent include = vs.getCompose().addInclude();
+ include.setSystem(URL_MY_CODE_SYSTEM);
+ include.addConcept().setCode("ZZZZ");
+
+ mySystemDao.markAllResourcesForReindexing();
+ mySystemDao.performReindexingPass(null);
+ myTermSvc.saveDeferred();
+ mySystemDao.performReindexingPass(null);
+ myTermSvc.saveDeferred();
+
+ // Again
+ mySystemDao.markAllResourcesForReindexing();
+ mySystemDao.performReindexingPass(null);
+ myTermSvc.saveDeferred();
+ mySystemDao.performReindexingPass(null);
+ myTermSvc.saveDeferred();
+
+ }
+
@Test
public void testSearchCodeAboveLocalCodesystem() {
createLocalCsAndVs();
@@ -636,107 +795,6 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
- @Test
- public void testSearchCodeBelowLocalCodesystem() {
- createLocalCsAndVs();
-
- Observation obsAA = new Observation();
- obsAA.getCode().addCoding().setSystem(URL_MY_CODE_SYSTEM).setCode("AA");
- IIdType idAA = myObservationDao.create(obsAA, mySrd).getId().toUnqualifiedVersionless();
-
- Observation obsBA = new Observation();
- obsBA.getCode().addCoding().setSystem(URL_MY_CODE_SYSTEM).setCode("BA");
- IIdType idBA = myObservationDao.create(obsBA, mySrd).getId().toUnqualifiedVersionless();
-
- Observation obsCA = new Observation();
- obsCA.getCode().addCoding().setSystem(URL_MY_CODE_SYSTEM).setCode("CA");
- IIdType idCA = myObservationDao.create(obsCA, mySrd).getId().toUnqualifiedVersionless();
-
- SearchParameterMap params = new SearchParameterMap();
- params.add(Observation.SP_CODE, new TokenParam(URL_MY_CODE_SYSTEM, "A").setModifier(TokenParamModifier.BELOW));
- assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(params)), containsInAnyOrder(idAA.getValue()));
-
- params = new SearchParameterMap();
- params.add(Observation.SP_CODE, new TokenParam(URL_MY_CODE_SYSTEM, "AAA").setModifier(TokenParamModifier.BELOW));
- assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(params)), empty());
-
- }
-
- @Test
- public void testSearchCodeInBuiltInValueSet() {
- AllergyIntolerance ai1 = new AllergyIntolerance();
- ai1.setClinicalStatus(AllergyIntoleranceClinicalStatus.ACTIVE);
- String id1 = myAllergyIntoleranceDao.create(ai1, mySrd).getId().toUnqualifiedVersionless().getValue();
-
- AllergyIntolerance ai2 = new AllergyIntolerance();
- ai2.setClinicalStatus(AllergyIntoleranceClinicalStatus.RESOLVED);
- String id2 = myAllergyIntoleranceDao.create(ai2, mySrd).getId().toUnqualifiedVersionless().getValue();
-
- AllergyIntolerance ai3 = new AllergyIntolerance();
- ai3.setClinicalStatus(AllergyIntoleranceClinicalStatus.INACTIVE);
- String id3 = myAllergyIntoleranceDao.create(ai3, mySrd).getId().toUnqualifiedVersionless().getValue();
-
- SearchParameterMap params;
- params = new SearchParameterMap();
- params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-clinical-status").setModifier(TokenParamModifier.IN));
- assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1, id2, id3));
-
- // No codes in this one
- params = new SearchParameterMap();
- params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-intolerance-criticality").setModifier(TokenParamModifier.IN));
- assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
-
- // Invalid VS
- params = new SearchParameterMap();
- params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/FOO").setModifier(TokenParamModifier.IN));
- try {
- myAllergyIntoleranceDao.search(params);
- } catch (InvalidRequestException e) {
- assertEquals("Unable to find imported value set http://hl7.org/fhir/ValueSet/FOO", e.getMessage());
- }
-
- }
-
-
- /**
- * Todo: not yet implemented
- */
- @Test
- @Ignore
- public void testSearchCodeNotInBuiltInValueSet() {
- AllergyIntolerance ai1 = new AllergyIntolerance();
- ai1.setClinicalStatus(AllergyIntoleranceClinicalStatus.ACTIVE);
- String id1 = myAllergyIntoleranceDao.create(ai1, mySrd).getId().toUnqualifiedVersionless().getValue();
-
- AllergyIntolerance ai2 = new AllergyIntolerance();
- ai2.setClinicalStatus(AllergyIntoleranceClinicalStatus.RESOLVED);
- String id2 = myAllergyIntoleranceDao.create(ai2, mySrd).getId().toUnqualifiedVersionless().getValue();
-
- AllergyIntolerance ai3 = new AllergyIntolerance();
- ai3.setClinicalStatus(AllergyIntoleranceClinicalStatus.INACTIVE);
- String id3 = myAllergyIntoleranceDao.create(ai3, mySrd).getId().toUnqualifiedVersionless().getValue();
-
- SearchParameterMap params;
- params = new SearchParameterMap();
- params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-intolerance-status").setModifier(TokenParamModifier.NOT_IN));
- assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
-
- // No codes in this one
- params = new SearchParameterMap();
- params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-intolerance-criticality").setModifier(TokenParamModifier.NOT_IN));
- assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1, id2, id3));
-
- // Invalid VS
- params = new SearchParameterMap();
- params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/FOO").setModifier(TokenParamModifier.NOT_IN));
- try {
- myAllergyIntoleranceDao.search(params);
- } catch (InvalidRequestException e) {
- assertEquals("Unable to find imported value set http://hl7.org/fhir/ValueSet/FOO", e.getMessage());
- }
-
- }
-
@Test
public void testSearchCodeBelowBuiltInCodesystem() {
AllergyIntolerance ai1 = new AllergyIntolerance();
@@ -824,6 +882,68 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
+
+ @Test
+ public void testSearchCodeBelowLocalCodesystem() {
+ createLocalCsAndVs();
+
+ Observation obsAA = new Observation();
+ obsAA.getCode().addCoding().setSystem(URL_MY_CODE_SYSTEM).setCode("AA");
+ IIdType idAA = myObservationDao.create(obsAA, mySrd).getId().toUnqualifiedVersionless();
+
+ Observation obsBA = new Observation();
+ obsBA.getCode().addCoding().setSystem(URL_MY_CODE_SYSTEM).setCode("BA");
+ IIdType idBA = myObservationDao.create(obsBA, mySrd).getId().toUnqualifiedVersionless();
+
+ Observation obsCA = new Observation();
+ obsCA.getCode().addCoding().setSystem(URL_MY_CODE_SYSTEM).setCode("CA");
+ IIdType idCA = myObservationDao.create(obsCA, mySrd).getId().toUnqualifiedVersionless();
+
+ SearchParameterMap params = new SearchParameterMap();
+ params.add(Observation.SP_CODE, new TokenParam(URL_MY_CODE_SYSTEM, "A").setModifier(TokenParamModifier.BELOW));
+ assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(params)), containsInAnyOrder(idAA.getValue()));
+
+ params = new SearchParameterMap();
+ params.add(Observation.SP_CODE, new TokenParam(URL_MY_CODE_SYSTEM, "AAA").setModifier(TokenParamModifier.BELOW));
+ assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(params)), empty());
+
+ }
+
+ @Test
+ public void testSearchCodeInBuiltInValueSet() {
+ AllergyIntolerance ai1 = new AllergyIntolerance();
+ ai1.setClinicalStatus(AllergyIntoleranceClinicalStatus.ACTIVE);
+ String id1 = myAllergyIntoleranceDao.create(ai1, mySrd).getId().toUnqualifiedVersionless().getValue();
+
+ AllergyIntolerance ai2 = new AllergyIntolerance();
+ ai2.setClinicalStatus(AllergyIntoleranceClinicalStatus.RESOLVED);
+ String id2 = myAllergyIntoleranceDao.create(ai2, mySrd).getId().toUnqualifiedVersionless().getValue();
+
+ AllergyIntolerance ai3 = new AllergyIntolerance();
+ ai3.setClinicalStatus(AllergyIntoleranceClinicalStatus.INACTIVE);
+ String id3 = myAllergyIntoleranceDao.create(ai3, mySrd).getId().toUnqualifiedVersionless().getValue();
+
+ SearchParameterMap params;
+ params = new SearchParameterMap();
+ params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-clinical-status").setModifier(TokenParamModifier.IN));
+ assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1, id2, id3));
+
+ // No codes in this one
+ params = new SearchParameterMap();
+ params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-intolerance-criticality").setModifier(TokenParamModifier.IN));
+ assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
+
+ // Invalid VS
+ params = new SearchParameterMap();
+ params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/FOO").setModifier(TokenParamModifier.IN));
+ try {
+ myAllergyIntoleranceDao.search(params);
+ } catch (InvalidRequestException e) {
+ assertEquals("Unable to find imported value set http://hl7.org/fhir/ValueSet/FOO", e.getMessage());
+ }
+
+ }
+
@Test
public void testSearchCodeInEmptyValueSet() {
ValueSet valueSet = new ValueSet();
@@ -848,40 +968,6 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
ourLog.info("testSearchCodeInEmptyValueSet done");
}
- @Test
- public void testSearchCodeInValueSetThatImportsInvalidCodeSystem() {
- ValueSet valueSet = new ValueSet();
- valueSet.getCompose().addInclude().addValueSet("http://non_existant_VS");
- valueSet.setUrl(URL_MY_VALUE_SET);
- IIdType vsid = myValueSetDao.create(valueSet, mySrd).getId().toUnqualifiedVersionless();
-
- SearchParameterMap params;
-
- ourLog.info("testSearchCodeInEmptyValueSet without status");
-
- params = new SearchParameterMap();
- params.add(Observation.SP_CODE, new TokenParam(null, URL_MY_VALUE_SET).setModifier(TokenParamModifier.IN));
- try {
- myObservationDao.search(params);
- } catch(InvalidRequestException e) {
- assertEquals("Unable to expand imported value set: Unable to find imported value set http://non_existant_VS", e.getMessage());
- }
-
- // Now let's update
- valueSet = new ValueSet();
- valueSet.setId(vsid);
- valueSet.getCompose().addInclude().setSystem("http://hl7.org/fhir/v3/MaritalStatus").addConcept().setCode("A");
- valueSet.setUrl(URL_MY_VALUE_SET);
- myValueSetDao.update(valueSet, mySrd).getId().toUnqualifiedVersionless();
-
- params = new SearchParameterMap();
- params.add(Observation.SP_CODE, new TokenParam(null, URL_MY_VALUE_SET).setModifier(TokenParamModifier.IN));
- params.add(Observation.SP_STATUS, new TokenParam(null, "final"));
- assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(params)), empty());
-
- }
-
-
@Test
public void testSearchCodeInExternalCodesystem() {
createExternalCsAndLocalVs();
@@ -941,6 +1027,7 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
assertThat(toUnqualifiedVersionlessIdValues(myAuditEventDao.search(params)), empty());
}
+
@Test
public void testSearchCodeInLocalCodesystem() {
createLocalCsAndVs();
@@ -963,6 +1050,78 @@ public class FhirResourceDaoDstu3TerminologyTest extends BaseJpaDstu3Test {
}
+ @Test
+ public void testSearchCodeInValueSetThatImportsInvalidCodeSystem() {
+ ValueSet valueSet = new ValueSet();
+ valueSet.getCompose().addInclude().addValueSet("http://non_existant_VS");
+ valueSet.setUrl(URL_MY_VALUE_SET);
+ IIdType vsid = myValueSetDao.create(valueSet, mySrd).getId().toUnqualifiedVersionless();
+
+ SearchParameterMap params;
+
+ ourLog.info("testSearchCodeInEmptyValueSet without status");
+
+ params = new SearchParameterMap();
+ params.add(Observation.SP_CODE, new TokenParam(null, URL_MY_VALUE_SET).setModifier(TokenParamModifier.IN));
+ try {
+ myObservationDao.search(params);
+ } catch(InvalidRequestException e) {
+ assertEquals("Unable to expand imported value set: Unable to find imported value set http://non_existant_VS", e.getMessage());
+ }
+
+ // Now let's update
+ valueSet = new ValueSet();
+ valueSet.setId(vsid);
+ valueSet.getCompose().addInclude().setSystem("http://hl7.org/fhir/v3/MaritalStatus").addConcept().setCode("A");
+ valueSet.setUrl(URL_MY_VALUE_SET);
+ myValueSetDao.update(valueSet, mySrd).getId().toUnqualifiedVersionless();
+
+ params = new SearchParameterMap();
+ params.add(Observation.SP_CODE, new TokenParam(null, URL_MY_VALUE_SET).setModifier(TokenParamModifier.IN));
+ params.add(Observation.SP_STATUS, new TokenParam(null, "final"));
+ assertThat(toUnqualifiedVersionlessIdValues(myObservationDao.search(params)), empty());
+
+ }
+
+ /**
+ * Todo: not yet implemented
+ */
+ @Test
+ @Ignore
+ public void testSearchCodeNotInBuiltInValueSet() {
+ AllergyIntolerance ai1 = new AllergyIntolerance();
+ ai1.setClinicalStatus(AllergyIntoleranceClinicalStatus.ACTIVE);
+ String id1 = myAllergyIntoleranceDao.create(ai1, mySrd).getId().toUnqualifiedVersionless().getValue();
+
+ AllergyIntolerance ai2 = new AllergyIntolerance();
+ ai2.setClinicalStatus(AllergyIntoleranceClinicalStatus.RESOLVED);
+ String id2 = myAllergyIntoleranceDao.create(ai2, mySrd).getId().toUnqualifiedVersionless().getValue();
+
+ AllergyIntolerance ai3 = new AllergyIntolerance();
+ ai3.setClinicalStatus(AllergyIntoleranceClinicalStatus.INACTIVE);
+ String id3 = myAllergyIntoleranceDao.create(ai3, mySrd).getId().toUnqualifiedVersionless().getValue();
+
+ SearchParameterMap params;
+ params = new SearchParameterMap();
+ params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-intolerance-status").setModifier(TokenParamModifier.NOT_IN));
+ assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), empty());
+
+ // No codes in this one
+ params = new SearchParameterMap();
+ params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/allergy-intolerance-criticality").setModifier(TokenParamModifier.NOT_IN));
+ assertThat(toUnqualifiedVersionlessIdValues(myAllergyIntoleranceDao.search(params)), containsInAnyOrder(id1, id2, id3));
+
+ // Invalid VS
+ params = new SearchParameterMap();
+ params.add(AllergyIntolerance.SP_CLINICAL_STATUS, new TokenParam(null, "http://hl7.org/fhir/ValueSet/FOO").setModifier(TokenParamModifier.NOT_IN));
+ try {
+ myAllergyIntoleranceDao.search(params);
+ } catch (InvalidRequestException e) {
+ assertEquals("Unable to find imported value set http://hl7.org/fhir/ValueSet/FOO", e.getMessage());
+ }
+
+ }
+
private ArrayList toCodesContains(List theContains) {
ArrayList retVal = new ArrayList();
for (ValueSetExpansionContainsComponent next : theContains) {
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java
index 7673c4a24a0..a095433946d 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirResourceDaoDstu3ValidateTest.java
@@ -24,6 +24,7 @@ import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
import ca.uhn.fhir.rest.server.exceptions.PreconditionFailedException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
+import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.TestUtil;
public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
@@ -186,7 +187,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
try {
myPatientDao.validate(pat, null, null, null, ValidationModeEnum.CREATE, null, mySrd);
fail();
- } catch (InvalidRequestException e) {
+ } catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("ID must not be populated"));
}
@@ -209,7 +210,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
try {
myPatientDao.validate(pat, null, null, null, ValidationModeEnum.UPDATE, null, mySrd);
fail();
- } catch (InvalidRequestException e) {
+ } catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("ID must be populated"));
}
@@ -232,7 +233,7 @@ public class FhirResourceDaoDstu3ValidateTest extends BaseJpaDstu3Test {
try {
myPatientDao.validate(pat, null, null, null, ValidationModeEnum.UPDATE, null, mySrd);
fail();
- } catch (InvalidRequestException e) {
+ } catch (UnprocessableEntityException e) {
assertThat(e.getMessage(), containsString("ID must be populated"));
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java
index fe3db761a81..fe4555ea0a3 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/FhirSystemDaoDstu3Test.java
@@ -382,6 +382,42 @@ public class FhirSystemDaoDstu3Test extends BaseJpaDstu3SystemTest {
}
}
+ /**
+ * Per a message on the mailing list
+ */
+ @Test
+ public void testTransactionWithPostDoesntUpdate() throws Exception {
+
+ // First bundle (name is Joshua)
+
+ String input = IOUtils.toString(getClass().getResource("/dstu3-post1.xml"), StandardCharsets.UTF_8);
+ Bundle request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
+ Bundle response = mySystemDao.transaction(mySrd, request);
+ ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
+
+ assertEquals(1, response.getEntry().size());
+ assertEquals("201 Created", response.getEntry().get(0).getResponse().getStatus());
+ assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
+ String id = response.getEntry().get(0).getResponse().getLocation();
+
+ // Now the second (name is Adam, shouldn't get used)
+
+ input = IOUtils.toString(getClass().getResource("/dstu3-post2.xml"), StandardCharsets.UTF_8);
+ request = myFhirCtx.newXmlParser().parseResource(Bundle.class, input);
+ response = mySystemDao.transaction(mySrd, request);
+ ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(response));
+
+ assertEquals(1, response.getEntry().size());
+ assertEquals("200 OK", response.getEntry().get(0).getResponse().getStatus());
+ assertEquals("1", response.getEntry().get(0).getResponse().getEtag());
+ String id2 = response.getEntry().get(0).getResponse().getLocation();
+ assertEquals(id, id2);
+
+ Patient patient = myPatientDao.read(new IdType(id), mySrd);
+ ourLog.info(myFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(patient));
+ assertEquals("Joshua", patient.getNameFirstRep().getGivenAsSingleString());
+ }
+
@Test
public void testTransactionCreateInlineMatchUrlWithOneMatch() {
String methodName = "testTransactionCreateInlineMatchUrlWithOneMatch";
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java
index a15ff03eede..811c477e2cb 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/dao/dstu3/SearchParamExtractorDstu3Test.java
@@ -60,7 +60,7 @@ public class SearchParamExtractorDstu3Test {
}
@Override
- public Collection getAllSearchParams(String theResourceName) {
+ public Map> getActiveSearchParams() {
throw new UnsupportedOperationException();
}
};
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java
index df6f9ab9680..612adaf421e 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/ResourceProviderDstu2Test.java
@@ -2556,4 +2556,61 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
}
+ @Test
+ public void testValidateOnNoId() throws Exception {
+ HttpGet get = new HttpGet(ourServerBase + "/QuestionnaireResponse/$validate");
+ CloseableHttpResponse response = ourHttpClient.execute(get);
+ try {
+ String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
+ ourLog.info("Response: {}", responseString);
+ assertThat(responseString, containsString("No resource supplied for $validate operation"));
+ assertEquals(400, response.getStatusLine().getStatusCode());
+ } finally {
+ IOUtils.closeQuietly(response);
+ }
+
+ }
+
+ /**
+ * From a Skype message from Brian Postlethwaite
+ */
+ @Test
+ public void testValidateQuestionnaireResponseWithNoIdForCreate() throws Exception {
+
+ String input = "{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"mode\",\"valueString\":\"create\"},{\"name\":\"resource\",\"resource\":{\"resourceType\":\"QuestionnaireResponse\",\"questionnaire\":{\"reference\":\"http://fhirtest.uhn.ca/baseDstu2/Questionnaire/MedsCheckEligibility\"},\"text\":{\"status\":\"generated\",\"div\":\"!-- populated from the rendered HTML below -->
\"},\"status\":\"completed\",\"authored\":\"2017-02-10T00:02:58.098Z\",\"group\":{\"question\":[{\"linkId\":\"d94b4f57-1ca0-4d65-acba-8bd9a3926c8c\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has a valid Medicare or DVA entitlement card\"},{\"linkId\":\"0cbe66db-ff12-473a-940e-4672fb82de44\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has received a MedsCheck, Diabetes MedsCheck, Home Medicines Review (HMR) otr Restidential Medication Management Review (RMMR) in the past 12 months\"},{\"linkId\":\"35790cfd-2d98-4721-963e-9663e1897a17\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient is living at home in a community setting\"},{\"linkId\":\"3ccc8304-76cd-41ff-9360-2c8755590bae\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has been recently diagnosed with type 3 diabetes (in the last 12 months) AND is unable to gain timely access to existing diabetes education or health services in the community OR \"},{\"linkId\":\"b05f6f09-49ec-40f9-a889-9a3fdff9e0da\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has type 2 diabetes , is less than ideally controlled AND is unable to gain timely access to existing diabetes education or health services in their community \"},{\"linkId\":\"4a777f56-800d-4e0b-a9c3-e929832adb5b\",\"answer\":[{\"valueBoolean\":false,\"group\":[{\"linkId\":\"95bbc904-149e-427f-88a4-7f6c8ab186fa\",\"question\":[{\"linkId\":\"f0acea9e-716c-4fce-b7a2-aad59de9d136\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Patient has had an Acute or Adverse Event\"},{\"linkId\":\"e1629159-6dea-4295-a93e-e7c2829ce180\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Exacerbation of a Chronic Disease or Condition\"},{\"linkId\":\"2ce526fa-edaa-44b3-8d5a-6e97f6379ce8\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"New Diagnosis\"},{\"linkId\":\"9d6ffa9f-0110-418c-9ed0-f04910fda2ed\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Recent hospital admission (<3 months)\"},{\"linkId\":\"d2803ff7-25f7-4c7b-ab92-356c49910478\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Major change to regular medication regime\"},{\"linkId\":\"b34af32d-c69d-4d44-889f-5b6d420a7d08\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Suspected non-adherence to the patient's medication regime \"},{\"linkId\":\"74bad553-c273-41e6-8647-22b860430bc2\",\"answer\":[],\"text\":\"Other\"}]}]}],\"text\":\"The patient has experienced one or more of the following recent significant medical events\"},{\"linkId\":\"ecbf4e5a-d4d1-43eb-9f43-0c0e35fc09c7\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The Pharmacist has obtained patient consent to take part in the MedsCheck Service or Diabetes MedsCheck Service and share information obtained during the services with other nominated members of the patients healthcare team (such as their GP, diabetes educator) if required\"},{\"linkId\":\"8ef66774-43b0-4190-873f-cfbb6e980aa9\",\"answer\":[],\"text\":\"Question\"}]}}}]}";
+ HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse/$validate?_pretty=true");
+ post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON));
+ CloseableHttpResponse response = ourHttpClient.execute(post);
+ try {
+ String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
+ ourLog.info("Response: {}", responseString);
+ assertThat(responseString, containsString("No issues detected"));
+ assertEquals(200, response.getStatusLine().getStatusCode());
+ } finally {
+ IOUtils.closeQuietly(response);
+ }
+
+ }
+
+ /**
+ * From a Skype message from Brian Postlethwaite
+ */
+ @Test
+ public void testValidateQuestionnaireResponseWithNoIdForUpdate() throws Exception {
+
+ String input = "{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"mode\",\"valueString\":\"update\"},{\"name\":\"resource\",\"resource\":{\"resourceType\":\"QuestionnaireResponse\",\"questionnaire\":{\"reference\":\"http://fhirtest.uhn.ca/baseDstu2/Questionnaire/MedsCheckEligibility\"},\"text\":{\"status\":\"generated\",\"div\":\"!-- populated from the rendered HTML below -->
\"},\"status\":\"completed\",\"authored\":\"2017-02-10T00:02:58.098Z\",\"group\":{\"question\":[{\"linkId\":\"d94b4f57-1ca0-4d65-acba-8bd9a3926c8c\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has a valid Medicare or DVA entitlement card\"},{\"linkId\":\"0cbe66db-ff12-473a-940e-4672fb82de44\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has received a MedsCheck, Diabetes MedsCheck, Home Medicines Review (HMR) otr Restidential Medication Management Review (RMMR) in the past 12 months\"},{\"linkId\":\"35790cfd-2d98-4721-963e-9663e1897a17\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient is living at home in a community setting\"},{\"linkId\":\"3ccc8304-76cd-41ff-9360-2c8755590bae\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has been recently diagnosed with type 3 diabetes (in the last 12 months) AND is unable to gain timely access to existing diabetes education or health services in the community OR \"},{\"linkId\":\"b05f6f09-49ec-40f9-a889-9a3fdff9e0da\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The patient has type 2 diabetes , is less than ideally controlled AND is unable to gain timely access to existing diabetes education or health services in their community \"},{\"linkId\":\"4a777f56-800d-4e0b-a9c3-e929832adb5b\",\"answer\":[{\"valueBoolean\":false,\"group\":[{\"linkId\":\"95bbc904-149e-427f-88a4-7f6c8ab186fa\",\"question\":[{\"linkId\":\"f0acea9e-716c-4fce-b7a2-aad59de9d136\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Patient has had an Acute or Adverse Event\"},{\"linkId\":\"e1629159-6dea-4295-a93e-e7c2829ce180\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Exacerbation of a Chronic Disease or Condition\"},{\"linkId\":\"2ce526fa-edaa-44b3-8d5a-6e97f6379ce8\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"New Diagnosis\"},{\"linkId\":\"9d6ffa9f-0110-418c-9ed0-f04910fda2ed\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Recent hospital admission (<3 months)\"},{\"linkId\":\"d2803ff7-25f7-4c7b-ab92-356c49910478\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Major change to regular medication regime\"},{\"linkId\":\"b34af32d-c69d-4d44-889f-5b6d420a7d08\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"Suspected non-adherence to the patient's medication regime \"},{\"linkId\":\"74bad553-c273-41e6-8647-22b860430bc2\",\"answer\":[],\"text\":\"Other\"}]}]}],\"text\":\"The patient has experienced one or more of the following recent significant medical events\"},{\"linkId\":\"ecbf4e5a-d4d1-43eb-9f43-0c0e35fc09c7\",\"answer\":[{\"valueBoolean\":false}],\"text\":\"The Pharmacist has obtained patient consent to take part in the MedsCheck Service or Diabetes MedsCheck Service and share information obtained during the services with other nominated members of the patients healthcare team (such as their GP, diabetes educator) if required\"},{\"linkId\":\"8ef66774-43b0-4190-873f-cfbb6e980aa9\",\"answer\":[],\"text\":\"Question\"}]}}}]}";
+ HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse/$validate?_pretty=true");
+ post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON));
+ CloseableHttpResponse response = ourHttpClient.execute(post);
+ try {
+ String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
+ ourLog.info("Response: {}", responseString);
+ assertThat(responseString, containsString("Resource has no ID"));
+ assertEquals(422, response.getStatusLine().getStatusCode());
+ } finally {
+ IOUtils.closeQuietly(response);
+ }
+
+ }
+
}
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java
index 18e2416a292..0f88926f0b9 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderCustomSearchParamDstu3Test.java
@@ -14,6 +14,7 @@ import java.util.Map;
import org.hl7.fhir.dstu3.model.Bundle;
import org.hl7.fhir.dstu3.model.CapabilityStatement;
+import org.hl7.fhir.dstu3.model.CodeType;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceComponent;
import org.hl7.fhir.dstu3.model.CapabilityStatement.CapabilityStatementRestResourceSearchParamComponent;
@@ -35,6 +36,7 @@ import ca.uhn.fhir.jpa.dao.SearchParameterMap;
import ca.uhn.fhir.jpa.entity.ResourceTable;
import ca.uhn.fhir.rest.gclient.ReferenceClientParam;
import ca.uhn.fhir.rest.gclient.TokenClientParam;
+import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.TestUtil;
@@ -70,6 +72,55 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
}
}
+
+ @Test
+ public void testSearchForExtension() {
+ SearchParameter eyeColourSp = new SearchParameter();
+ eyeColourSp.addBase("Patient");
+ eyeColourSp.setCode("eyecolour");
+ eyeColourSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
+ eyeColourSp.setTitle("Eye Colour");
+ eyeColourSp.setExpression("Patient.extension('http://acme.org/eyecolour')");
+ eyeColourSp.setXpathUsage(org.hl7.fhir.dstu3.model.SearchParameter.XPathUsageType.NORMAL);
+ eyeColourSp.setStatus(org.hl7.fhir.dstu3.model.Enumerations.PublicationStatus.ACTIVE);
+
+ ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(eyeColourSp));
+
+ ourClient
+ .create()
+ .resource(eyeColourSp)
+ .execute();
+
+// mySearchParamRegsitry.forceRefresh();
+
+ Patient p1 = new Patient();
+ p1.setActive(true);
+ p1.addExtension().setUrl("http://acme.org/eyecolour").setValue(new CodeType("blue"));
+ IIdType p1id = myPatientDao.create(p1).getId().toUnqualifiedVersionless();
+
+ ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(p1));
+
+ Patient p2 = new Patient();
+ p2.setActive(true);
+ p2.addExtension().setUrl("http://acme.org/eyecolour").setValue(new CodeType("green"));
+ IIdType p2id = myPatientDao.create(p2).getId().toUnqualifiedVersionless();
+
+ Bundle bundle = ourClient
+ .search()
+ .forResource(Patient.class)
+ .where(new TokenClientParam("eyecolour").exactly().code("blue"))
+ .returnBundle(Bundle.class)
+ .execute();
+
+ ourLog.info(myFhirCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(bundle));
+
+ List foundResources = toUnqualifiedVersionlessIdValues(bundle);
+ assertThat(foundResources, contains(p1id.getValue()));
+
+ }
+
+ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceProviderCustomSearchParamDstu3Test.class);
+
@Override
@Before
public void beforeResetConfig() {
@@ -97,6 +148,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
// Add a custom search parameter
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -107,6 +159,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
// Disable an existing parameter
fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("gender");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("Gender");
@@ -149,6 +202,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
// Add a custom search parameter
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -159,6 +213,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
// Disable an existing parameter
fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("gender");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("Gender");
@@ -203,6 +258,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
public void testSearchWithCustomParam() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -254,6 +310,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
assertEquals(BaseHapiFhirDao.INDEX_STATUS_INDEXED, res.getIndexStatus().longValue());
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.TOKEN);
fooSp.setTitle("FOO SP");
@@ -274,6 +331,7 @@ public class ResourceProviderCustomSearchParamDstu3Test extends BaseResourceProv
public void testSearchQualifiedWithCustomReferenceParam() {
SearchParameter fooSp = new SearchParameter();
+ fooSp.addBase("Patient");
fooSp.setCode("foo");
fooSp.setType(org.hl7.fhir.dstu3.model.Enumerations.SearchParamType.REFERENCE);
fooSp.setTitle("FOO SP");
diff --git a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderQuestionnaireResponseDstu3Test.java b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderQuestionnaireResponseDstu3Test.java
index b62fdd2b2a3..99ccc42b07c 100644
--- a/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderQuestionnaireResponseDstu3Test.java
+++ b/hapi-fhir-jpaserver-base/src/test/java/ca/uhn/fhir/jpa/provider/dstu3/ResourceProviderQuestionnaireResponseDstu3Test.java
@@ -6,10 +6,12 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
+import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import org.apache.commons.io.IOUtils;
+import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
@@ -181,5 +183,63 @@ public class ResourceProviderQuestionnaireResponseDstu3Test extends BaseResource
}
+ @Test
+ public void testValidateOnNoId() throws Exception {
+ HttpGet get = new HttpGet(ourServerBase + "/QuestionnaireResponse/$validate");
+ CloseableHttpResponse response = ourHttpClient.execute(get);
+ try {
+ String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
+ ourLog.info("Response: {}", responseString);
+ assertThat(responseString, containsString("No resource supplied for $validate operation"));
+ assertEquals(400, response.getStatusLine().getStatusCode());
+ } finally {
+ IOUtils.closeQuietly(response);
+ }
+
+ }
+
+
+ /**
+ * From a Skype message from Brian Postlethwaite
+ */
+ @Test
+ public void testValidateQuestionnaireResponseWithNoIdForCreate() throws Exception {
+
+ String input = "{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"mode\",\"valueString\":\"create\"},{\"name\":\"resource\",\"resource\":{\"resourceType\":\"QuestionnaireResponse\",\"questionnaire\":{\"reference\":\"http://fhirtest.uhn.ca/baseDstu2/Questionnaire/MedsCheckEligibility\"},\"text\":{\"status\":\"generated\",\"div\":\"!-- populated from the rendered HTML below -->
\"},\"status\":\"completed\",\"authored\":\"2017-02-10T00:02:58.098Z\"}}]}";
+ HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse/$validate?_pretty=true");
+ post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON));
+ CloseableHttpResponse response = ourHttpClient.execute(post);
+ try {
+ String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
+ ourLog.info("Response: {}", responseString);
+ assertEquals(200, response.getStatusLine().getStatusCode());
+ } finally {
+ IOUtils.closeQuietly(response);
+ }
+
+ }
+
+ /**
+ * From a Skype message from Brian Postlethwaite
+ */
+ @Test
+ public void testValidateQuestionnaireResponseWithNoIdForUpdate() throws Exception {
+
+ String input = "{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"mode\",\"valueString\":\"update\"},{\"name\":\"resource\",\"resource\":{\"resourceType\":\"QuestionnaireResponse\",\"questionnaire\":{\"reference\":\"http://fhirtest.uhn.ca/baseDstu2/Questionnaire/MedsCheckEligibility\"},\"text\":{\"status\":\"generated\",\"div\":\"!-- populated from the rendered HTML below -->
\"},\"status\":\"completed\",\"authored\":\"2017-02-10T00:02:58.098Z\"}}]}";
+ HttpPost post = new HttpPost(ourServerBase + "/QuestionnaireResponse/$validate?_pretty=true");
+ post.setEntity(new StringEntity(input, ContentType.APPLICATION_JSON));
+ CloseableHttpResponse response = ourHttpClient.execute(post);
+ try {
+ String responseString = IOUtils.toString(response.getEntity().getContent(), StandardCharsets.UTF_8);
+ ourLog.info("Response: {}", responseString);
+ assertThat(responseString, containsString("Resource has no ID"));
+ assertEquals(422, response.getStatusLine().getStatusCode());
+ } finally {
+ IOUtils.closeQuietly(response);
+ }
+
+ }
+
+
}
diff --git a/hapi-fhir-jpaserver-base/src/test/resources/dstu3-post1.xml b/hapi-fhir-jpaserver-base/src/test/resources/dstu3-post1.xml
new file mode 100644
index 00000000000..745a89effb7
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/resources/dstu3-post1.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hapi-fhir-jpaserver-base/src/test/resources/dstu3-post2.xml b/hapi-fhir-jpaserver-base/src/test/resources/dstu3-post2.xml
new file mode 100644
index 00000000000..c6a60f0258a
--- /dev/null
+++ b/hapi-fhir-jpaserver-base/src/test/resources/dstu3-post2.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
index 4d5b7bc5b01..6056b717e85 100644
--- a/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
+++ b/hapi-fhir-jpaserver-uhnfhirtest/pom.xml
@@ -177,8 +177,14 @@
org.apache.maven.plugins
maven-compiler-plugin
-
- 1.7
+
+
+ 1.8
jdk15
test
@@ -116,7 +116,7 @@
net.sf.json-lib
json-lib
- 2.4
+
jdk15-sources
test
@@ -139,7 +139,7 @@
directory-naming
naming-java
- 0.8
+
test
diff --git a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java
index 7cbf365e373..ab2c58431df 100644
--- a/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java
+++ b/hapi-fhir-structures-dstu2/src/test/java/ca/uhn/fhir/rest/server/SearchDstu2Test.java
@@ -575,6 +575,11 @@ public class SearchDstu2Test {
public int size() {
return 0;
}
+
+ @Override
+ public String getUuid() {
+ return null;
+ }
};
}
diff --git a/hapi-fhir-structures-dstu3/.editorconfig b/hapi-fhir-structures-dstu3/.editorconfig
new file mode 100644
index 00000000000..cd68918bc8b
--- /dev/null
+++ b/hapi-fhir-structures-dstu3/.editorconfig
@@ -0,0 +1,5 @@
+[*.java]
+charset = utf-8
+indent_style = space
+indent_size = 2
+
diff --git a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/terminologies/ValueSetExpanderSimple.java b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/terminologies/ValueSetExpanderSimple.java
index b7217351356..40b74e810e2 100644
--- a/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/terminologies/ValueSetExpanderSimple.java
+++ b/hapi-fhir-structures-dstu3/src/main/java/org/hl7/fhir/dstu3/terminologies/ValueSetExpanderSimple.java
@@ -6,33 +6,33 @@ import java.io.FileNotFoundException;
import java.io.IOException;
/*
-Copyright (c) 2011+, HL7, Inc
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- * Neither the name of HL7 nor the names of its contributors may be used to
- endorse or promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-
-*/
+ * Copyright (c) 2011+, HL7, Inc
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of HL7 nor the names of its contributors may be used to
+ * endorse or promote products derived from this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
import java.util.ArrayList;
import java.util.HashMap;
@@ -72,66 +72,67 @@ import org.hl7.fhir.utilities.Utilities;
public class ValueSetExpanderSimple implements ValueSetExpander {
- private List codes = new ArrayList();
+ private List codes = new ArrayList();
private List roots = new ArrayList();
private Map