Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
ae9ab6c109
|
@ -59,6 +59,13 @@
|
|||
<groupId>com.phloc</groupId>
|
||||
<artifactId>phloc-commons</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<!-- Guava brings in a newer replacement for this dependency called com.google.code.findbugs:jsr305 -->
|
||||
<groupId>com.google.code.findbugs</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency> <groupId>xerces</groupId> <artifactId>xercesImpl</artifactId>
|
||||
|
@ -77,6 +84,10 @@
|
|||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- Logging -->
|
||||
<dependency>
|
||||
|
|
|
@ -138,19 +138,6 @@ public class ParameterUtil {
|
|||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a string according to the rules for parameter escaping specified in the <a href="http://www.hl7.org/implement/standards/fhir/search.html#escaping">FHIR Specification Escaping
|
||||
* Section</a>
|
||||
*/
|
||||
public static String escapeAndUrlEncode(String theValue) {
|
||||
if (theValue == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String escaped = escape(theValue);
|
||||
return UrlUtil.escape(escaped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes a string according to the rules for parameter escaping specified in the <a href="http://www.hl7.org/implement/standards/fhir/search.html#escaping">FHIR Specification Escaping
|
||||
* Section</a>
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
package ca.uhn.fhir.util;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import com.google.common.escape.Escaper;
|
||||
import com.google.common.net.PercentEscaper;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultIfBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
|
@ -35,6 +39,10 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
public class UrlUtil {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(UrlUtil.class);
|
||||
|
||||
private static final String URL_FORM_PARAMETER_OTHER_SAFE_CHARS = "-_.*";
|
||||
private static final Escaper PARAMETER_ESCAPER = new PercentEscaper(URL_FORM_PARAMETER_OTHER_SAFE_CHARS, false);
|
||||
|
||||
|
||||
/**
|
||||
* Resolve a relative URL - THIS METHOD WILL NOT FAIL but will log a warning and return theEndpoint if the input is invalid.
|
||||
*/
|
||||
|
@ -88,19 +96,24 @@ public class UrlUtil {
|
|||
}
|
||||
|
||||
/**
|
||||
* URL encode a value
|
||||
* URL encode a value according to RFC 3986
|
||||
* <p>
|
||||
* This method is intended to be applied to an individual parameter
|
||||
* name or value. For example, if you are creating the URL
|
||||
* <code>http://example.com/fhir/Patient?key=føø</code>
|
||||
* it would be appropriate to pass the string "føø" to this method,
|
||||
* but not appropriate to pass the entire URL since characters
|
||||
* such as "/" and "?" would also be escaped.
|
||||
* </P>
|
||||
*/
|
||||
public static String escape(String theValue) {
|
||||
if (theValue == null) {
|
||||
public static String escapeUrlParam(String theUnescaped) {
|
||||
if (theUnescaped == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return URLEncoder.encode(theValue, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error("UTF-8 not supported on this platform");
|
||||
}
|
||||
return PARAMETER_ESCAPER.escape(theUnescaped);
|
||||
}
|
||||
|
||||
|
||||
public static boolean isAbsolute(String theValue) {
|
||||
String value = theValue.toLowerCase();
|
||||
return value.startsWith("http://") || value.startsWith("https://");
|
||||
|
@ -147,7 +160,7 @@ public class UrlUtil {
|
|||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(escape("http://snomed.info/sct?fhir_vs=isa/126851005"));
|
||||
System.out.println(escapeUrlParam("http://snomed.info/sct?fhir_vs=isa/126851005"));
|
||||
}
|
||||
|
||||
public static Map<String, String[]> parseQueryString(String theQueryString) {
|
||||
|
@ -156,36 +169,20 @@ public class UrlUtil {
|
|||
return toQueryStringMap(map);
|
||||
}
|
||||
|
||||
public static Map<String, String[]> parseQueryStrings(String... theQueryString) {
|
||||
HashMap<String, List<String>> map = new HashMap<String, List<String>>();
|
||||
for (String next : theQueryString) {
|
||||
parseQueryString(next, map);
|
||||
}
|
||||
return toQueryStringMap(map);
|
||||
}
|
||||
|
||||
private static Map<String, String[]> toQueryStringMap(HashMap<String, List<String>> map) {
|
||||
HashMap<String, String[]> retVal = new HashMap<String, String[]>();
|
||||
for (Entry<String, List<String>> nextEntry : map.entrySet()) {
|
||||
retVal.put(nextEntry.getKey(), nextEntry.getValue().toArray(new String[nextEntry.getValue().size()]));
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private static void parseQueryString(String theQueryString, HashMap<String, List<String>> map) {
|
||||
String query = theQueryString;
|
||||
if (query.startsWith("?")) {
|
||||
query = query.substring(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
StringTokenizer tok = new StringTokenizer(query, "&");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String nextToken = tok.nextToken();
|
||||
if (isBlank(nextToken)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
int equalsIndex = nextToken.indexOf('=');
|
||||
String nextValue;
|
||||
String nextKey;
|
||||
|
@ -196,21 +193,28 @@ public class UrlUtil {
|
|||
nextKey = nextToken.substring(0, equalsIndex);
|
||||
nextValue = nextToken.substring(equalsIndex + 1);
|
||||
}
|
||||
|
||||
|
||||
nextKey = unescape(nextKey);
|
||||
nextValue = unescape(nextValue);
|
||||
|
||||
|
||||
List<String> list = map.get(nextKey);
|
||||
if (list == null) {
|
||||
list = new ArrayList<String>();
|
||||
list = new ArrayList<>();
|
||||
map.put(nextKey, list);
|
||||
}
|
||||
list.add(nextValue);
|
||||
}
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
/**
|
||||
public static Map<String, String[]> parseQueryStrings(String... theQueryString) {
|
||||
HashMap<String, List<String>> map = new HashMap<String, List<String>>();
|
||||
for (String next : theQueryString) {
|
||||
parseQueryString(next, map);
|
||||
}
|
||||
return toQueryStringMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a URL in one of the following forms:
|
||||
* <ul>
|
||||
* <li>[Resource Type]?[Search Params]
|
||||
|
@ -278,6 +282,16 @@ public class UrlUtil {
|
|||
|
||||
}
|
||||
|
||||
//@formatter:off
|
||||
|
||||
private static Map<String, String[]> toQueryStringMap(HashMap<String, List<String>> map) {
|
||||
HashMap<String, String[]> retVal = new HashMap<String, String[]>();
|
||||
for (Entry<String, List<String>> nextEntry : map.entrySet()) {
|
||||
retVal.put(nextEntry.getKey(), nextEntry.getValue().toArray(new String[nextEntry.getValue().size()]));
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static String unescape(String theString) {
|
||||
if (theString == null) {
|
||||
return null;
|
||||
|
@ -305,30 +319,30 @@ public class UrlUtil {
|
|||
return myParams;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return myResourceId;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myResourceType;
|
||||
}
|
||||
|
||||
public String getVersionId() {
|
||||
return myVersionId;
|
||||
}
|
||||
|
||||
public void setParams(String theParams) {
|
||||
myParams = theParams;
|
||||
}
|
||||
|
||||
public String getResourceId() {
|
||||
return myResourceId;
|
||||
}
|
||||
|
||||
public void setResourceId(String theResourceId) {
|
||||
myResourceId = theResourceId;
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myResourceType;
|
||||
}
|
||||
|
||||
public void setResourceType(String theResourceType) {
|
||||
myResourceType = theResourceType;
|
||||
}
|
||||
|
||||
public String getVersionId() {
|
||||
return myVersionId;
|
||||
}
|
||||
|
||||
public void setVersionId(String theVersionId) {
|
||||
myVersionId = theVersionId;
|
||||
}
|
||||
|
|
|
@ -1,20 +1,42 @@
|
|||
package ca.uhn.fhir.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class UrlUtilTest {
|
||||
|
||||
@Test
|
||||
public void testConstructAbsoluteUrl() {
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructAbsoluteUrl(null, "http://foo/bar/baz"));
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructAbsoluteUrl("http://foo/bar/", "baz"));
|
||||
assertEquals("http://foo/bar/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/", "baz/"));
|
||||
assertEquals("http://foo/bar/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/", "./baz/"));
|
||||
|
||||
assertEquals("http://foo/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/", "../baz/"));
|
||||
assertEquals("http://foo/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/", "/baz/"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructRelativeUrl() {
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructRelativeUrl("http://boo/far/faz", "http://foo/bar/baz"));
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructRelativeUrl("http://foo/far/faz", "http://foo/bar/baz"));
|
||||
assertEquals("baz", UrlUtil.constructRelativeUrl("http://foo/bar/boo", "http://foo/bar/baz"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEscape() {
|
||||
assertEquals("A%20B", UrlUtil.escapeUrlParam("A B"));
|
||||
assertEquals("A%2BB", UrlUtil.escapeUrlParam("A+B"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsValid() {
|
||||
assertTrue(UrlUtil.isValid("http://foo"));
|
||||
assertTrue(UrlUtil.isValid("https://foo"));
|
||||
assertTrue(UrlUtil.isValid("HTTP://Foo"));
|
||||
assertTrue(UrlUtil.isValid("HTTPS://Foo"));
|
||||
|
||||
|
||||
assertFalse(UrlUtil.isValid("file://foo"));
|
||||
assertFalse(UrlUtil.isValid("://foo"));
|
||||
assertFalse(UrlUtil.isValid("http:/ss"));
|
||||
|
@ -24,7 +46,7 @@ public class UrlUtilTest {
|
|||
assertFalse(UrlUtil.isValid(""));
|
||||
assertFalse(UrlUtil.isValid(null));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParseUrl() {
|
||||
assertEquals("ConceptMap", UrlUtil.parseUrl("http://hl7.org/fhir/ConceptMap/ussgfht-loincde").getResourceType());
|
||||
|
@ -36,25 +58,5 @@ public class UrlUtilTest {
|
|||
assertEquals("a=b", UrlUtil.parseUrl("ConceptMap/ussgfht-loincde?a=b").getParams());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructAbsoluteUrl() {
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructAbsoluteUrl(null, "http://foo/bar/baz"));
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructAbsoluteUrl("http://foo/bar/","baz"));
|
||||
assertEquals("http://foo/bar/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/","baz/"));
|
||||
assertEquals("http://foo/bar/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/","./baz/"));
|
||||
|
||||
assertEquals("http://foo/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/","../baz/"));
|
||||
assertEquals("http://foo/baz/", UrlUtil.constructAbsoluteUrl("http://foo/bar/","/baz/"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
public void testConstructRelativeUrl() {
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructRelativeUrl("http://boo/far/faz", "http://foo/bar/baz"));
|
||||
assertEquals("http://foo/bar/baz", UrlUtil.constructRelativeUrl("http://foo/far/faz", "http://foo/bar/baz"));
|
||||
assertEquals("baz", UrlUtil.constructRelativeUrl("http://foo/bar/boo", "http://foo/bar/baz"));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,13 +20,6 @@ package ca.uhn.fhir.rest.client.impl;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
|
@ -34,6 +27,12 @@ import ca.uhn.fhir.rest.client.api.Header;
|
|||
import ca.uhn.fhir.rest.client.api.IHttpClient;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClientFactory;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
public abstract class BaseHttpClientInvocation {
|
||||
|
||||
|
@ -115,13 +114,9 @@ public abstract class BaseHttpClientInvocation {
|
|||
} else {
|
||||
theUrlBuilder.append('&');
|
||||
}
|
||||
try {
|
||||
theUrlBuilder.append(URLEncoder.encode(next.getKey(), "UTF-8"));
|
||||
theUrlBuilder.append('=');
|
||||
theUrlBuilder.append(URLEncoder.encode(nextValue, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error("UTF-8 not supported - This should not happen");
|
||||
}
|
||||
theUrlBuilder.append(UrlUtil.escapeUrlParam(next.getKey()));
|
||||
theUrlBuilder.append('=');
|
||||
theUrlBuilder.append(UrlUtil.escapeUrlParam(nextValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -354,7 +354,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
case '?':
|
||||
case '$':
|
||||
case ':':
|
||||
b.append(UrlUtil.escape(Character.toString(nextChar)));
|
||||
b.append(UrlUtil.escapeUrlParam(Character.toString(nextChar)));
|
||||
break;
|
||||
default:
|
||||
b.append(nextChar);
|
||||
|
|
|
@ -20,21 +20,18 @@ package ca.uhn.fhir.rest.client.method;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.RequestTypeEnum;
|
||||
import ca.uhn.fhir.rest.client.api.IHttpRequest;
|
||||
import ca.uhn.fhir.rest.client.impl.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
* @author James Agnew
|
||||
|
@ -51,51 +48,40 @@ public class HttpGetClientInvocation extends BaseHttpClientInvocation {
|
|||
myUrlPath = StringUtils.join(theUrlFragments, '/');
|
||||
}
|
||||
|
||||
public HttpGetClientInvocation(FhirContext theContext, Map<String, List<String>> theParameters, List<String> theUrlFragments) {
|
||||
super(theContext);
|
||||
myParameters = theParameters;
|
||||
myUrlPath = StringUtils.join(theUrlFragments, '/');
|
||||
}
|
||||
|
||||
public HttpGetClientInvocation(FhirContext theContext, String theUrlPath) {
|
||||
super(theContext);
|
||||
myParameters = new HashMap<String, List<String>>();
|
||||
myParameters = new HashMap<>();
|
||||
myUrlPath = theUrlPath;
|
||||
}
|
||||
|
||||
public HttpGetClientInvocation(FhirContext theContext, String... theUrlFragments) {
|
||||
super(theContext);
|
||||
myParameters = new HashMap<String, List<String>>();
|
||||
myUrlPath = StringUtils.join(theUrlFragments, '/');
|
||||
}
|
||||
|
||||
private boolean addQueryParameter(StringBuilder b, boolean first, String nextKey, String nextValue) {
|
||||
boolean retVal = first;
|
||||
if (retVal) {
|
||||
b.append('?');
|
||||
retVal = false;
|
||||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
b.append(UrlUtil.escapeUrlParam(nextKey));
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(nextValue));
|
||||
|
||||
public HttpGetClientInvocation(FhirContext theContext, List<String> theUrlFragments) {
|
||||
super(theContext);
|
||||
myParameters = new HashMap<String, List<String>>();
|
||||
myUrlPath = StringUtils.join(theUrlFragments, '/');
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getParameters() {
|
||||
return myParameters;
|
||||
}
|
||||
|
||||
public String getUrlPath() {
|
||||
return myUrlPath;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IHttpRequest asHttpRequest(String theUrlBase, Map<String, List<String>> theExtraParams, EncodingEnum theEncoding, Boolean thePrettyPrint) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
|
||||
if (!myUrlPath.contains("://")) {
|
||||
b.append(theUrlBase);
|
||||
if (!theUrlBase.endsWith("/") && !myUrlPath.startsWith("/")) {
|
||||
b.append('/');
|
||||
}
|
||||
}
|
||||
b.append(myUrlPath);
|
||||
|
||||
b.append(theUrlBase);
|
||||
if (!theUrlBase.endsWith("/") && !myUrlPath.startsWith("/")) {
|
||||
b.append('/');
|
||||
}
|
||||
}
|
||||
b.append(myUrlPath);
|
||||
|
||||
boolean first = b.indexOf("?") == -1;
|
||||
for (Entry<String, List<String>> next : myParameters.entrySet()) {
|
||||
if (next.getValue() == null || next.getValue().isEmpty()) {
|
||||
|
@ -112,22 +98,12 @@ public class HttpGetClientInvocation extends BaseHttpClientInvocation {
|
|||
return super.createHttpRequest(b.toString(), theEncoding, RequestTypeEnum.GET);
|
||||
}
|
||||
|
||||
private boolean addQueryParameter(StringBuilder b, boolean first, String nextKey, String nextValue) {
|
||||
boolean retVal = first;
|
||||
if (retVal) {
|
||||
b.append('?');
|
||||
retVal = false;
|
||||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
try {
|
||||
b.append(URLEncoder.encode(nextKey, "UTF-8"));
|
||||
b.append('=');
|
||||
b.append(URLEncoder.encode(nextValue, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ConfigurationException("Could not find UTF-8 encoding. This shouldn't happen.", e);
|
||||
}
|
||||
return retVal;
|
||||
public Map<String, List<String>> getParameters() {
|
||||
return myParameters;
|
||||
}
|
||||
|
||||
public String getUrlPath() {
|
||||
return myUrlPath;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -209,9 +209,9 @@ public class MethodUtil {
|
|||
for (String nextValue : nextEntry.getValue()) {
|
||||
b.append(haveQuestionMark ? '&' : '?');
|
||||
haveQuestionMark = true;
|
||||
b.append(UrlUtil.escape(nextEntry.getKey()));
|
||||
b.append(UrlUtil.escapeUrlParam(nextEntry.getKey()));
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escape(nextValue));
|
||||
b.append(UrlUtil.escapeUrlParam(nextValue));
|
||||
}
|
||||
}
|
||||
return b;
|
||||
|
|
|
@ -35,7 +35,6 @@ import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.XhtmlDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
|
@ -229,14 +228,14 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
ArrayList<String> nextChoicesList = new ArrayList<>();
|
||||
partsChoices.add(nextChoicesList);
|
||||
|
||||
String key = UrlUtil.escape(nextCompositeOf.getName());
|
||||
String key = UrlUtil.escapeUrlParam(nextCompositeOf.getName());
|
||||
if (paramsListForCompositePart != null) {
|
||||
for (BaseResourceIndexedSearchParam nextParam : paramsListForCompositePart) {
|
||||
if (nextParam.getParamName().equals(nextCompositeOf.getName())) {
|
||||
IQueryParameterType nextParamAsClientParam = nextParam.toQueryParameterType();
|
||||
String value = nextParamAsClientParam.getValueAsQueryToken(getContext());
|
||||
if (isNotBlank(value)) {
|
||||
value = UrlUtil.escape(value);
|
||||
value = UrlUtil.escapeUrlParam(value);
|
||||
nextChoicesList.add(key + "=" + value);
|
||||
}
|
||||
}
|
||||
|
@ -246,7 +245,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
for (ResourceLink nextLink : linksForCompositePart) {
|
||||
String value = nextLink.getTargetResource().getIdDt().toUnqualifiedVersionless().getValue();
|
||||
if (isNotBlank(value)) {
|
||||
value = UrlUtil.escape(value);
|
||||
value = UrlUtil.escapeUrlParam(value);
|
||||
nextChoicesList.add(key + "=" + value);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,7 +60,6 @@ import org.hibernate.ScrollMode;
|
|||
import org.hibernate.ScrollableResults;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hl7.fhir.dstu3.model.BaseResource;
|
||||
import org.hl7.fhir.dstu3.model.Reference;
|
||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
|
@ -175,7 +174,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
if (valueBuilder.length() > 0) {
|
||||
valueBuilder.append(',');
|
||||
}
|
||||
valueBuilder.append(UrlUtil.escape(next.getValueAsQueryToken(myContext)));
|
||||
valueBuilder.append(UrlUtil.escapeUrlParam(next.getValueAsQueryToken(myContext)));
|
||||
targetResourceType = next.getTargetResourceType();
|
||||
owningParameter = next.getOwningFieldName();
|
||||
parameterName = next.getParameterName();
|
||||
|
@ -185,7 +184,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
continue;
|
||||
}
|
||||
|
||||
String matchUrl = targetResourceType + '?' + UrlUtil.escape(parameterName) + '=' + valueBuilder.toString();
|
||||
String matchUrl = targetResourceType + '?' + UrlUtil.escapeUrlParam(parameterName) + '=' + valueBuilder.toString();
|
||||
RuntimeResourceDefinition targetResourceDefinition;
|
||||
try {
|
||||
targetResourceDefinition = myContext.getResourceDefinition(targetResourceType);
|
||||
|
@ -1272,13 +1271,13 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
List<List<String>> params = new ArrayList<>();
|
||||
for (Entry<String, List<List<? extends IQueryParameterType>>> nextParamNameToValues : theParams.entrySet()) {
|
||||
String nextParamName = nextParamNameToValues.getKey();
|
||||
nextParamName = UrlUtil.escape(nextParamName);
|
||||
nextParamName = UrlUtil.escapeUrlParam(nextParamName);
|
||||
for (List<? extends IQueryParameterType> nextAnd : nextParamNameToValues.getValue()) {
|
||||
ArrayList<String> nextValueList = new ArrayList<>();
|
||||
params.add(nextValueList);
|
||||
for (IQueryParameterType nextOr : nextAnd) {
|
||||
String nextOrValue = nextOr.getValueAsQueryToken(myContext);
|
||||
nextOrValue = UrlUtil.escape(nextOrValue);
|
||||
nextOrValue = UrlUtil.escapeUrlParam(nextOrValue);
|
||||
nextValueList.add(nextParamName + "=" + nextOrValue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
/*
|
||||
|
@ -24,7 +23,6 @@ import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|||
*/
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
|
@ -138,9 +136,9 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
|||
addUrlParamSeparator(b);
|
||||
b.append(paramName);
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escape(nextInclude.getParamType()));
|
||||
b.append(UrlUtil.escapeUrlParam(nextInclude.getParamType()));
|
||||
b.append(':');
|
||||
b.append(UrlUtil.escape(nextInclude.getParamName()));
|
||||
b.append(UrlUtil.escapeUrlParam(nextInclude.getParamName()));
|
||||
if (isNotBlank(nextInclude.getParamTargetType())) {
|
||||
b.append(':');
|
||||
b.append(nextInclude.getParamTargetType());
|
||||
|
@ -314,7 +312,7 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
|||
for (List<IQueryParameterType> nextValuesAnd : nextValuesAndsOut) {
|
||||
addUrlParamSeparator(b);
|
||||
IQueryParameterType firstValue = nextValuesAnd.get(0);
|
||||
b.append(UrlUtil.escape(nextKey));
|
||||
b.append(UrlUtil.escapeUrlParam(nextKey));
|
||||
|
||||
if (firstValue.getMissing() != null) {
|
||||
b.append(Constants.PARAMQUALIFIER_MISSING);
|
||||
|
@ -340,7 +338,7 @@ public class SearchParameterMap extends LinkedHashMap<String, List<List<? extend
|
|||
}
|
||||
String valueAsQueryToken = nextValueOr.getValueAsQueryToken(theCtx);
|
||||
// b.append(ParameterUtil.escapeAndUrlEncode(valueAsQueryToken));
|
||||
b.append(UrlUtil.escape(valueAsQueryToken));
|
||||
b.append(UrlUtil.escapeUrlParam(valueAsQueryToken));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -676,7 +676,7 @@ public class FhirSystemDaoDstu3 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
|||
String nextReplacementIdPart = nextReplacementId.getValueAsString();
|
||||
if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) {
|
||||
matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart);
|
||||
matchUrl = matchUrl.replace(UrlUtil.escape(nextTemporaryIdPart), nextReplacementIdPart);
|
||||
matchUrl = matchUrl.replace(UrlUtil.escapeUrlParam(nextTemporaryIdPart), nextReplacementIdPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -667,7 +667,7 @@ public class FhirSystemDaoR4 extends BaseHapiFhirSystemDao<Bundle, Meta> {
|
|||
String nextReplacementIdPart = nextReplacementId.getValueAsString();
|
||||
if (nextTemporaryId.isUrn() && nextTemporaryIdPart.length() > IdType.URN_PREFIX.length()) {
|
||||
matchUrl = matchUrl.replace(nextTemporaryIdPart, nextReplacementIdPart);
|
||||
matchUrl = matchUrl.replace(UrlUtil.escape(nextTemporaryIdPart), nextReplacementIdPart);
|
||||
matchUrl = matchUrl.replace(UrlUtil.escapeUrlParam(nextTemporaryIdPart), nextReplacementIdPart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -593,6 +593,9 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
shouldSync = true;
|
||||
}
|
||||
|
||||
// If no abort was requested, bail out
|
||||
Validate.isTrue(myAbortRequested == false, "Abort has been requested");
|
||||
|
||||
if (shouldSync) {
|
||||
saveUnsynced(theResultIterator);
|
||||
}
|
||||
|
@ -605,10 +608,11 @@ public class SearchCoordinatorSvcImpl implements ISearchCoordinatorSvc {
|
|||
}
|
||||
}
|
||||
|
||||
// Check if an abort got requested
|
||||
Validate.isTrue(myAbortRequested == false, "Abort has been requested");
|
||||
|
||||
}
|
||||
|
||||
// If no abort was requested, bail out
|
||||
Validate.isTrue(myAbortRequested == false, "Abort has been requested");
|
||||
|
||||
saveUnsynced(theResultIterator);
|
||||
}
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ public class HapiTerminologySvcDstu3 extends BaseHapiTerminologySvc implements I
|
|||
cs.setUrl(theSystem);
|
||||
cs.setContent(CodeSystemContentMode.NOTPRESENT);
|
||||
|
||||
DaoMethodOutcome createOutcome = myCodeSystemResourceDao.create(cs, "CodeSystem?url=" + UrlUtil.escape(theSystem), theRequestDetails);
|
||||
DaoMethodOutcome createOutcome = myCodeSystemResourceDao.create(cs, "CodeSystem?url=" + UrlUtil.escapeUrlParam(theSystem), theRequestDetails);
|
||||
IIdType csId = createOutcome.getId().toUnqualifiedVersionless();
|
||||
if (createOutcome.getCreated() != Boolean.TRUE) {
|
||||
CodeSystem existing = myCodeSystemResourceDao.read(csId, theRequestDetails);
|
||||
|
|
|
@ -325,7 +325,7 @@ public class HapiTerminologySvcR4 extends BaseHapiTerminologySvc implements IVal
|
|||
cs.setUrl(theSystem);
|
||||
cs.setContent(CodeSystemContentMode.NOTPRESENT);
|
||||
|
||||
DaoMethodOutcome createOutcome = myCodeSystemResourceDao.create(cs, "CodeSystem?url=" + UrlUtil.escape(theSystem), theRequestDetails);
|
||||
DaoMethodOutcome createOutcome = myCodeSystemResourceDao.create(cs, "CodeSystem?url=" + UrlUtil.escapeUrlParam(theSystem), theRequestDetails);
|
||||
IIdType csId = createOutcome.getId().toUnqualifiedVersionless();
|
||||
if (createOutcome.getCreated() != Boolean.TRUE) {
|
||||
CodeSystem existing = myCodeSystemResourceDao.read(csId, theRequestDetails);
|
||||
|
|
|
@ -30,7 +30,7 @@ public class TestDstu2Config extends BaseJavaConfigDstu2 {
|
|||
public DataSource dataSource() {
|
||||
BasicDataSource retVal = new BasicDataSource();
|
||||
retVal.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
|
||||
retVal.setUrl("jdbc:derby:memory:myUnitTestDB;create=true");
|
||||
retVal.setUrl("jdbc:derby:memory:myUnitTestDBDstu2;create=true");
|
||||
retVal.setUsername("");
|
||||
retVal.setPassword("");
|
||||
return retVal;
|
||||
|
|
|
@ -90,7 +90,7 @@ public class TestDstu3Config extends BaseJavaConfigDstu3 {
|
|||
|
||||
};
|
||||
retVal.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
|
||||
retVal.setUrl("jdbc:derby:memory:myUnitTestDB;create=true");
|
||||
retVal.setUrl("jdbc:derby:memory:myUnitTestDBDstu3;create=true");
|
||||
retVal.setMaxWaitMillis(10000);
|
||||
retVal.setUsername("");
|
||||
retVal.setPassword("");
|
||||
|
|
|
@ -85,7 +85,7 @@ public class TestR4Config extends BaseJavaConfigR4 {
|
|||
|
||||
};
|
||||
retVal.setDriver(new org.apache.derby.jdbc.EmbeddedDriver());
|
||||
retVal.setUrl("jdbc:derby:memory:myUnitTestDB;create=true");
|
||||
retVal.setUrl("jdbc:derby:memory:myUnitTestDBR4;create=true");
|
||||
retVal.setMaxWaitMillis(10000);
|
||||
retVal.setUsername("");
|
||||
retVal.setPassword("");
|
||||
|
|
|
@ -1,38 +1,12 @@
|
|||
package ca.uhn.fhir.jpa.dao;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
|
||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Observation;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hibernate.search.jpa.Search;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.dstu3.model.Resource;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.jpa.entity.*;
|
||||
import ca.uhn.fhir.jpa.provider.SystemProviderDstu2Test;
|
||||
import ca.uhn.fhir.jpa.search.ISearchCoordinatorSvc;
|
||||
import ca.uhn.fhir.jpa.sp.ISearchParamPresenceSvc;
|
||||
import ca.uhn.fhir.jpa.term.VersionIndependentConcept;
|
||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -41,6 +15,31 @@ import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor;
|
|||
import ca.uhn.fhir.rest.server.servlet.ServletRequestDetails;
|
||||
import ca.uhn.fhir.util.BundleUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.hibernate.search.jpa.Search;
|
||||
import org.hl7.fhir.dstu3.model.Bundle.BundleEntryComponent;
|
||||
import org.hl7.fhir.dstu3.model.Resource;
|
||||
import org.hl7.fhir.instance.model.api.IBaseBundle;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.TransactionCallback;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public abstract class BaseJpaTest {
|
||||
|
||||
|
@ -53,13 +52,23 @@ public abstract class BaseJpaTest {
|
|||
public void beforeCreateSrd() {
|
||||
mySrd = mock(ServletRequestDetails.class, Mockito.RETURNS_DEEP_STUBS);
|
||||
when(mySrd.getRequestOperationCallback()).thenReturn(myRequestOperationCallback);
|
||||
myServerInterceptorList = new ArrayList<IServerInterceptor>();
|
||||
myServerInterceptorList = new ArrayList<>();
|
||||
when(mySrd.getServer().getInterceptors()).thenReturn(myServerInterceptorList);
|
||||
when(mySrd.getUserData()).thenReturn(new HashMap<Object, Object>());
|
||||
when(mySrd.getUserData()).thenReturn(new HashMap<>());
|
||||
}
|
||||
|
||||
protected abstract FhirContext getContext();
|
||||
|
||||
/**
|
||||
* Sleep until at least 1 ms has elapsed
|
||||
*/
|
||||
public void sleepUntilTimeChanges() throws InterruptedException {
|
||||
StopWatch sw = new StopWatch();
|
||||
while (sw.getMillis() == 0) {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
protected org.hl7.fhir.dstu3.model.Bundle toBundle(IBundleProvider theSearch) {
|
||||
org.hl7.fhir.dstu3.model.Bundle bundle = new org.hl7.fhir.dstu3.model.Bundle();
|
||||
for (IBaseResource next : theSearch.getResources(0, theSearch.size())) {
|
||||
|
@ -76,11 +85,11 @@ public abstract class BaseJpaTest {
|
|||
return bundle;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
@SuppressWarnings({"rawtypes"})
|
||||
protected List toList(IBundleProvider theSearch) {
|
||||
return theSearch.getResources(0, theSearch.size());
|
||||
}
|
||||
|
||||
|
||||
protected List<String> toUnqualifiedIdValues(IBaseBundle theFound) {
|
||||
List<String> retVal = new ArrayList<String>();
|
||||
|
||||
|
@ -214,9 +223,9 @@ public abstract class BaseJpaTest {
|
|||
}
|
||||
|
||||
public static void purgeDatabase(final EntityManager entityManager, PlatformTransactionManager theTxManager, ISearchParamPresenceSvc theSearchParamPresenceSvc, ISearchCoordinatorSvc theSearchCoordinatorSvc, ISearchParamRegistry theSearchParamRegistry) {
|
||||
|
||||
|
||||
theSearchCoordinatorSvc.cancelAllActiveSearches();
|
||||
|
||||
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(theTxManager);
|
||||
txTemplate.setPropagationBehavior(TransactionTemplate.PROPAGATION_REQUIRED);
|
||||
txTemplate.execute(new TransactionCallback<Void>() {
|
||||
|
|
|
@ -2346,7 +2346,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testSortByLastUpdated() {
|
||||
public void testSortByLastUpdated() throws InterruptedException {
|
||||
String methodName = "testSortByLastUpdated";
|
||||
|
||||
Patient p = new Patient();
|
||||
|
@ -2354,21 +2354,29 @@ public class FhirResourceDaoDstu2Test extends BaseJpaDstu2Test {
|
|||
p.addName().addFamily(methodName);
|
||||
IIdType id1 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
sleepUntilTimeChanges();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system2").setValue(methodName);
|
||||
p.addName().addFamily(methodName);
|
||||
IIdType id2 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
sleepUntilTimeChanges();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system3").setValue(methodName);
|
||||
p.addName().addFamily(methodName);
|
||||
IIdType id3 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
sleepUntilTimeChanges();
|
||||
|
||||
p = new Patient();
|
||||
p.addIdentifier().setSystem("urn:system4").setValue(methodName);
|
||||
p.addName().addFamily(methodName);
|
||||
IIdType id4 = myPatientDao.create(p, mySrd).getId().toUnqualifiedVersionless();
|
||||
|
||||
sleepUntilTimeChanges();
|
||||
|
||||
SearchParameterMap pm;
|
||||
List<IIdType> actual;
|
||||
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||
|
||||
import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.entity.Search;
|
||||
import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl;
|
||||
import ca.uhn.fhir.jpa.util.StopWatch;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.hl7.fhir.dstu3.model.Patient;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.*;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.test.util.AopTestUtils;
|
||||
|
@ -16,10 +19,11 @@ import org.springframework.transaction.TransactionStatus;
|
|||
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
|
||||
import org.springframework.transaction.support.TransactionTemplate;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.jpa.search.StaleSearchDeletingSvcImpl;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
import static ca.uhn.fhir.jpa.util.TestUtil.sleepAtLeast;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class FhirResourceDaoDstu3SearchPageExpiryTest extends BaseJpaDstu3Test {
|
||||
private static final Logger ourLog = LoggerFactory.getLogger(FhirResourceDaoDstu3SearchPageExpiryTest.class);
|
||||
|
@ -104,14 +108,17 @@ public class FhirResourceDaoDstu3SearchPageExpiryTest extends BaseJpaDstu3Test {
|
|||
// Search just got used so it shouldn't be deleted
|
||||
|
||||
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
|
||||
final AtomicLong search3timestamp = new AtomicLong();
|
||||
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
|
||||
assertNotNull(mySearchEntityDao.findByUuid(searchUuid3));
|
||||
Search search3 = mySearchEntityDao.findByUuid(searchUuid3);
|
||||
assertNotNull(search3);
|
||||
search3timestamp.set(search3.getCreated().getTime());
|
||||
}
|
||||
});
|
||||
|
||||
StaleSearchDeletingSvcImpl.setNowForUnitTests(start + 1400);
|
||||
StaleSearchDeletingSvcImpl.setNowForUnitTests(search3timestamp.get() + 1400);
|
||||
|
||||
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
|
||||
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
|
||||
|
@ -127,14 +134,14 @@ public class FhirResourceDaoDstu3SearchPageExpiryTest extends BaseJpaDstu3Test {
|
|||
}
|
||||
});
|
||||
|
||||
StaleSearchDeletingSvcImpl.setNowForUnitTests(start + 2200);
|
||||
StaleSearchDeletingSvcImpl.setNowForUnitTests(search3timestamp.get() + 2200);
|
||||
|
||||
myStaleSearchDeletingSvc.pollForStaleSearchesAndDeleteThem();
|
||||
newTxTemplate().execute(new TransactionCallbackWithoutResult() {
|
||||
@Override
|
||||
protected void doInTransactionWithoutResult(TransactionStatus theArg0) {
|
||||
assertNull(mySearchEntityDao.findByUuid(searchUuid1));
|
||||
assertNull(mySearchEntityDao.findByUuid(searchUuid3));
|
||||
assertNull("Search 1 still exists", mySearchEntityDao.findByUuid(searchUuid1));
|
||||
assertNull("Search 3 still exists", mySearchEntityDao.findByUuid(searchUuid3));
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -30,7 +30,6 @@ import ca.uhn.fhir.model.dstu2.resource.*;
|
|||
import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
||||
import ca.uhn.fhir.model.dstu2.valueset.*;
|
||||
import ca.uhn.fhir.model.primitive.*;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
@ -528,7 +527,7 @@ public class ResourceProviderDstu2Test extends BaseResourceProviderDstu2Test {
|
|||
|
||||
pt.addName().addFamily("FOO");
|
||||
resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escape("|"))));
|
||||
HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escapeUrlParam("|"))));
|
||||
put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
IdDt id2;
|
||||
|
|
|
@ -1639,7 +1639,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
myObservationDao.create(obs, mySrd);
|
||||
}
|
||||
|
||||
String uri = ourServerBase + "/Patient?_has:Observation:subject:identifier=" + UrlUtil.escape("urn:system|FOO");
|
||||
String uri = ourServerBase + "/Patient?_has:Observation:subject:identifier=" + UrlUtil.escapeUrlParam("urn:system|FOO");
|
||||
List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||
assertThat(ids, contains(pid0.getValue()));
|
||||
}
|
||||
|
@ -2347,7 +2347,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
myPatientDao.create(p, mySrd);
|
||||
}
|
||||
|
||||
String uri = ourServerBase + "/Patient?name=" + URLEncoder.encode("Jernelöv", "UTF-8") + "&_count=5&_pretty=true";
|
||||
String uri = ourServerBase + "/Patient?name=" + UrlUtil.escapeUrlParam("Jernelöv") + "&_count=5&_pretty=true";
|
||||
ourLog.info("URI: {}", uri);
|
||||
HttpGet get = new HttpGet(uri);
|
||||
CloseableHttpResponse resp = ourHttpClient.execute(get);
|
||||
|
@ -3792,7 +3792,7 @@ public class ResourceProviderDstu3Test extends BaseResourceProviderDstu3Test {
|
|||
|
||||
pt.addName().setFamily("FOO");
|
||||
resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escape("|"))));
|
||||
HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escapeUrlParam("|"))));
|
||||
put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
IdType id2;
|
||||
|
|
|
@ -25,7 +25,7 @@ public class GraphQLProviderR4Test extends BaseResourceProviderR4Test {
|
|||
initTestPatients();
|
||||
|
||||
String query = "{name{family,given}}";
|
||||
HttpGet httpGet = new HttpGet(ourServerBase + "/Patient/" + myPatientId0.getIdPart() + "/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet(ourServerBase + "/Patient/" + myPatientId0.getIdPart() + "/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
|
||||
CloseableHttpResponse response = ourHttpClient.execute(httpGet);
|
||||
try {
|
||||
|
@ -50,7 +50,7 @@ public class GraphQLProviderR4Test extends BaseResourceProviderR4Test {
|
|||
initTestPatients();
|
||||
|
||||
String query = "{PatientList(given:\"given\"){name{family,given}}}";
|
||||
HttpGet httpGet = new HttpGet(ourServerBase + "/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet(ourServerBase + "/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
|
||||
CloseableHttpResponse response = ourHttpClient.execute(httpGet);
|
||||
try {
|
||||
|
|
|
@ -61,7 +61,6 @@ import java.math.BigDecimal;
|
|||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
|
@ -1647,7 +1646,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
myObservationDao.create(obs, mySrd);
|
||||
}
|
||||
|
||||
String uri = ourServerBase + "/Patient?_has:Observation:subject:identifier=" + UrlUtil.escape("urn:system|FOO");
|
||||
String uri = ourServerBase + "/Patient?_has:Observation:subject:identifier=" + UrlUtil.escapeUrlParam("urn:system|FOO");
|
||||
List<String> ids = searchAndReturnUnqualifiedVersionlessIdValues(uri);
|
||||
assertThat(ids, contains(pid0.getValue()));
|
||||
}
|
||||
|
@ -2355,7 +2354,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
myPatientDao.create(p, mySrd);
|
||||
}
|
||||
|
||||
String uri = ourServerBase + "/Patient?name=" + URLEncoder.encode("Jernelöv", "UTF-8") + "&_count=5&_pretty=true";
|
||||
String uri = ourServerBase + "/Patient?name=" + UrlUtil.escapeUrlParam("Jernelöv") + "&_count=5&_pretty=true";
|
||||
ourLog.info("URI: {}", uri);
|
||||
HttpGet get = new HttpGet(uri);
|
||||
CloseableHttpResponse resp = ourHttpClient.execute(get);
|
||||
|
@ -3938,7 +3937,7 @@ public class ResourceProviderR4Test extends BaseResourceProviderR4Test {
|
|||
|
||||
pt.addName().setFamily("FOO");
|
||||
resource = myFhirCtx.newXmlParser().encodeResourceToString(pt);
|
||||
HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escape("|"))));
|
||||
HttpPut put = new HttpPut(ourServerBase + "/Patient?identifier=" + ("http://general-hospital.co.uk/Identifiers|09832345234543876876".replace("|", UrlUtil.escapeUrlParam("|"))));
|
||||
put.setEntity(new StringEntity(resource, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
IdType id2;
|
||||
|
|
|
@ -80,13 +80,13 @@ public class AnalyticsInterceptor extends InterceptorAdapter {
|
|||
b.append("&tid=").append(myAnalyticsTid);
|
||||
|
||||
b.append("&t=event");
|
||||
b.append("&an=").append(UrlUtil.escape(myHostname)).append('+').append(UrlUtil.escape(next.getApplicationName()));
|
||||
b.append("&an=").append(UrlUtil.escapeUrlParam(myHostname)).append('+').append(UrlUtil.escapeUrlParam(next.getApplicationName()));
|
||||
b.append("&ec=").append(next.getResourceName());
|
||||
b.append("&ea=").append(next.getRestOperation());
|
||||
|
||||
b.append("&cid=").append(next.getClientId());
|
||||
b.append("&uip=").append(UrlUtil.escape(next.getSourceIp()));
|
||||
b.append("&ua=").append(UrlUtil.escape(next.getUserAgent()));
|
||||
b.append("&uip=").append(UrlUtil.escapeUrlParam(next.getSourceIp()));
|
||||
b.append("&ua=").append(UrlUtil.escapeUrlParam(next.getUserAgent()));
|
||||
b.append("\n");
|
||||
}
|
||||
|
||||
|
|
|
@ -19,34 +19,38 @@ package ca.uhn.fhir.rest.server;
|
|||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import ca.uhn.fhir.util.BinaryUtil;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.FhirVersionEnum;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.PreferReturnEnum;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.api.server.IRestfulResponse;
|
||||
import ca.uhn.fhir.rest.api.server.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.method.ElementsParameter;
|
||||
import ca.uhn.fhir.rest.server.method.SummaryEnumParameter;
|
||||
import ca.uhn.fhir.util.BinaryUtil;
|
||||
import ca.uhn.fhir.util.DateUtils;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.hl7.fhir.instance.model.api.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.IOException;
|
||||
import java.io.Writer;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
public class RestfulServerUtils {
|
||||
static final Pattern ACCEPT_HEADER_PATTERN = Pattern.compile("\\s*([a-zA-Z0-9+.*/-]+)\\s*(;\\s*([a-zA-Z]+)\\s*=\\s*([a-zA-Z0-9.]+)\\s*)?(,?)");
|
||||
|
@ -127,74 +131,70 @@ public class RestfulServerUtils {
|
|||
}
|
||||
|
||||
public static String createPagingLink(Set<Include> theIncludes, String theServerBase, String theSearchId, int theOffset, int theCount, Map<String, String[]> theRequestParameters, boolean thePrettyPrint,
|
||||
BundleTypeEnum theBundleType) {
|
||||
try {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(theServerBase);
|
||||
b.append('?');
|
||||
b.append(Constants.PARAM_PAGINGACTION);
|
||||
b.append('=');
|
||||
b.append(URLEncoder.encode(theSearchId, "UTF-8"));
|
||||
BundleTypeEnum theBundleType) {
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(theServerBase);
|
||||
b.append('?');
|
||||
b.append(Constants.PARAM_PAGINGACTION);
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(theSearchId));
|
||||
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_PAGINGOFFSET);
|
||||
b.append('=');
|
||||
b.append(theOffset);
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_COUNT);
|
||||
b.append('=');
|
||||
b.append(theCount);
|
||||
String[] strings = theRequestParameters.get(Constants.PARAM_FORMAT);
|
||||
if (strings != null && strings.length > 0) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_PAGINGOFFSET);
|
||||
b.append(Constants.PARAM_FORMAT);
|
||||
b.append('=');
|
||||
b.append(theOffset);
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_COUNT);
|
||||
b.append('=');
|
||||
b.append(theCount);
|
||||
String[] strings = theRequestParameters.get(Constants.PARAM_FORMAT);
|
||||
if (strings != null && strings.length > 0) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_FORMAT);
|
||||
b.append('=');
|
||||
String format = strings[0];
|
||||
format = replace(format, " ", "+");
|
||||
b.append(UrlUtil.escape(format));
|
||||
}
|
||||
if (thePrettyPrint) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_PRETTY);
|
||||
b.append('=');
|
||||
b.append(Constants.PARAM_PRETTY_VALUE_TRUE);
|
||||
}
|
||||
|
||||
if (theIncludes != null) {
|
||||
for (Include nextInclude : theIncludes) {
|
||||
if (isNotBlank(nextInclude.getValue())) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_INCLUDE);
|
||||
b.append('=');
|
||||
b.append(URLEncoder.encode(nextInclude.getValue(), "UTF-8"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theBundleType != null) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_BUNDLETYPE);
|
||||
b.append('=');
|
||||
b.append(theBundleType.getCode());
|
||||
}
|
||||
|
||||
String paramName = Constants.PARAM_ELEMENTS;
|
||||
String[] params = theRequestParameters.get(paramName);
|
||||
if (params != null) {
|
||||
for (String nextValue : params) {
|
||||
if (isNotBlank(nextValue)) {
|
||||
b.append('&');
|
||||
b.append(paramName);
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escape(nextValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error("UTF-8 not supported", e);// should not happen
|
||||
String format = strings[0];
|
||||
format = replace(format, " ", "+");
|
||||
b.append(UrlUtil.escapeUrlParam(format));
|
||||
}
|
||||
if (thePrettyPrint) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_PRETTY);
|
||||
b.append('=');
|
||||
b.append(Constants.PARAM_PRETTY_VALUE_TRUE);
|
||||
}
|
||||
|
||||
if (theIncludes != null) {
|
||||
for (Include nextInclude : theIncludes) {
|
||||
if (isNotBlank(nextInclude.getValue())) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_INCLUDE);
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(nextInclude.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (theBundleType != null) {
|
||||
b.append('&');
|
||||
b.append(Constants.PARAM_BUNDLETYPE);
|
||||
b.append('=');
|
||||
b.append(theBundleType.getCode());
|
||||
}
|
||||
|
||||
String paramName = Constants.PARAM_ELEMENTS;
|
||||
String[] params = theRequestParameters.get(paramName);
|
||||
if (params != null) {
|
||||
for (String nextValue : params) {
|
||||
if (isNotBlank(nextValue)) {
|
||||
b.append('&');
|
||||
b.append(paramName);
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(nextValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -392,15 +392,15 @@ public class RestfulServerUtils {
|
|||
try {
|
||||
NarrativeModeEnum narrativeMode = NarrativeModeEnum.valueOfCaseInsensitive(narrative[0]);
|
||||
switch (narrativeMode) {
|
||||
case NORMAL:
|
||||
retVal = Collections.singleton(SummaryEnum.FALSE);
|
||||
break;
|
||||
case ONLY:
|
||||
retVal = Collections.singleton(SummaryEnum.TEXT);
|
||||
break;
|
||||
case SUPPRESS:
|
||||
retVal = Collections.singleton(SummaryEnum.DATA);
|
||||
break;
|
||||
case NORMAL:
|
||||
retVal = Collections.singleton(SummaryEnum.FALSE);
|
||||
break;
|
||||
case ONLY:
|
||||
retVal = Collections.singleton(SummaryEnum.TEXT);
|
||||
break;
|
||||
case SUPPRESS:
|
||||
retVal = Collections.singleton(SummaryEnum.DATA);
|
||||
break;
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
ourLog.debug("Invalid {} parameter: {}", Constants.PARAM_NARRATIVE, narrative[0]);
|
||||
|
@ -461,13 +461,13 @@ public class RestfulServerUtils {
|
|||
EncodingEnum responseEncoding = RestfulServerUtils.determineResponseEncodingWithDefault(theRequestDetails).getEncoding();
|
||||
IParser parser;
|
||||
switch (responseEncoding) {
|
||||
case JSON:
|
||||
parser = theContext.newJsonParser();
|
||||
break;
|
||||
case XML:
|
||||
default:
|
||||
parser = theContext.newXmlParser();
|
||||
break;
|
||||
case JSON:
|
||||
parser = theContext.newJsonParser();
|
||||
break;
|
||||
case XML:
|
||||
default:
|
||||
parser = theContext.newXmlParser();
|
||||
break;
|
||||
}
|
||||
|
||||
configureResponseParser(theRequestDetails, parser);
|
||||
|
@ -581,13 +581,13 @@ public class RestfulServerUtils {
|
|||
}
|
||||
|
||||
public static Object streamResponseAsResource(IRestfulServerDefaults theServer, IBaseResource theResource, Set<SummaryEnum> theSummaryMode, int stausCode, boolean theAddContentLocationHeader,
|
||||
boolean respondGzip, RequestDetails theRequestDetails) throws IOException {
|
||||
boolean respondGzip, RequestDetails theRequestDetails) throws IOException {
|
||||
return streamResponseAsResource(theServer, theResource, theSummaryMode, stausCode, null, theAddContentLocationHeader, respondGzip, theRequestDetails, null, null);
|
||||
}
|
||||
|
||||
public static Object streamResponseAsResource(IRestfulServerDefaults theServer, IBaseResource theResource, Set<SummaryEnum> theSummaryMode, int theStausCode, String theStatusMessage,
|
||||
boolean theAddContentLocationHeader, boolean respondGzip, RequestDetails theRequestDetails, IIdType theOperationResourceId, IPrimitiveType<Date> theOperationResourceLastUpdated)
|
||||
throws IOException {
|
||||
boolean theAddContentLocationHeader, boolean respondGzip, RequestDetails theRequestDetails, IIdType theOperationResourceId, IPrimitiveType<Date> theOperationResourceLastUpdated)
|
||||
throws IOException {
|
||||
IRestfulResponse response = theRequestDetails.getResponse();
|
||||
|
||||
// Determine response encoding
|
||||
|
@ -706,7 +706,7 @@ public class RestfulServerUtils {
|
|||
try {
|
||||
return Integer.parseInt(retVal[0]);
|
||||
} catch (NumberFormatException e) {
|
||||
ourLog.debug("Failed to parse {} value '{}': {}", new Object[] { theParamName, retVal[0], e });
|
||||
ourLog.debug("Failed to parse {} value '{}': {}", new Object[]{theParamName, retVal[0], e});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -752,7 +752,7 @@ public class RestfulServerUtils {
|
|||
if (theContentType.equals(EncodingEnum.JSON_PLAIN_STRING) || theContentType.equals(EncodingEnum.XML_PLAIN_STRING)) {
|
||||
FhirVersionEnum ctxtEnum = theCtx.getVersion().getVersion();
|
||||
myNonLegacy = ctxtEnum.isNewerThan(FhirVersionEnum.DSTU3)
|
||||
|| (ctxtEnum.isEquivalentTo(FhirVersionEnum.DSTU3) && !"1.4.0".equals(theCtx.getVersion().getVersion().getFhirVersionString()));
|
||||
|| (ctxtEnum.isEquivalentTo(FhirVersionEnum.DSTU3) && !"1.4.0".equals(theCtx.getVersion().getVersion().getFhirVersionString()));
|
||||
} else {
|
||||
myNonLegacy = EncodingEnum.isNonLegacy(theContentType);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.io.IOException;
|
|||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Date;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
@ -33,6 +32,7 @@ import javax.servlet.ServletException;
|
|||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.apache.commons.lang3.text.StrLookup;
|
||||
|
@ -277,13 +277,9 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
try {
|
||||
b.append(URLEncoder.encode(next.getKey(), "UTF-8"));
|
||||
b.append('=');
|
||||
b.append(URLEncoder.encode(nextValue, "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ca.uhn.fhir.context.ConfigurationException("UTF-8 not supported", e);
|
||||
}
|
||||
b.append(UrlUtil.escapeUrlParam(next.getKey()));
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escapeUrlParam(nextValue));
|
||||
}
|
||||
}
|
||||
return b.toString();
|
||||
|
|
|
@ -92,9 +92,9 @@ public class ResponseHighlighterInterceptor extends InterceptorAdapter {
|
|||
} else {
|
||||
rawB.append('&');
|
||||
}
|
||||
rawB.append(UrlUtil.escape(next));
|
||||
rawB.append(UrlUtil.escapeUrlParam(next));
|
||||
rawB.append('=');
|
||||
rawB.append(UrlUtil.escape(nextValue));
|
||||
rawB.append(UrlUtil.escapeUrlParam(nextValue));
|
||||
}
|
||||
}
|
||||
if (rawB.length() == 0) {
|
||||
|
|
|
@ -186,9 +186,9 @@ public abstract class BaseResourceReturningMethodBinding extends BaseMethodBindi
|
|||
} else {
|
||||
b.append('&');
|
||||
}
|
||||
b.append(UrlUtil.escape(nextParamName));
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamName));
|
||||
b.append('=');
|
||||
b.append(UrlUtil.escape(nextParamValue));
|
||||
b.append(UrlUtil.escapeUrlParam(nextParamValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
@ -20,20 +23,11 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.primitive.DateTimeDt;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.CompositeAndListParam;
|
||||
import ca.uhn.fhir.rest.param.CompositeOrListParam;
|
||||
import ca.uhn.fhir.rest.param.CompositeParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -48,7 +42,7 @@ public class CompositeParameterTest {
|
|||
@Test
|
||||
public void testSearchWithDateValue() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation?" + Observation.SP_NAME_VALUE_DATE + "=" + URLEncoder.encode("foo\\$bar$2001-01-01", "UTF-8"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation?" + Observation.SP_NAME_VALUE_DATE + "=" + UrlUtil.escape("foo\\$bar$2001-01-01"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
@ -66,7 +60,7 @@ public class CompositeParameterTest {
|
|||
@Test
|
||||
public void testSearchWithMultipleValue() throws Exception {
|
||||
{
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation?" + Observation.SP_NAME_VALUE_STRING + "=" + URLEncoder.encode("l1$r1,l2$r2", "UTF-8") + "&" + Observation.SP_NAME_VALUE_STRING + "=" + URLEncoder.encode("l3$r3,l4$r4", "UTF-8"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Observation?" + Observation.SP_NAME_VALUE_STRING + "=" + UrlUtil.escape("l1$r1,l2$r2") + "&" + Observation.SP_NAME_VALUE_STRING + "=" + UrlUtil.escape("l3$r3,l4$r4"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.hamcrest.Matchers.stringContainsInOrder;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
|
@ -22,20 +21,11 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.common.net.UrlEscapers;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.BaseResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.not;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class DefaultEncodingTest {
|
||||
|
||||
|
|
|
@ -1,11 +1,17 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.BaseResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
|
@ -20,18 +26,10 @@ import org.junit.AfterClass;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.BaseResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ReadDstu1Test {
|
||||
|
||||
|
@ -129,10 +127,10 @@ public class ReadDstu1Test {
|
|||
@Test
|
||||
public void testReadWithEscapedCharsInId() throws Exception {
|
||||
String id = "ABC!@#$--DEF";
|
||||
String idEscaped = URLEncoder.encode(id, "UTF-8");
|
||||
String idEscaped = UrlUtil.escapeid);
|
||||
|
||||
String vid = "GHI:/:/JKL";
|
||||
String vidEscaped = URLEncoder.encode(vid, "UTF-8");
|
||||
String vidEscaped = UrlUtil.escape(vid);
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/" + idEscaped + "/_history/" + vidEscaped);
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
|
|
@ -1,41 +1,12 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.utils.URLEncodedUtils;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.BundleEntry;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu.resource.*;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResourceSearchParam;
|
||||
import ca.uhn.fhir.model.dstu.resource.Location;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.ResourceTypeEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
|
@ -47,6 +18,27 @@ import ca.uhn.fhir.rest.param.StringParam;
|
|||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ServletHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.defaultString;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -105,7 +97,7 @@ public class ReferenceParameterTest {
|
|||
|
||||
@Test
|
||||
public void testReferenceParamViewToken() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?provider.name=" + URLEncoder.encode("foo|bar", "UTF-8"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?provider.name=" + UrlUtil.escape("foo|bar"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
|
|
@ -105,7 +105,7 @@ public class OperationServerWithSearchParamTypesDstu2_1Test {
|
|||
|
||||
@Test
|
||||
public void testEscapedOperationName() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/%24andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/%24andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -118,7 +118,7 @@ public class OperationServerWithSearchParamTypesDstu2_1Test {
|
|||
|
||||
@Test
|
||||
public void testAndListWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -270,7 +270,7 @@ public class OperationServerWithSearchParamTypesDstu2_1Test {
|
|||
}
|
||||
@Test
|
||||
public void testNonRepeatingWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr=VALSTR&valtok=" + UrlUtil.escape("VALTOKA|VALTOKB"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr=VALSTR&valtok=" + UrlUtil.escapeUrlParam("VALTOKA|VALTOKB"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -290,7 +290,7 @@ public class OperationServerWithSearchParamTypesDstu2_1Test {
|
|||
|
||||
@Test
|
||||
public void testNonRepeatingWithUrlQualified() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr:exact=VALSTR&valtok:not=" + UrlUtil.escape("VALTOKA|VALTOKB"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr:exact=VALSTR&valtok:not=" + UrlUtil.escapeUrlParam("VALTOKA|VALTOKB"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -345,7 +345,7 @@ public class OperationServerWithSearchParamTypesDstu2_1Test {
|
|||
|
||||
@Test
|
||||
public void testOrListWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$orlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$orlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
|
|
@ -110,8 +110,8 @@ public class OperationServerWithSearchParamTypesDstu2Test {
|
|||
|
||||
@Test
|
||||
public void testAndListWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok="
|
||||
+ UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok="
|
||||
+ UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -214,7 +214,7 @@ public class OperationServerWithSearchParamTypesDstu2Test {
|
|||
|
||||
@Test
|
||||
public void testNonRepeatingWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr=VALSTR&valtok=" + UrlUtil.escape("VALTOKA|VALTOKB"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr=VALSTR&valtok=" + UrlUtil.escapeUrlParam("VALTOKA|VALTOKB"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -234,7 +234,7 @@ public class OperationServerWithSearchParamTypesDstu2Test {
|
|||
|
||||
@Test
|
||||
public void testNonRepeatingWithUrlQualified() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr:exact=VALSTR&valtok:not=" + UrlUtil.escape("VALTOKA|VALTOKB"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr:exact=VALSTR&valtok:not=" + UrlUtil.escapeUrlParam("VALTOKA|VALTOKB"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -289,8 +289,8 @@ public class OperationServerWithSearchParamTypesDstu2Test {
|
|||
|
||||
@Test
|
||||
public void testOrListWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$orlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok="
|
||||
+ UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$orlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok="
|
||||
+ UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
@ -22,14 +24,11 @@ import org.junit.Before;
|
|||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu2.resource.Patient;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class ServerSearchDstu2Test {
|
||||
|
||||
|
@ -106,7 +105,7 @@ public class ServerSearchDstu2Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithEncodedValue() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/?param1=" + URLEncoder.encode("Jernelöv", "UTF-8"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/?param1=" + UrlUtil.escapeUrlParam("Jernelöv"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
|
|
|
@ -14,7 +14,6 @@ import static org.junit.Assert.assertTrue;
|
|||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
@ -186,7 +185,7 @@ public class ResponseHighlightingInterceptorTest {
|
|||
|
||||
@Test
|
||||
public void testForceApplicationJsonPlusFhir() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/json+fhir"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escapeUrlParam("application/json+fhir"));
|
||||
httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1");
|
||||
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
@ -225,7 +224,7 @@ public class ResponseHighlightingInterceptorTest {
|
|||
|
||||
@Test
|
||||
public void testForceApplicationXmlPlusFhir() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escape("application/xml+fhir"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1?_format=" + UrlUtil.escapeUrlParam("application/xml+fhir"));
|
||||
httpGet.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1");
|
||||
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
|
|
@ -1,122 +1,122 @@
|
|||
package org.hl7.fhir.dstu3.model.codesystems;
|
||||
|
||||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
// Generated on Sat, Mar 25, 2017 21:03-0400 for FHIR v3.0.0
|
||||
|
||||
|
||||
import org.hl7.fhir.dstu3.model.EnumFactory;
|
||||
|
||||
public class MapTransformEnumFactory implements EnumFactory<MapTransform> {
|
||||
|
||||
public MapTransform fromCode(String codeString) throws IllegalArgumentException {
|
||||
if (codeString == null || "".equals(codeString))
|
||||
return null;
|
||||
if ("create".equals(codeString))
|
||||
return MapTransform.CREATE;
|
||||
if ("copy".equals(codeString))
|
||||
return MapTransform.COPY;
|
||||
if ("truncate".equals(codeString))
|
||||
return MapTransform.TRUNCATE;
|
||||
if ("escape".equals(codeString))
|
||||
return MapTransform.ESCAPE;
|
||||
if ("cast".equals(codeString))
|
||||
return MapTransform.CAST;
|
||||
if ("append".equals(codeString))
|
||||
return MapTransform.APPEND;
|
||||
if ("translate".equals(codeString))
|
||||
return MapTransform.TRANSLATE;
|
||||
if ("reference".equals(codeString))
|
||||
return MapTransform.REFERENCE;
|
||||
if ("dateOp".equals(codeString))
|
||||
return MapTransform.DATEOP;
|
||||
if ("uuid".equals(codeString))
|
||||
return MapTransform.UUID;
|
||||
if ("pointer".equals(codeString))
|
||||
return MapTransform.POINTER;
|
||||
if ("evaluate".equals(codeString))
|
||||
return MapTransform.EVALUATE;
|
||||
if ("cc".equals(codeString))
|
||||
return MapTransform.CC;
|
||||
if ("c".equals(codeString))
|
||||
return MapTransform.C;
|
||||
if ("qty".equals(codeString))
|
||||
return MapTransform.QTY;
|
||||
if ("id".equals(codeString))
|
||||
return MapTransform.ID;
|
||||
if ("cp".equals(codeString))
|
||||
return MapTransform.CP;
|
||||
throw new IllegalArgumentException("Unknown MapTransform code '"+codeString+"'");
|
||||
}
|
||||
|
||||
public String toCode(MapTransform code) {
|
||||
if (code == MapTransform.CREATE)
|
||||
return "create";
|
||||
if (code == MapTransform.COPY)
|
||||
return "copy";
|
||||
if (code == MapTransform.TRUNCATE)
|
||||
return "truncate";
|
||||
if (code == MapTransform.ESCAPE)
|
||||
return "escape";
|
||||
if (code == MapTransform.CAST)
|
||||
return "cast";
|
||||
if (code == MapTransform.APPEND)
|
||||
return "append";
|
||||
if (code == MapTransform.TRANSLATE)
|
||||
return "translate";
|
||||
if (code == MapTransform.REFERENCE)
|
||||
return "reference";
|
||||
if (code == MapTransform.DATEOP)
|
||||
return "dateOp";
|
||||
if (code == MapTransform.UUID)
|
||||
return "uuid";
|
||||
if (code == MapTransform.POINTER)
|
||||
return "pointer";
|
||||
if (code == MapTransform.EVALUATE)
|
||||
return "evaluate";
|
||||
if (code == MapTransform.CC)
|
||||
return "cc";
|
||||
if (code == MapTransform.C)
|
||||
return "c";
|
||||
if (code == MapTransform.QTY)
|
||||
return "qty";
|
||||
if (code == MapTransform.ID)
|
||||
return "id";
|
||||
if (code == MapTransform.CP)
|
||||
return "cp";
|
||||
return "?";
|
||||
}
|
||||
|
||||
public String toSystem(MapTransform code) {
|
||||
return code.getSystem();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
package org.hl7.fhir.dstu3.model.codesystems;
|
||||
|
||||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
|
||||
// Generated on Sat, Mar 25, 2017 21:03-0400 for FHIR v3.0.0
|
||||
|
||||
|
||||
import org.hl7.fhir.dstu3.model.EnumFactory;
|
||||
|
||||
public class MapTransformEnumFactory implements EnumFactory<MapTransform> {
|
||||
|
||||
public MapTransform fromCode(String codeString) throws IllegalArgumentException {
|
||||
if (codeString == null || "".equals(codeString))
|
||||
return null;
|
||||
if ("create".equals(codeString))
|
||||
return MapTransform.CREATE;
|
||||
if ("copy".equals(codeString))
|
||||
return MapTransform.COPY;
|
||||
if ("truncate".equals(codeString))
|
||||
return MapTransform.TRUNCATE;
|
||||
if ("escapeUrlParam".equals(codeString))
|
||||
return MapTransform.ESCAPE;
|
||||
if ("cast".equals(codeString))
|
||||
return MapTransform.CAST;
|
||||
if ("append".equals(codeString))
|
||||
return MapTransform.APPEND;
|
||||
if ("translate".equals(codeString))
|
||||
return MapTransform.TRANSLATE;
|
||||
if ("reference".equals(codeString))
|
||||
return MapTransform.REFERENCE;
|
||||
if ("dateOp".equals(codeString))
|
||||
return MapTransform.DATEOP;
|
||||
if ("uuid".equals(codeString))
|
||||
return MapTransform.UUID;
|
||||
if ("pointer".equals(codeString))
|
||||
return MapTransform.POINTER;
|
||||
if ("evaluate".equals(codeString))
|
||||
return MapTransform.EVALUATE;
|
||||
if ("cc".equals(codeString))
|
||||
return MapTransform.CC;
|
||||
if ("c".equals(codeString))
|
||||
return MapTransform.C;
|
||||
if ("qty".equals(codeString))
|
||||
return MapTransform.QTY;
|
||||
if ("id".equals(codeString))
|
||||
return MapTransform.ID;
|
||||
if ("cp".equals(codeString))
|
||||
return MapTransform.CP;
|
||||
throw new IllegalArgumentException("Unknown MapTransform code '"+codeString+"'");
|
||||
}
|
||||
|
||||
public String toCode(MapTransform code) {
|
||||
if (code == MapTransform.CREATE)
|
||||
return "create";
|
||||
if (code == MapTransform.COPY)
|
||||
return "copy";
|
||||
if (code == MapTransform.TRUNCATE)
|
||||
return "truncate";
|
||||
if (code == MapTransform.ESCAPE)
|
||||
return "escapeUrlParam";
|
||||
if (code == MapTransform.CAST)
|
||||
return "cast";
|
||||
if (code == MapTransform.APPEND)
|
||||
return "append";
|
||||
if (code == MapTransform.TRANSLATE)
|
||||
return "translate";
|
||||
if (code == MapTransform.REFERENCE)
|
||||
return "reference";
|
||||
if (code == MapTransform.DATEOP)
|
||||
return "dateOp";
|
||||
if (code == MapTransform.UUID)
|
||||
return "uuid";
|
||||
if (code == MapTransform.POINTER)
|
||||
return "pointer";
|
||||
if (code == MapTransform.EVALUATE)
|
||||
return "evaluate";
|
||||
if (code == MapTransform.CC)
|
||||
return "cc";
|
||||
if (code == MapTransform.C)
|
||||
return "c";
|
||||
if (code == MapTransform.QTY)
|
||||
return "qty";
|
||||
if (code == MapTransform.ID)
|
||||
return "id";
|
||||
if (code == MapTransform.CP)
|
||||
return "cp";
|
||||
return "?";
|
||||
}
|
||||
|
||||
public String toSystem(MapTransform code) {
|
||||
return code.getSystem();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ public class OperationServerWithSearchParamTypesDstu3Test {
|
|||
|
||||
@Test
|
||||
public void testEscapedOperationName() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/%24andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/%24andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -118,7 +118,7 @@ public class OperationServerWithSearchParamTypesDstu3Test {
|
|||
|
||||
@Test
|
||||
public void testAndListWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$andlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -270,7 +270,7 @@ public class OperationServerWithSearchParamTypesDstu3Test {
|
|||
}
|
||||
@Test
|
||||
public void testNonRepeatingWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr=VALSTR&valtok=" + UrlUtil.escape("VALTOKA|VALTOKB"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr=VALSTR&valtok=" + UrlUtil.escapeUrlParam("VALTOKA|VALTOKB"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -290,7 +290,7 @@ public class OperationServerWithSearchParamTypesDstu3Test {
|
|||
|
||||
@Test
|
||||
public void testNonRepeatingWithUrlQualified() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr:exact=VALSTR&valtok:not=" + UrlUtil.escape("VALTOKA|VALTOKB"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$nonrepeating?valstr:exact=VALSTR&valtok:not=" + UrlUtil.escapeUrlParam("VALTOKA|VALTOKB"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
@ -345,7 +345,7 @@ public class OperationServerWithSearchParamTypesDstu3Test {
|
|||
|
||||
@Test
|
||||
public void testOrListWithUrl() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$orlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escape("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escape("VALTOK2A|VALTOK2B"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/$orlist?valstr=VALSTR1A,VALSTR1B&valstr=VALSTR2A,VALSTR2B&valtok=" + UrlUtil.escapeUrlParam("VALTOK1A|VALTOK1B") + "&valtok=" + UrlUtil.escapeUrlParam("VALTOK2A|VALTOK2B"));
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
|
|
|
@ -137,25 +137,25 @@ public class SearchDstu3Test {
|
|||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar&_format=" + Constants.CT_FHIR_JSON_NEW);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
// Fetch the next page
|
||||
httpGet = new HttpGet(linkNext);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
// Fetch the next page
|
||||
httpGet = new HttpGet(linkNext);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
// Fetch the next page
|
||||
httpGet = new HttpGet(linkNext);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,406 +1,406 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
package org.hl7.fhir.instance.utilities.xml;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.hl7.fhir.instance.utilities.Utilities;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.ls.DOMImplementationLS;
|
||||
import org.w3c.dom.ls.LSSerializer;
|
||||
|
||||
public class XMLUtil {
|
||||
|
||||
public static final String SPACE_CHAR = "\u00A0";
|
||||
|
||||
public static boolean isNMToken(String name) {
|
||||
if (name == null)
|
||||
return false;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
if (!isNMTokenChar(name.charAt(i)))
|
||||
return false;
|
||||
return name.length() > 0;
|
||||
}
|
||||
|
||||
public static boolean isNMTokenChar(char c) {
|
||||
return isLetter(c) || isDigit(c) || c == '.' || c == '-' || c == '_' || c == ':' || isCombiningChar(c) || isExtender(c);
|
||||
}
|
||||
|
||||
private static boolean isDigit(char c) {
|
||||
return (c >= '\u0030' && c <= '\u0039') || (c >= '\u0660' && c <= '\u0669') || (c >= '\u06F0' && c <= '\u06F9') ||
|
||||
(c >= '\u0966' && c <= '\u096F') || (c >= '\u09E6' && c <= '\u09EF') || (c >= '\u0A66' && c <= '\u0A6F') ||
|
||||
(c >= '\u0AE6' && c <= '\u0AEF') || (c >= '\u0B66' && c <= '\u0B6F') || (c >= '\u0BE7' && c <= '\u0BEF') ||
|
||||
(c >= '\u0C66' && c <= '\u0C6F') || (c >= '\u0CE6' && c <= '\u0CEF') || (c >= '\u0D66' && c <= '\u0D6F') ||
|
||||
(c >= '\u0E50' && c <= '\u0E59') || (c >= '\u0ED0' && c <= '\u0ED9') || (c >= '\u0F20' && c <= '\u0F29');
|
||||
}
|
||||
|
||||
private static boolean isCombiningChar(char c) {
|
||||
return (c >= '\u0300' && c <= '\u0345') || (c >= '\u0360' && c <= '\u0361') || (c >= '\u0483' && c <= '\u0486') ||
|
||||
(c >= '\u0591' && c <= '\u05A1') || (c >= '\u05A3' && c <= '\u05B9') || (c >= '\u05BB' && c <= '\u05BD') ||
|
||||
c == '\u05BF' || (c >= '\u05C1' && c <= '\u05C2') || c == '\u05C4' || (c >= '\u064B' && c <= '\u0652') ||
|
||||
c == '\u0670' || (c >= '\u06D6' && c <= '\u06DC') || (c >= '\u06DD' && c <= '\u06DF') || (c >= '\u06E0' && c <= '\u06E4') ||
|
||||
(c >= '\u06E7' && c <= '\u06E8') || (c >= '\u06EA' && c <= '\u06ED') || (c >= '\u0901' && c <= '\u0903') || c == '\u093C' ||
|
||||
(c >= '\u093E' && c <= '\u094C') || c == '\u094D' || (c >= '\u0951' && c <= '\u0954') || (c >= '\u0962' && c <= '\u0963') ||
|
||||
(c >= '\u0981' && c <= '\u0983') || c == '\u09BC' || c == '\u09BE' || c == '\u09BF' || (c >= '\u09C0' && c <= '\u09C4') ||
|
||||
(c >= '\u09C7' && c <= '\u09C8') || (c >= '\u09CB' && c <= '\u09CD') || c == '\u09D7' || (c >= '\u09E2' && c <= '\u09E3') ||
|
||||
c == '\u0A02' || c == '\u0A3C' || c == '\u0A3E' || c == '\u0A3F' || (c >= '\u0A40' && c <= '\u0A42') ||
|
||||
(c >= '\u0A47' && c <= '\u0A48') || (c >= '\u0A4B' && c <= '\u0A4D') || (c >= '\u0A70' && c <= '\u0A71') ||
|
||||
(c >= '\u0A81' && c <= '\u0A83') || c == '\u0ABC' || (c >= '\u0ABE' && c <= '\u0AC5') || (c >= '\u0AC7' && c <= '\u0AC9') ||
|
||||
(c >= '\u0ACB' && c <= '\u0ACD') || (c >= '\u0B01' && c <= '\u0B03') || c == '\u0B3C' || (c >= '\u0B3E' && c <= '\u0B43') ||
|
||||
(c >= '\u0B47' && c <= '\u0B48') || (c >= '\u0B4B' && c <= '\u0B4D') || (c >= '\u0B56' && c <= '\u0B57') ||
|
||||
(c >= '\u0B82' && c <= '\u0B83') || (c >= '\u0BBE' && c <= '\u0BC2') || (c >= '\u0BC6' && c <= '\u0BC8') ||
|
||||
(c >= '\u0BCA' && c <= '\u0BCD') || c == '\u0BD7' || (c >= '\u0C01' && c <= '\u0C03') || (c >= '\u0C3E' && c <= '\u0C44') ||
|
||||
(c >= '\u0C46' && c <= '\u0C48') || (c >= '\u0C4A' && c <= '\u0C4D') || (c >= '\u0C55' && c <= '\u0C56') ||
|
||||
(c >= '\u0C82' && c <= '\u0C83') || (c >= '\u0CBE' && c <= '\u0CC4') || (c >= '\u0CC6' && c <= '\u0CC8') ||
|
||||
(c >= '\u0CCA' && c <= '\u0CCD') || (c >= '\u0CD5' && c <= '\u0CD6') || (c >= '\u0D02' && c <= '\u0D03') ||
|
||||
(c >= '\u0D3E' && c <= '\u0D43') || (c >= '\u0D46' && c <= '\u0D48') || (c >= '\u0D4A' && c <= '\u0D4D') || c == '\u0D57' ||
|
||||
c == '\u0E31' || (c >= '\u0E34' && c <= '\u0E3A') || (c >= '\u0E47' && c <= '\u0E4E') || c == '\u0EB1' ||
|
||||
(c >= '\u0EB4' && c <= '\u0EB9') || (c >= '\u0EBB' && c <= '\u0EBC') || (c >= '\u0EC8' && c <= '\u0ECD') ||
|
||||
(c >= '\u0F18' && c <= '\u0F19') || c == '\u0F35' || c == '\u0F37' || c == '\u0F39' || c == '\u0F3E' || c == '\u0F3F' ||
|
||||
(c >= '\u0F71' && c <= '\u0F84') || (c >= '\u0F86' && c <= '\u0F8B') || (c >= '\u0F90' && c <= '\u0F95') || c == '\u0F97' ||
|
||||
(c >= '\u0F99' && c <= '\u0FAD') || (c >= '\u0FB1' && c <= '\u0FB7') || c == '\u0FB9' || (c >= '\u20D0' && c <= '\u20DC') ||
|
||||
c == '\u20E1' || (c >= '\u302A' && c <= '\u302F') || c == '\u3099' || c == '\u309A';
|
||||
}
|
||||
|
||||
private static boolean isExtender(char c) {
|
||||
return c == '\u00B7' || c == '\u02D0' || c == '\u02D1' || c == '\u0387' || c == '\u0640' || c == '\u0E46' ||
|
||||
c == '\u0EC6' || c == '\u3005' || (c >= '\u3031' && c <= '\u3035') || (c >= '\u309D' && c <= '\u309E') ||
|
||||
(c >= '\u30FC' && c <= '\u30FE');
|
||||
}
|
||||
|
||||
private static boolean isLetter(char c) {
|
||||
return isBaseChar(c) || isIdeographic(c);
|
||||
}
|
||||
|
||||
private static boolean isBaseChar(char c) {
|
||||
return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A') || (c >= '\u00C0' && c <= '\u00D6') ||
|
||||
(c >= '\u00D8' && c <= '\u00F6') || (c >= '\u00F8' && c <= '\u00FF') || (c >= '\u0100' && c <= '\u0131') ||
|
||||
(c >= '\u0134' && c <= '\u013E') || (c >= '\u0141' && c <= '\u0148') || (c >= '\u014A' && c <= '\u017E') ||
|
||||
(c >= '\u0180' && c <= '\u01C3') || (c >= '\u01CD' && c <= '\u01F0') || (c >= '\u01F4' && c <= '\u01F5') ||
|
||||
(c >= '\u01FA' && c <= '\u0217') || (c >= '\u0250' && c <= '\u02A8') || (c >= '\u02BB' && c <= '\u02C1') ||
|
||||
c == '\u0386' || (c >= '\u0388' && c <= '\u038A') || c == '\u038C' || (c >= '\u038E' && c <= '\u03A1') ||
|
||||
(c >= '\u03A3' && c <= '\u03CE') || (c >= '\u03D0' && c <= '\u03D6') || c == '\u03DA' || c == '\u03DC' || c == '\u03DE' ||
|
||||
c == '\u03E0' || (c >= '\u03E2' && c <= '\u03F3') || (c >= '\u0401' && c <= '\u040C') || (c >= '\u040E' && c <= '\u044F') ||
|
||||
(c >= '\u0451' && c <= '\u045C') || (c >= '\u045E' && c <= '\u0481') || (c >= '\u0490' && c <= '\u04C4') ||
|
||||
(c >= '\u04C7' && c <= '\u04C8') || (c >= '\u04CB' && c <= '\u04CC') || (c >= '\u04D0' && c <= '\u04EB') ||
|
||||
(c >= '\u04EE' && c <= '\u04F5') || (c >= '\u04F8' && c <= '\u04F9') || (c >= '\u0531' && c <= '\u0556') ||
|
||||
c == '\u0559' || (c >= '\u0561' && c <= '\u0586') || (c >= '\u05D0' && c <= '\u05EA') || (c >= '\u05F0' && c <= '\u05F2') ||
|
||||
(c >= '\u0621' && c <= '\u063A') || (c >= '\u0641' && c <= '\u064A') || (c >= '\u0671' && c <= '\u06B7') ||
|
||||
(c >= '\u06BA' && c <= '\u06BE') || (c >= '\u06C0' && c <= '\u06CE') || (c >= '\u06D0' && c <= '\u06D3') ||
|
||||
c == '\u06D5' || (c >= '\u06E5' && c <= '\u06E6') || (c >= '\u0905' && c <= '\u0939') || c == '\u093D' ||
|
||||
(c >= '\u0958' && c <= '\u0961') || (c >= '\u0985' && c <= '\u098C') || (c >= '\u098F' && c <= '\u0990') ||
|
||||
(c >= '\u0993' && c <= '\u09A8') || (c >= '\u09AA' && c <= '\u09B0') || c == '\u09B2' ||
|
||||
(c >= '\u09B6' && c <= '\u09B9') || (c >= '\u09DC' && c <= '\u09DD') || (c >= '\u09DF' && c <= '\u09E1') ||
|
||||
(c >= '\u09F0' && c <= '\u09F1') || (c >= '\u0A05' && c <= '\u0A0A') || (c >= '\u0A0F' && c <= '\u0A10') ||
|
||||
(c >= '\u0A13' && c <= '\u0A28') || (c >= '\u0A2A' && c <= '\u0A30') || (c >= '\u0A32' && c <= '\u0A33') ||
|
||||
(c >= '\u0A35' && c <= '\u0A36') || (c >= '\u0A38' && c <= '\u0A39') || (c >= '\u0A59' && c <= '\u0A5C') ||
|
||||
c == '\u0A5E' || (c >= '\u0A72' && c <= '\u0A74') || (c >= '\u0A85' && c <= '\u0A8B') || c == '\u0A8D' ||
|
||||
(c >= '\u0A8F' && c <= '\u0A91') || (c >= '\u0A93' && c <= '\u0AA8') || (c >= '\u0AAA' && c <= '\u0AB0') ||
|
||||
(c >= '\u0AB2' && c <= '\u0AB3') || (c >= '\u0AB5' && c <= '\u0AB9') || c == '\u0ABD' || c == '\u0AE0' ||
|
||||
(c >= '\u0B05' && c <= '\u0B0C') || (c >= '\u0B0F' && c <= '\u0B10') || (c >= '\u0B13' && c <= '\u0B28') ||
|
||||
(c >= '\u0B2A' && c <= '\u0B30') || (c >= '\u0B32' && c <= '\u0B33') || (c >= '\u0B36' && c <= '\u0B39') ||
|
||||
c == '\u0B3D' || (c >= '\u0B5C' && c <= '\u0B5D') || (c >= '\u0B5F' && c <= '\u0B61') ||
|
||||
(c >= '\u0B85' && c <= '\u0B8A') || (c >= '\u0B8E' && c <= '\u0B90') || (c >= '\u0B92' && c <= '\u0B95') ||
|
||||
(c >= '\u0B99' && c <= '\u0B9A') || c == '\u0B9C' || (c >= '\u0B9E' && c <= '\u0B9F') ||
|
||||
(c >= '\u0BA3' && c <= '\u0BA4') || (c >= '\u0BA8' && c <= '\u0BAA') || (c >= '\u0BAE' && c <= '\u0BB5') ||
|
||||
(c >= '\u0BB7' && c <= '\u0BB9') || (c >= '\u0C05' && c <= '\u0C0C') || (c >= '\u0C0E' && c <= '\u0C10') ||
|
||||
(c >= '\u0C12' && c <= '\u0C28') || (c >= '\u0C2A' && c <= '\u0C33') || (c >= '\u0C35' && c <= '\u0C39') ||
|
||||
(c >= '\u0C60' && c <= '\u0C61') || (c >= '\u0C85' && c <= '\u0C8C') || (c >= '\u0C8E' && c <= '\u0C90') ||
|
||||
(c >= '\u0C92' && c <= '\u0CA8') || (c >= '\u0CAA' && c <= '\u0CB3') || (c >= '\u0CB5' && c <= '\u0CB9') ||
|
||||
c == '\u0CDE' || (c >= '\u0CE0' && c <= '\u0CE1') || (c >= '\u0D05' && c <= '\u0D0C') ||
|
||||
(c >= '\u0D0E' && c <= '\u0D10') || (c >= '\u0D12' && c <= '\u0D28') || (c >= '\u0D2A' && c <= '\u0D39') ||
|
||||
(c >= '\u0D60' && c <= '\u0D61') || (c >= '\u0E01' && c <= '\u0E2E') || c == '\u0E30' ||
|
||||
(c >= '\u0E32' && c <= '\u0E33') || (c >= '\u0E40' && c <= '\u0E45') || (c >= '\u0E81' && c <= '\u0E82') ||
|
||||
c == '\u0E84' || (c >= '\u0E87' && c <= '\u0E88') || c == '\u0E8A' || c == '\u0E8D' || (c >= '\u0E94' && c <= '\u0E97') ||
|
||||
(c >= '\u0E99' && c <= '\u0E9F') || (c >= '\u0EA1' && c <= '\u0EA3') || c == '\u0EA5' || c == '\u0EA7' ||
|
||||
(c >= '\u0EAA' && c <= '\u0EAB') || (c >= '\u0EAD' && c <= '\u0EAE') || c == '\u0EB0' ||
|
||||
(c >= '\u0EB2' && c <= '\u0EB3') || c == '\u0EBD' || (c >= '\u0EC0' && c <= '\u0EC4') ||
|
||||
(c >= '\u0F40' && c <= '\u0F47') || (c >= '\u0F49' && c <= '\u0F69') || (c >= '\u10A0' && c <= '\u10C5') ||
|
||||
(c >= '\u10D0' && c <= '\u10F6') || c == '\u1100' || (c >= '\u1102' && c <= '\u1103') ||
|
||||
(c >= '\u1105' && c <= '\u1107') || c == '\u1109' || (c >= '\u110B' && c <= '\u110C') ||
|
||||
(c >= '\u110E' && c <= '\u1112') || c == '\u113C' || c == '\u113E' || c == '\u1140' || c == '\u114C' ||
|
||||
c == '\u114E' || c == '\u1150' || (c >= '\u1154' && c <= '\u1155') || c == '\u1159' ||
|
||||
(c >= '\u115F' && c <= '\u1161') || c == '\u1163' || c == '\u1165' || c == '\u1167' || c == '\u1169' ||
|
||||
(c >= '\u116D' && c <= '\u116E') || (c >= '\u1172' && c <= '\u1173') || c == '\u1175' ||
|
||||
c == '\u119E' || c == '\u11A8' || c == '\u11AB' || (c >= '\u11AE' && c <= '\u11AF') ||
|
||||
(c >= '\u11B7' && c <= '\u11B8') || c == '\u11BA' || (c >= '\u11BC' && c <= '\u11C2') ||
|
||||
c == '\u11EB' || c == '\u11F0' || c == '\u11F9' || (c >= '\u1E00' && c <= '\u1E9B') || (c >= '\u1EA0' && c <= '\u1EF9') ||
|
||||
(c >= '\u1F00' && c <= '\u1F15') || (c >= '\u1F18' && c <= '\u1F1D') || (c >= '\u1F20' && c <= '\u1F45') ||
|
||||
(c >= '\u1F48' && c <= '\u1F4D') || (c >= '\u1F50' && c <= '\u1F57') || c == '\u1F59' || c == '\u1F5B' || c == '\u1F5D' ||
|
||||
(c >= '\u1F5F' && c <= '\u1F7D') || (c >= '\u1F80' && c <= '\u1FB4') || (c >= '\u1FB6' && c <= '\u1FBC') ||
|
||||
c == '\u1FBE' || (c >= '\u1FC2' && c <= '\u1FC4') || (c >= '\u1FC6' && c <= '\u1FCC') ||
|
||||
(c >= '\u1FD0' && c <= '\u1FD3') || (c >= '\u1FD6' && c <= '\u1FDB') || (c >= '\u1FE0' && c <= '\u1FEC') ||
|
||||
(c >= '\u1FF2' && c <= '\u1FF4') || (c >= '\u1FF6' && c <= '\u1FFC') || c == '\u2126' ||
|
||||
(c >= '\u212A' && c <= '\u212B') || c == '\u212E' || (c >= '\u2180' && c <= '\u2182') ||
|
||||
(c >= '\u3041' && c <= '\u3094') || (c >= '\u30A1' && c <= '\u30FA') || (c >= '\u3105' && c <= '\u312C') ||
|
||||
(c >= '\uAC00' && c <= '\uD7A3');
|
||||
}
|
||||
|
||||
private static boolean isIdeographic(char c) {
|
||||
return (c >= '\u4E00' && c <= '\u9FA5') || c == '\u3007' || (c >= '\u3021' && c <= '\u3029');
|
||||
}
|
||||
|
||||
public static String determineEncoding(InputStream stream) throws IOException {
|
||||
stream.mark(20000);
|
||||
try {
|
||||
int b0 = stream.read();
|
||||
int b1 = stream.read();
|
||||
int b2 = stream.read();
|
||||
int b3 = stream.read();
|
||||
|
||||
if (b0 == 0xFE && b1 == 0xFF)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0xFF && b1 == 0xFE)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF )
|
||||
return "UTF-8";
|
||||
else if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0x3C && b1 == 0x3F && b2 == 0x78 && b3 == 0x6D) {
|
||||
// UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS, EUC, or any other 7-bit, 8-bit, or mixed-width encoding
|
||||
// which ensures that the characters of ASCII have their normal positions, width, and values; the actual encoding
|
||||
// declaration must be read to detect which of these applies, but since all of these encodings use the same bit patterns
|
||||
// for the relevant ASCII characters, the encoding declaration itself may be read reliably
|
||||
InputStreamReader rdr = new InputStreamReader(stream, "US-ASCII");
|
||||
String hdr = readFirstLine(rdr);
|
||||
return extractEncoding(hdr);
|
||||
} else
|
||||
return null;
|
||||
} finally {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractEncoding(String hdr) {
|
||||
int i = hdr.indexOf("encoding=");
|
||||
if (i == -1)
|
||||
return null;
|
||||
hdr = hdr.substring(i+9);
|
||||
char sep = hdr.charAt(0);
|
||||
hdr = hdr.substring(1);
|
||||
i = hdr.indexOf(sep);
|
||||
if (i == -1)
|
||||
return null;
|
||||
return hdr.substring(0, i);
|
||||
}
|
||||
|
||||
private static String readFirstLine(InputStreamReader rdr) throws IOException {
|
||||
char[] buf = new char[1];
|
||||
StringBuffer bldr = new StringBuffer();
|
||||
rdr.read(buf);
|
||||
while (buf[0] != '>') {
|
||||
bldr.append(buf[0]);
|
||||
rdr.read(buf);
|
||||
}
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
|
||||
public static boolean charSetImpliesAscii(String charset) {
|
||||
return charset.equals("ISO-8859-1") || charset.equals("US-ASCII");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the raw characters to XML escape characters.
|
||||
*
|
||||
* @param rawContent
|
||||
* @param charset Null when charset is not known, so we assume it's unicode
|
||||
* @param isNoLines
|
||||
* @return escape string
|
||||
*/
|
||||
public static String escapeXML(String rawContent, String charset, boolean isNoLines) {
|
||||
if (rawContent == null)
|
||||
return "";
|
||||
else {
|
||||
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("&#x"+Integer.toHexString(new Character(ch).hashCode()).toUpperCase()+";");
|
||||
else if (isNoLines) {
|
||||
if (ch == '\r')
|
||||
sb.append("
");
|
||||
else if (ch != '\n')
|
||||
sb.append(ch);
|
||||
}
|
||||
else
|
||||
sb.append(ch);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static Element getFirstChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getFirstChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Element getNextSibling(Element e) {
|
||||
Node n = e.getNextSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static void getNamedChildren(Element e, String name, List<Element> set) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null) {
|
||||
if (name.equals(c.getLocalName()) || name.equals(c.getNodeName()) )
|
||||
set.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(Element r) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
Node n = r.getFirstChild();
|
||||
boolean ws = false;
|
||||
while (n != null) {
|
||||
if (n.getNodeType() == Node.TEXT_NODE) {
|
||||
String t = n.getTextContent().trim();
|
||||
if (Utilities.noString(t))
|
||||
ws = true;
|
||||
else {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(t);
|
||||
}
|
||||
}
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(htmlToXmlEscapedPlainText((Element) n));
|
||||
if (r.getNodeName().equals("br") || r.getNodeName().equals("p"))
|
||||
s.append("\r\n");
|
||||
}
|
||||
n = n.getNextSibling();
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(String definition) throws Exception {
|
||||
return htmlToXmlEscapedPlainText(parseToDom("<div>"+definition+"</div>").getDocumentElement());
|
||||
}
|
||||
|
||||
public static String elementToString(Element el) {
|
||||
if (el == null)
|
||||
return "";
|
||||
Document document = el.getOwnerDocument();
|
||||
DOMImplementationLS domImplLS = (DOMImplementationLS) document
|
||||
.getImplementation();
|
||||
LSSerializer serializer = domImplLS.createLSSerializer();
|
||||
return serializer.writeToString(el);
|
||||
}
|
||||
|
||||
public static String getNamedChildValue(Element element, String name) {
|
||||
Element e = getNamedChild(element, name);
|
||||
return e == null ? null : e.getAttribute("value");
|
||||
}
|
||||
|
||||
public static void getNamedChildrenWithWildcard(Element focus, String name, List<Element> children) {
|
||||
Element c = getFirstChild(focus);
|
||||
while (c != null) {
|
||||
String n = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
|
||||
if (name.equals(n) || (name.endsWith("[x]") && n.startsWith(name.substring(0, name.length()-3))))
|
||||
children.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean hasNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c != null;
|
||||
}
|
||||
|
||||
public static Document parseToDom(String content) throws Exception {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(false);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.parse(new ByteArrayInputStream(content.getBytes()));
|
||||
}
|
||||
|
||||
public static Element getLastChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getLastChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getPrevSibling(Element e) {
|
||||
Node n = e.getPreviousSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
package org.hl7.fhir.instance.utilities.xml;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.hl7.fhir.instance.utilities.Utilities;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.ls.DOMImplementationLS;
|
||||
import org.w3c.dom.ls.LSSerializer;
|
||||
|
||||
public class XMLUtil {
|
||||
|
||||
public static final String SPACE_CHAR = "\u00A0";
|
||||
|
||||
public static boolean isNMToken(String name) {
|
||||
if (name == null)
|
||||
return false;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
if (!isNMTokenChar(name.charAt(i)))
|
||||
return false;
|
||||
return name.length() > 0;
|
||||
}
|
||||
|
||||
public static boolean isNMTokenChar(char c) {
|
||||
return isLetter(c) || isDigit(c) || c == '.' || c == '-' || c == '_' || c == ':' || isCombiningChar(c) || isExtender(c);
|
||||
}
|
||||
|
||||
private static boolean isDigit(char c) {
|
||||
return (c >= '\u0030' && c <= '\u0039') || (c >= '\u0660' && c <= '\u0669') || (c >= '\u06F0' && c <= '\u06F9') ||
|
||||
(c >= '\u0966' && c <= '\u096F') || (c >= '\u09E6' && c <= '\u09EF') || (c >= '\u0A66' && c <= '\u0A6F') ||
|
||||
(c >= '\u0AE6' && c <= '\u0AEF') || (c >= '\u0B66' && c <= '\u0B6F') || (c >= '\u0BE7' && c <= '\u0BEF') ||
|
||||
(c >= '\u0C66' && c <= '\u0C6F') || (c >= '\u0CE6' && c <= '\u0CEF') || (c >= '\u0D66' && c <= '\u0D6F') ||
|
||||
(c >= '\u0E50' && c <= '\u0E59') || (c >= '\u0ED0' && c <= '\u0ED9') || (c >= '\u0F20' && c <= '\u0F29');
|
||||
}
|
||||
|
||||
private static boolean isCombiningChar(char c) {
|
||||
return (c >= '\u0300' && c <= '\u0345') || (c >= '\u0360' && c <= '\u0361') || (c >= '\u0483' && c <= '\u0486') ||
|
||||
(c >= '\u0591' && c <= '\u05A1') || (c >= '\u05A3' && c <= '\u05B9') || (c >= '\u05BB' && c <= '\u05BD') ||
|
||||
c == '\u05BF' || (c >= '\u05C1' && c <= '\u05C2') || c == '\u05C4' || (c >= '\u064B' && c <= '\u0652') ||
|
||||
c == '\u0670' || (c >= '\u06D6' && c <= '\u06DC') || (c >= '\u06DD' && c <= '\u06DF') || (c >= '\u06E0' && c <= '\u06E4') ||
|
||||
(c >= '\u06E7' && c <= '\u06E8') || (c >= '\u06EA' && c <= '\u06ED') || (c >= '\u0901' && c <= '\u0903') || c == '\u093C' ||
|
||||
(c >= '\u093E' && c <= '\u094C') || c == '\u094D' || (c >= '\u0951' && c <= '\u0954') || (c >= '\u0962' && c <= '\u0963') ||
|
||||
(c >= '\u0981' && c <= '\u0983') || c == '\u09BC' || c == '\u09BE' || c == '\u09BF' || (c >= '\u09C0' && c <= '\u09C4') ||
|
||||
(c >= '\u09C7' && c <= '\u09C8') || (c >= '\u09CB' && c <= '\u09CD') || c == '\u09D7' || (c >= '\u09E2' && c <= '\u09E3') ||
|
||||
c == '\u0A02' || c == '\u0A3C' || c == '\u0A3E' || c == '\u0A3F' || (c >= '\u0A40' && c <= '\u0A42') ||
|
||||
(c >= '\u0A47' && c <= '\u0A48') || (c >= '\u0A4B' && c <= '\u0A4D') || (c >= '\u0A70' && c <= '\u0A71') ||
|
||||
(c >= '\u0A81' && c <= '\u0A83') || c == '\u0ABC' || (c >= '\u0ABE' && c <= '\u0AC5') || (c >= '\u0AC7' && c <= '\u0AC9') ||
|
||||
(c >= '\u0ACB' && c <= '\u0ACD') || (c >= '\u0B01' && c <= '\u0B03') || c == '\u0B3C' || (c >= '\u0B3E' && c <= '\u0B43') ||
|
||||
(c >= '\u0B47' && c <= '\u0B48') || (c >= '\u0B4B' && c <= '\u0B4D') || (c >= '\u0B56' && c <= '\u0B57') ||
|
||||
(c >= '\u0B82' && c <= '\u0B83') || (c >= '\u0BBE' && c <= '\u0BC2') || (c >= '\u0BC6' && c <= '\u0BC8') ||
|
||||
(c >= '\u0BCA' && c <= '\u0BCD') || c == '\u0BD7' || (c >= '\u0C01' && c <= '\u0C03') || (c >= '\u0C3E' && c <= '\u0C44') ||
|
||||
(c >= '\u0C46' && c <= '\u0C48') || (c >= '\u0C4A' && c <= '\u0C4D') || (c >= '\u0C55' && c <= '\u0C56') ||
|
||||
(c >= '\u0C82' && c <= '\u0C83') || (c >= '\u0CBE' && c <= '\u0CC4') || (c >= '\u0CC6' && c <= '\u0CC8') ||
|
||||
(c >= '\u0CCA' && c <= '\u0CCD') || (c >= '\u0CD5' && c <= '\u0CD6') || (c >= '\u0D02' && c <= '\u0D03') ||
|
||||
(c >= '\u0D3E' && c <= '\u0D43') || (c >= '\u0D46' && c <= '\u0D48') || (c >= '\u0D4A' && c <= '\u0D4D') || c == '\u0D57' ||
|
||||
c == '\u0E31' || (c >= '\u0E34' && c <= '\u0E3A') || (c >= '\u0E47' && c <= '\u0E4E') || c == '\u0EB1' ||
|
||||
(c >= '\u0EB4' && c <= '\u0EB9') || (c >= '\u0EBB' && c <= '\u0EBC') || (c >= '\u0EC8' && c <= '\u0ECD') ||
|
||||
(c >= '\u0F18' && c <= '\u0F19') || c == '\u0F35' || c == '\u0F37' || c == '\u0F39' || c == '\u0F3E' || c == '\u0F3F' ||
|
||||
(c >= '\u0F71' && c <= '\u0F84') || (c >= '\u0F86' && c <= '\u0F8B') || (c >= '\u0F90' && c <= '\u0F95') || c == '\u0F97' ||
|
||||
(c >= '\u0F99' && c <= '\u0FAD') || (c >= '\u0FB1' && c <= '\u0FB7') || c == '\u0FB9' || (c >= '\u20D0' && c <= '\u20DC') ||
|
||||
c == '\u20E1' || (c >= '\u302A' && c <= '\u302F') || c == '\u3099' || c == '\u309A';
|
||||
}
|
||||
|
||||
private static boolean isExtender(char c) {
|
||||
return c == '\u00B7' || c == '\u02D0' || c == '\u02D1' || c == '\u0387' || c == '\u0640' || c == '\u0E46' ||
|
||||
c == '\u0EC6' || c == '\u3005' || (c >= '\u3031' && c <= '\u3035') || (c >= '\u309D' && c <= '\u309E') ||
|
||||
(c >= '\u30FC' && c <= '\u30FE');
|
||||
}
|
||||
|
||||
private static boolean isLetter(char c) {
|
||||
return isBaseChar(c) || isIdeographic(c);
|
||||
}
|
||||
|
||||
private static boolean isBaseChar(char c) {
|
||||
return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A') || (c >= '\u00C0' && c <= '\u00D6') ||
|
||||
(c >= '\u00D8' && c <= '\u00F6') || (c >= '\u00F8' && c <= '\u00FF') || (c >= '\u0100' && c <= '\u0131') ||
|
||||
(c >= '\u0134' && c <= '\u013E') || (c >= '\u0141' && c <= '\u0148') || (c >= '\u014A' && c <= '\u017E') ||
|
||||
(c >= '\u0180' && c <= '\u01C3') || (c >= '\u01CD' && c <= '\u01F0') || (c >= '\u01F4' && c <= '\u01F5') ||
|
||||
(c >= '\u01FA' && c <= '\u0217') || (c >= '\u0250' && c <= '\u02A8') || (c >= '\u02BB' && c <= '\u02C1') ||
|
||||
c == '\u0386' || (c >= '\u0388' && c <= '\u038A') || c == '\u038C' || (c >= '\u038E' && c <= '\u03A1') ||
|
||||
(c >= '\u03A3' && c <= '\u03CE') || (c >= '\u03D0' && c <= '\u03D6') || c == '\u03DA' || c == '\u03DC' || c == '\u03DE' ||
|
||||
c == '\u03E0' || (c >= '\u03E2' && c <= '\u03F3') || (c >= '\u0401' && c <= '\u040C') || (c >= '\u040E' && c <= '\u044F') ||
|
||||
(c >= '\u0451' && c <= '\u045C') || (c >= '\u045E' && c <= '\u0481') || (c >= '\u0490' && c <= '\u04C4') ||
|
||||
(c >= '\u04C7' && c <= '\u04C8') || (c >= '\u04CB' && c <= '\u04CC') || (c >= '\u04D0' && c <= '\u04EB') ||
|
||||
(c >= '\u04EE' && c <= '\u04F5') || (c >= '\u04F8' && c <= '\u04F9') || (c >= '\u0531' && c <= '\u0556') ||
|
||||
c == '\u0559' || (c >= '\u0561' && c <= '\u0586') || (c >= '\u05D0' && c <= '\u05EA') || (c >= '\u05F0' && c <= '\u05F2') ||
|
||||
(c >= '\u0621' && c <= '\u063A') || (c >= '\u0641' && c <= '\u064A') || (c >= '\u0671' && c <= '\u06B7') ||
|
||||
(c >= '\u06BA' && c <= '\u06BE') || (c >= '\u06C0' && c <= '\u06CE') || (c >= '\u06D0' && c <= '\u06D3') ||
|
||||
c == '\u06D5' || (c >= '\u06E5' && c <= '\u06E6') || (c >= '\u0905' && c <= '\u0939') || c == '\u093D' ||
|
||||
(c >= '\u0958' && c <= '\u0961') || (c >= '\u0985' && c <= '\u098C') || (c >= '\u098F' && c <= '\u0990') ||
|
||||
(c >= '\u0993' && c <= '\u09A8') || (c >= '\u09AA' && c <= '\u09B0') || c == '\u09B2' ||
|
||||
(c >= '\u09B6' && c <= '\u09B9') || (c >= '\u09DC' && c <= '\u09DD') || (c >= '\u09DF' && c <= '\u09E1') ||
|
||||
(c >= '\u09F0' && c <= '\u09F1') || (c >= '\u0A05' && c <= '\u0A0A') || (c >= '\u0A0F' && c <= '\u0A10') ||
|
||||
(c >= '\u0A13' && c <= '\u0A28') || (c >= '\u0A2A' && c <= '\u0A30') || (c >= '\u0A32' && c <= '\u0A33') ||
|
||||
(c >= '\u0A35' && c <= '\u0A36') || (c >= '\u0A38' && c <= '\u0A39') || (c >= '\u0A59' && c <= '\u0A5C') ||
|
||||
c == '\u0A5E' || (c >= '\u0A72' && c <= '\u0A74') || (c >= '\u0A85' && c <= '\u0A8B') || c == '\u0A8D' ||
|
||||
(c >= '\u0A8F' && c <= '\u0A91') || (c >= '\u0A93' && c <= '\u0AA8') || (c >= '\u0AAA' && c <= '\u0AB0') ||
|
||||
(c >= '\u0AB2' && c <= '\u0AB3') || (c >= '\u0AB5' && c <= '\u0AB9') || c == '\u0ABD' || c == '\u0AE0' ||
|
||||
(c >= '\u0B05' && c <= '\u0B0C') || (c >= '\u0B0F' && c <= '\u0B10') || (c >= '\u0B13' && c <= '\u0B28') ||
|
||||
(c >= '\u0B2A' && c <= '\u0B30') || (c >= '\u0B32' && c <= '\u0B33') || (c >= '\u0B36' && c <= '\u0B39') ||
|
||||
c == '\u0B3D' || (c >= '\u0B5C' && c <= '\u0B5D') || (c >= '\u0B5F' && c <= '\u0B61') ||
|
||||
(c >= '\u0B85' && c <= '\u0B8A') || (c >= '\u0B8E' && c <= '\u0B90') || (c >= '\u0B92' && c <= '\u0B95') ||
|
||||
(c >= '\u0B99' && c <= '\u0B9A') || c == '\u0B9C' || (c >= '\u0B9E' && c <= '\u0B9F') ||
|
||||
(c >= '\u0BA3' && c <= '\u0BA4') || (c >= '\u0BA8' && c <= '\u0BAA') || (c >= '\u0BAE' && c <= '\u0BB5') ||
|
||||
(c >= '\u0BB7' && c <= '\u0BB9') || (c >= '\u0C05' && c <= '\u0C0C') || (c >= '\u0C0E' && c <= '\u0C10') ||
|
||||
(c >= '\u0C12' && c <= '\u0C28') || (c >= '\u0C2A' && c <= '\u0C33') || (c >= '\u0C35' && c <= '\u0C39') ||
|
||||
(c >= '\u0C60' && c <= '\u0C61') || (c >= '\u0C85' && c <= '\u0C8C') || (c >= '\u0C8E' && c <= '\u0C90') ||
|
||||
(c >= '\u0C92' && c <= '\u0CA8') || (c >= '\u0CAA' && c <= '\u0CB3') || (c >= '\u0CB5' && c <= '\u0CB9') ||
|
||||
c == '\u0CDE' || (c >= '\u0CE0' && c <= '\u0CE1') || (c >= '\u0D05' && c <= '\u0D0C') ||
|
||||
(c >= '\u0D0E' && c <= '\u0D10') || (c >= '\u0D12' && c <= '\u0D28') || (c >= '\u0D2A' && c <= '\u0D39') ||
|
||||
(c >= '\u0D60' && c <= '\u0D61') || (c >= '\u0E01' && c <= '\u0E2E') || c == '\u0E30' ||
|
||||
(c >= '\u0E32' && c <= '\u0E33') || (c >= '\u0E40' && c <= '\u0E45') || (c >= '\u0E81' && c <= '\u0E82') ||
|
||||
c == '\u0E84' || (c >= '\u0E87' && c <= '\u0E88') || c == '\u0E8A' || c == '\u0E8D' || (c >= '\u0E94' && c <= '\u0E97') ||
|
||||
(c >= '\u0E99' && c <= '\u0E9F') || (c >= '\u0EA1' && c <= '\u0EA3') || c == '\u0EA5' || c == '\u0EA7' ||
|
||||
(c >= '\u0EAA' && c <= '\u0EAB') || (c >= '\u0EAD' && c <= '\u0EAE') || c == '\u0EB0' ||
|
||||
(c >= '\u0EB2' && c <= '\u0EB3') || c == '\u0EBD' || (c >= '\u0EC0' && c <= '\u0EC4') ||
|
||||
(c >= '\u0F40' && c <= '\u0F47') || (c >= '\u0F49' && c <= '\u0F69') || (c >= '\u10A0' && c <= '\u10C5') ||
|
||||
(c >= '\u10D0' && c <= '\u10F6') || c == '\u1100' || (c >= '\u1102' && c <= '\u1103') ||
|
||||
(c >= '\u1105' && c <= '\u1107') || c == '\u1109' || (c >= '\u110B' && c <= '\u110C') ||
|
||||
(c >= '\u110E' && c <= '\u1112') || c == '\u113C' || c == '\u113E' || c == '\u1140' || c == '\u114C' ||
|
||||
c == '\u114E' || c == '\u1150' || (c >= '\u1154' && c <= '\u1155') || c == '\u1159' ||
|
||||
(c >= '\u115F' && c <= '\u1161') || c == '\u1163' || c == '\u1165' || c == '\u1167' || c == '\u1169' ||
|
||||
(c >= '\u116D' && c <= '\u116E') || (c >= '\u1172' && c <= '\u1173') || c == '\u1175' ||
|
||||
c == '\u119E' || c == '\u11A8' || c == '\u11AB' || (c >= '\u11AE' && c <= '\u11AF') ||
|
||||
(c >= '\u11B7' && c <= '\u11B8') || c == '\u11BA' || (c >= '\u11BC' && c <= '\u11C2') ||
|
||||
c == '\u11EB' || c == '\u11F0' || c == '\u11F9' || (c >= '\u1E00' && c <= '\u1E9B') || (c >= '\u1EA0' && c <= '\u1EF9') ||
|
||||
(c >= '\u1F00' && c <= '\u1F15') || (c >= '\u1F18' && c <= '\u1F1D') || (c >= '\u1F20' && c <= '\u1F45') ||
|
||||
(c >= '\u1F48' && c <= '\u1F4D') || (c >= '\u1F50' && c <= '\u1F57') || c == '\u1F59' || c == '\u1F5B' || c == '\u1F5D' ||
|
||||
(c >= '\u1F5F' && c <= '\u1F7D') || (c >= '\u1F80' && c <= '\u1FB4') || (c >= '\u1FB6' && c <= '\u1FBC') ||
|
||||
c == '\u1FBE' || (c >= '\u1FC2' && c <= '\u1FC4') || (c >= '\u1FC6' && c <= '\u1FCC') ||
|
||||
(c >= '\u1FD0' && c <= '\u1FD3') || (c >= '\u1FD6' && c <= '\u1FDB') || (c >= '\u1FE0' && c <= '\u1FEC') ||
|
||||
(c >= '\u1FF2' && c <= '\u1FF4') || (c >= '\u1FF6' && c <= '\u1FFC') || c == '\u2126' ||
|
||||
(c >= '\u212A' && c <= '\u212B') || c == '\u212E' || (c >= '\u2180' && c <= '\u2182') ||
|
||||
(c >= '\u3041' && c <= '\u3094') || (c >= '\u30A1' && c <= '\u30FA') || (c >= '\u3105' && c <= '\u312C') ||
|
||||
(c >= '\uAC00' && c <= '\uD7A3');
|
||||
}
|
||||
|
||||
private static boolean isIdeographic(char c) {
|
||||
return (c >= '\u4E00' && c <= '\u9FA5') || c == '\u3007' || (c >= '\u3021' && c <= '\u3029');
|
||||
}
|
||||
|
||||
public static String determineEncoding(InputStream stream) throws IOException {
|
||||
stream.mark(20000);
|
||||
try {
|
||||
int b0 = stream.read();
|
||||
int b1 = stream.read();
|
||||
int b2 = stream.read();
|
||||
int b3 = stream.read();
|
||||
|
||||
if (b0 == 0xFE && b1 == 0xFF)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0xFF && b1 == 0xFE)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF )
|
||||
return "UTF-8";
|
||||
else if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0x3C && b1 == 0x3F && b2 == 0x78 && b3 == 0x6D) {
|
||||
// UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS, EUC, or any other 7-bit, 8-bit, or mixed-width encoding
|
||||
// which ensures that the characters of ASCII have their normal positions, width, and values; the actual encoding
|
||||
// declaration must be read to detect which of these applies, but since all of these encodings use the same bit patterns
|
||||
// for the relevant ASCII characters, the encoding declaration itself may be read reliably
|
||||
InputStreamReader rdr = new InputStreamReader(stream, "US-ASCII");
|
||||
String hdr = readFirstLine(rdr);
|
||||
return extractEncoding(hdr);
|
||||
} else
|
||||
return null;
|
||||
} finally {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractEncoding(String hdr) {
|
||||
int i = hdr.indexOf("encoding=");
|
||||
if (i == -1)
|
||||
return null;
|
||||
hdr = hdr.substring(i+9);
|
||||
char sep = hdr.charAt(0);
|
||||
hdr = hdr.substring(1);
|
||||
i = hdr.indexOf(sep);
|
||||
if (i == -1)
|
||||
return null;
|
||||
return hdr.substring(0, i);
|
||||
}
|
||||
|
||||
private static String readFirstLine(InputStreamReader rdr) throws IOException {
|
||||
char[] buf = new char[1];
|
||||
StringBuffer bldr = new StringBuffer();
|
||||
rdr.read(buf);
|
||||
while (buf[0] != '>') {
|
||||
bldr.append(buf[0]);
|
||||
rdr.read(buf);
|
||||
}
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
|
||||
public static boolean charSetImpliesAscii(String charset) {
|
||||
return charset.equals("ISO-8859-1") || charset.equals("US-ASCII");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the raw characters to XML escapeUrlParam characters.
|
||||
*
|
||||
* @param rawContent
|
||||
* @param charset Null when charset is not known, so we assume it's unicode
|
||||
* @param isNoLines
|
||||
* @return escapeUrlParam string
|
||||
*/
|
||||
public static String escapeXML(String rawContent, String charset, boolean isNoLines) {
|
||||
if (rawContent == null)
|
||||
return "";
|
||||
else {
|
||||
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("&#x"+Integer.toHexString(new Character(ch).hashCode()).toUpperCase()+";");
|
||||
else if (isNoLines) {
|
||||
if (ch == '\r')
|
||||
sb.append("
");
|
||||
else if (ch != '\n')
|
||||
sb.append(ch);
|
||||
}
|
||||
else
|
||||
sb.append(ch);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static Element getFirstChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getFirstChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Element getNextSibling(Element e) {
|
||||
Node n = e.getNextSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static void getNamedChildren(Element e, String name, List<Element> set) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null) {
|
||||
if (name.equals(c.getLocalName()) || name.equals(c.getNodeName()) )
|
||||
set.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(Element r) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
Node n = r.getFirstChild();
|
||||
boolean ws = false;
|
||||
while (n != null) {
|
||||
if (n.getNodeType() == Node.TEXT_NODE) {
|
||||
String t = n.getTextContent().trim();
|
||||
if (Utilities.noString(t))
|
||||
ws = true;
|
||||
else {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(t);
|
||||
}
|
||||
}
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(htmlToXmlEscapedPlainText((Element) n));
|
||||
if (r.getNodeName().equals("br") || r.getNodeName().equals("p"))
|
||||
s.append("\r\n");
|
||||
}
|
||||
n = n.getNextSibling();
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(String definition) throws Exception {
|
||||
return htmlToXmlEscapedPlainText(parseToDom("<div>"+definition+"</div>").getDocumentElement());
|
||||
}
|
||||
|
||||
public static String elementToString(Element el) {
|
||||
if (el == null)
|
||||
return "";
|
||||
Document document = el.getOwnerDocument();
|
||||
DOMImplementationLS domImplLS = (DOMImplementationLS) document
|
||||
.getImplementation();
|
||||
LSSerializer serializer = domImplLS.createLSSerializer();
|
||||
return serializer.writeToString(el);
|
||||
}
|
||||
|
||||
public static String getNamedChildValue(Element element, String name) {
|
||||
Element e = getNamedChild(element, name);
|
||||
return e == null ? null : e.getAttribute("value");
|
||||
}
|
||||
|
||||
public static void getNamedChildrenWithWildcard(Element focus, String name, List<Element> children) {
|
||||
Element c = getFirstChild(focus);
|
||||
while (c != null) {
|
||||
String n = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
|
||||
if (name.equals(n) || (name.endsWith("[x]") && n.startsWith(name.substring(0, name.length()-3))))
|
||||
children.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean hasNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c != null;
|
||||
}
|
||||
|
||||
public static Document parseToDom(String content) throws Exception {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(false);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.parse(new ByteArrayInputStream(content.getBytes()));
|
||||
}
|
||||
|
||||
public static Element getLastChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getLastChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getPrevSibling(Element e) {
|
||||
Node n = e.getPreviousSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,493 +1,493 @@
|
|||
package org.hl7.fhir.r4.elementmodel;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.hl7.fhir.r4.context.IWorkerContext;
|
||||
import org.hl7.fhir.r4.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
|
||||
/**
|
||||
* This class provides special support for parsing v2 by the v2 logical model
|
||||
* For the logical model, see the FHIRPath spec
|
||||
*
|
||||
* @author Grahame Grieve
|
||||
*
|
||||
*/
|
||||
public class VerticalBarParser extends ParserBase {
|
||||
|
||||
/**
|
||||
* Delimiters for a message. Note that the application rarely needs to concern
|
||||
* itself with this information; it mainly exists for internal use. However if
|
||||
* a message is being written to a spec that calls for non-standard delimiters,
|
||||
* the application can set them here.
|
||||
*
|
||||
* @author Grahame
|
||||
*
|
||||
*/
|
||||
public class Delimiters {
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a field
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_FIELD = '|';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a component
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_COMPONENT = '^';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a subcomponent
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_SUBCOMPONENT = '&';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a repeat
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_REPETITION = '~';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for an escape
|
||||
*/
|
||||
public final static char DEFAULT_CHARACTER_ESCAPE = '\\';
|
||||
|
||||
|
||||
/**
|
||||
* defined escape character for this message
|
||||
*/
|
||||
private char escapeCharacter;
|
||||
|
||||
/**
|
||||
* defined repetition character for this message
|
||||
*/
|
||||
private char repetitionDelimiter;
|
||||
|
||||
/**
|
||||
* defined field character for this message
|
||||
*/
|
||||
private char fieldDelimiter;
|
||||
|
||||
/**
|
||||
* defined subComponent character for this message
|
||||
*/
|
||||
private char subComponentDelimiter;
|
||||
|
||||
/**
|
||||
* defined component character for this message
|
||||
*/
|
||||
private char componentDelimiter;
|
||||
|
||||
/**
|
||||
* create
|
||||
*
|
||||
*/
|
||||
public Delimiters() {
|
||||
super();
|
||||
reset();
|
||||
}
|
||||
|
||||
public boolean matches(Delimiters other) {
|
||||
return escapeCharacter == other.escapeCharacter &&
|
||||
repetitionDelimiter == other.repetitionDelimiter &&
|
||||
fieldDelimiter == other.fieldDelimiter &&
|
||||
subComponentDelimiter == other.subComponentDelimiter &&
|
||||
componentDelimiter == other.componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get defined component character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getComponentDelimiter() {
|
||||
return componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set defined component character for this message
|
||||
* @param componentDelimiter
|
||||
*/
|
||||
public void setComponentDelimiter(char componentDelimiter) {
|
||||
this.componentDelimiter = componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get defined escape character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getEscapeCharacter() {
|
||||
return escapeCharacter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set defined escape character for this message
|
||||
* @param escapeCharacter
|
||||
*/
|
||||
public void setEscapeCharacter(char escapeCharacter) {
|
||||
this.escapeCharacter = escapeCharacter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get defined field character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getFieldDelimiter() {
|
||||
return fieldDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set defined field character for this message
|
||||
* @param fieldDelimiter
|
||||
*/
|
||||
public void setFieldDelimiter(char fieldDelimiter) {
|
||||
this.fieldDelimiter = fieldDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get repeat field character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getRepetitionDelimiter() {
|
||||
return repetitionDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set repeat field character for this message
|
||||
* @param repetitionDelimiter
|
||||
*/
|
||||
public void setRepetitionDelimiter(char repetitionDelimiter) {
|
||||
this.repetitionDelimiter = repetitionDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get sub-component field character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getSubComponentDelimiter() {
|
||||
return subComponentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set sub-component field character for this message
|
||||
* @param subComponentDelimiter
|
||||
*/
|
||||
public void setSubComponentDelimiter(char subComponentDelimiter) {
|
||||
this.subComponentDelimiter = subComponentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset to default HL7 values
|
||||
*
|
||||
*/
|
||||
public void reset () {
|
||||
fieldDelimiter = DEFAULT_DELIMITER_FIELD;
|
||||
componentDelimiter = DEFAULT_DELIMITER_COMPONENT;
|
||||
subComponentDelimiter = DEFAULT_DELIMITER_SUBCOMPONENT;
|
||||
repetitionDelimiter = DEFAULT_DELIMITER_REPETITION;
|
||||
escapeCharacter = DEFAULT_CHARACTER_ESCAPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* check that the delimiters are valid
|
||||
*
|
||||
* @throws FHIRException
|
||||
*/
|
||||
public void check() throws FHIRException {
|
||||
rule(componentDelimiter != fieldDelimiter, "Delimiter Error: \""+componentDelimiter+"\" is used for both CPComponent and CPField");
|
||||
rule(subComponentDelimiter != fieldDelimiter, "Delimiter Error: \""+subComponentDelimiter+"\" is used for both CPSubComponent and CPField");
|
||||
rule(subComponentDelimiter != componentDelimiter, "Delimiter Error: \""+subComponentDelimiter+"\" is used for both CPSubComponent and CPComponent");
|
||||
rule(repetitionDelimiter != fieldDelimiter, "Delimiter Error: \""+repetitionDelimiter+"\" is used for both Repetition and CPField");
|
||||
rule(repetitionDelimiter != componentDelimiter, "Delimiter Error: \""+repetitionDelimiter+"\" is used for both Repetition and CPComponent");
|
||||
rule(repetitionDelimiter != subComponentDelimiter, "Delimiter Error: \""+repetitionDelimiter+"\" is used for both Repetition and CPSubComponent");
|
||||
rule(escapeCharacter != fieldDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and CPField");
|
||||
rule(escapeCharacter != componentDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and CPComponent");
|
||||
rule(escapeCharacter != subComponentDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and CPSubComponent");
|
||||
rule(escapeCharacter != repetitionDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and Repetition");
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see whether ch is a delimiter character (vertical bar parser support)
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public boolean isDelimiter(char ch) {
|
||||
return ch == escapeCharacter || ch == repetitionDelimiter || ch == fieldDelimiter || ch == subComponentDelimiter || ch == componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see whether ch is a cell delimiter char (vertical bar parser support)
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public boolean isCellDelimiter(char ch) {
|
||||
return ch == repetitionDelimiter || ch == fieldDelimiter || ch == subComponentDelimiter || ch == componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the escape for a character
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public String getEscape(char ch) {
|
||||
if (ch == escapeCharacter)
|
||||
return escapeCharacter + "E" + escapeCharacter;
|
||||
else if (ch == fieldDelimiter)
|
||||
return escapeCharacter + "F" + escapeCharacter;
|
||||
else if (ch == componentDelimiter)
|
||||
return escapeCharacter + "S" + escapeCharacter;
|
||||
else if (ch == subComponentDelimiter)
|
||||
return escapeCharacter + "T" + escapeCharacter;
|
||||
else if (ch == repetitionDelimiter)
|
||||
return escapeCharacter + "R" + escapeCharacter;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* build the MSH-2 content
|
||||
* @return
|
||||
*/
|
||||
public String forMSH2() {
|
||||
return "" + componentDelimiter + repetitionDelimiter + escapeCharacter + subComponentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see whether ch represents a delimiter escape
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public boolean isDelimiterEscape(char ch) {
|
||||
return ch == 'F' || ch == 'S' || ch == 'E' || ch == 'T' || ch == 'R';
|
||||
}
|
||||
|
||||
/**
|
||||
* get escape for ch in an escape
|
||||
* @param ch
|
||||
* @return
|
||||
* @throws DefinitionException
|
||||
* @throws FHIRException
|
||||
*/
|
||||
public char getDelimiterEscapeChar(char ch) throws DefinitionException {
|
||||
if (ch == 'E')
|
||||
return escapeCharacter;
|
||||
else if (ch == 'F')
|
||||
return fieldDelimiter;
|
||||
else if (ch == 'S')
|
||||
return componentDelimiter;
|
||||
else if (ch == 'T')
|
||||
return subComponentDelimiter;
|
||||
else if (ch == 'R')
|
||||
return repetitionDelimiter;
|
||||
else
|
||||
throw new DefinitionException("internal error in getDelimiterEscapeChar");
|
||||
}
|
||||
}
|
||||
|
||||
public class VerticalBarParserReader {
|
||||
|
||||
|
||||
private BufferedInputStream stream;
|
||||
private String charsetName;
|
||||
private InputStreamReader reader = null;
|
||||
private boolean finished;
|
||||
private char peeked;
|
||||
private char lastValue;
|
||||
private int offset;
|
||||
private int lineNumber;
|
||||
|
||||
public VerticalBarParserReader(BufferedInputStream stream, String charsetName) throws FHIRException {
|
||||
super();
|
||||
setStream(stream);
|
||||
setCharsetName(charsetName);
|
||||
open();
|
||||
}
|
||||
|
||||
public String getCharsetName() {
|
||||
return charsetName;
|
||||
}
|
||||
|
||||
public void setCharsetName(String charsetName) {
|
||||
this.charsetName = charsetName;
|
||||
}
|
||||
|
||||
public BufferedInputStream getStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public void setStream(BufferedInputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
private void open() throws FHIRException {
|
||||
try {
|
||||
stream.mark(2048);
|
||||
reader = new InputStreamReader(stream, charsetName);
|
||||
offset = 0;
|
||||
lineNumber = 0;
|
||||
lastValue = ' ';
|
||||
next();
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void next() throws IOException, FHIRException {
|
||||
finished = !reader.ready();
|
||||
if (!finished) {
|
||||
char[] temp = new char[1];
|
||||
rule(reader.read(temp, 0, 1) == 1, "unable to read 1 character from the stream");
|
||||
peeked = temp[0];
|
||||
}
|
||||
}
|
||||
|
||||
public String read(int charCount) throws FHIRException {
|
||||
String value = "";
|
||||
for (int i = 0; i < charCount; i++)
|
||||
value = value + read();
|
||||
return value;
|
||||
}
|
||||
|
||||
public void skipEOL () throws FHIRException {
|
||||
while (!finished && (peek() == '\r' || peek() == '\n'))
|
||||
read();
|
||||
}
|
||||
|
||||
public char read () throws FHIRException {
|
||||
rule(!finished, "No more content to read");
|
||||
char value = peek();
|
||||
offset++;
|
||||
if (value == '\r' || value == '\n') {
|
||||
if (lastValue != '\r' || value != '\n')
|
||||
lineNumber++;
|
||||
}
|
||||
lastValue = value;
|
||||
try {
|
||||
next();
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean isFinished () {
|
||||
return finished;
|
||||
}
|
||||
|
||||
public char peek() throws FHIRException {
|
||||
rule(!finished, "Cannot peek");
|
||||
return peeked;
|
||||
}
|
||||
|
||||
public void mark() {
|
||||
stream.mark(2048);
|
||||
}
|
||||
|
||||
public void reset() throws FHIRException {
|
||||
try {
|
||||
stream.reset();
|
||||
} catch (IOException e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
open();
|
||||
}
|
||||
|
||||
public boolean IsEOL() throws FHIRException {
|
||||
return peek() == '\r' || peek() == '\n';
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public VerticalBarParser(IWorkerContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
private String charset = "ASCII";
|
||||
private Delimiters delimiters = new Delimiters();
|
||||
|
||||
@Override
|
||||
public Element parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/v2/StructureDefinition/Message");
|
||||
Element message = new Element("Message", new Property(context, sd.getSnapshot().getElementFirstRep(), sd));
|
||||
VerticalBarParserReader reader = new VerticalBarParserReader(new BufferedInputStream(stream), charset);
|
||||
|
||||
preDecode(reader);
|
||||
while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size()))
|
||||
readSegment(message, reader);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private void preDecode(VerticalBarParserReader reader) throws FHIRException {
|
||||
reader.skipEOL();
|
||||
String temp = reader.read(3);
|
||||
rule(temp.equals("MSH") || temp.equals("FHS"), "Found '" + temp + "' looking for 'MSH' or 'FHS'");
|
||||
readDelimiters(reader);
|
||||
// readVersion(message); - probably don't need to do that?
|
||||
// readCharacterSet();
|
||||
reader.reset(); // ready to read message now
|
||||
}
|
||||
|
||||
private void rule(boolean test, String msg) throws FHIRException {
|
||||
if (!test)
|
||||
throw new FHIRException(msg);
|
||||
}
|
||||
|
||||
private void readDelimiters(VerticalBarParserReader reader) throws FHIRException {
|
||||
delimiters.setFieldDelimiter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setComponentDelimiter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setRepetitionDelimiter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setEscapeCharacter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setSubComponentDelimiter(reader.read());
|
||||
delimiters.check();
|
||||
}
|
||||
|
||||
private void readSegment(Element message, VerticalBarParserReader reader) throws FHIRException {
|
||||
Element segment = new Element("segment", message.getProperty().getChild("segment"));
|
||||
message.getChildren().add(segment);
|
||||
Element segmentCode = new Element("code", segment.getProperty().getChild("code"));
|
||||
segment.getChildren().add(segmentCode);
|
||||
segmentCode.setValue(reader.read(3));
|
||||
|
||||
int index = 0;
|
||||
while (!reader.isFinished() && !reader.IsEOL()) {
|
||||
index++;
|
||||
readField(reader, segment, index);
|
||||
if (!reader.isFinished() && !reader.IsEOL())
|
||||
rule(reader.read() == delimiters.getFieldDelimiter(), "Expected to find field delimiter");
|
||||
}
|
||||
if (!reader.isFinished())
|
||||
reader.skipEOL();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void readField(VerticalBarParserReader reader, Element segment, int index) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compose(Element e, OutputStream destination, OutputStyle style, String base) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
package org.hl7.fhir.r4.elementmodel;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import org.hl7.fhir.r4.context.IWorkerContext;
|
||||
import org.hl7.fhir.r4.formats.IParser.OutputStyle;
|
||||
import org.hl7.fhir.r4.model.StructureDefinition;
|
||||
import org.hl7.fhir.exceptions.DefinitionException;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.exceptions.FHIRFormatError;
|
||||
|
||||
/**
|
||||
* This class provides special support for parsing v2 by the v2 logical model
|
||||
* For the logical model, see the FHIRPath spec
|
||||
*
|
||||
* @author Grahame Grieve
|
||||
*
|
||||
*/
|
||||
public class VerticalBarParser extends ParserBase {
|
||||
|
||||
/**
|
||||
* Delimiters for a message. Note that the application rarely needs to concern
|
||||
* itself with this information; it mainly exists for internal use. However if
|
||||
* a message is being written to a spec that calls for non-standard delimiters,
|
||||
* the application can set them here.
|
||||
*
|
||||
* @author Grahame
|
||||
*
|
||||
*/
|
||||
public class Delimiters {
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a field
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_FIELD = '|';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a component
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_COMPONENT = '^';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a subcomponent
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_SUBCOMPONENT = '&';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for a repeat
|
||||
*/
|
||||
public final static char DEFAULT_DELIMITER_REPETITION = '~';
|
||||
|
||||
/**
|
||||
* Hl7 defined default delimiter for an escapeUrlParam
|
||||
*/
|
||||
public final static char DEFAULT_CHARACTER_ESCAPE = '\\';
|
||||
|
||||
|
||||
/**
|
||||
* defined escapeUrlParam character for this message
|
||||
*/
|
||||
private char escapeCharacter;
|
||||
|
||||
/**
|
||||
* defined repetition character for this message
|
||||
*/
|
||||
private char repetitionDelimiter;
|
||||
|
||||
/**
|
||||
* defined field character for this message
|
||||
*/
|
||||
private char fieldDelimiter;
|
||||
|
||||
/**
|
||||
* defined subComponent character for this message
|
||||
*/
|
||||
private char subComponentDelimiter;
|
||||
|
||||
/**
|
||||
* defined component character for this message
|
||||
*/
|
||||
private char componentDelimiter;
|
||||
|
||||
/**
|
||||
* create
|
||||
*
|
||||
*/
|
||||
public Delimiters() {
|
||||
super();
|
||||
reset();
|
||||
}
|
||||
|
||||
public boolean matches(Delimiters other) {
|
||||
return escapeCharacter == other.escapeCharacter &&
|
||||
repetitionDelimiter == other.repetitionDelimiter &&
|
||||
fieldDelimiter == other.fieldDelimiter &&
|
||||
subComponentDelimiter == other.subComponentDelimiter &&
|
||||
componentDelimiter == other.componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get defined component character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getComponentDelimiter() {
|
||||
return componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set defined component character for this message
|
||||
* @param componentDelimiter
|
||||
*/
|
||||
public void setComponentDelimiter(char componentDelimiter) {
|
||||
this.componentDelimiter = componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get defined escapeUrlParam character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getEscapeCharacter() {
|
||||
return escapeCharacter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set defined escapeUrlParam character for this message
|
||||
* @param escapeCharacter
|
||||
*/
|
||||
public void setEscapeCharacter(char escapeCharacter) {
|
||||
this.escapeCharacter = escapeCharacter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get defined field character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getFieldDelimiter() {
|
||||
return fieldDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set defined field character for this message
|
||||
* @param fieldDelimiter
|
||||
*/
|
||||
public void setFieldDelimiter(char fieldDelimiter) {
|
||||
this.fieldDelimiter = fieldDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get repeat field character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getRepetitionDelimiter() {
|
||||
return repetitionDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set repeat field character for this message
|
||||
* @param repetitionDelimiter
|
||||
*/
|
||||
public void setRepetitionDelimiter(char repetitionDelimiter) {
|
||||
this.repetitionDelimiter = repetitionDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get sub-component field character for this message
|
||||
* @return
|
||||
*/
|
||||
public char getSubComponentDelimiter() {
|
||||
return subComponentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* set sub-component field character for this message
|
||||
* @param subComponentDelimiter
|
||||
*/
|
||||
public void setSubComponentDelimiter(char subComponentDelimiter) {
|
||||
this.subComponentDelimiter = subComponentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* reset to default HL7 values
|
||||
*
|
||||
*/
|
||||
public void reset () {
|
||||
fieldDelimiter = DEFAULT_DELIMITER_FIELD;
|
||||
componentDelimiter = DEFAULT_DELIMITER_COMPONENT;
|
||||
subComponentDelimiter = DEFAULT_DELIMITER_SUBCOMPONENT;
|
||||
repetitionDelimiter = DEFAULT_DELIMITER_REPETITION;
|
||||
escapeCharacter = DEFAULT_CHARACTER_ESCAPE;
|
||||
}
|
||||
|
||||
/**
|
||||
* check that the delimiters are valid
|
||||
*
|
||||
* @throws FHIRException
|
||||
*/
|
||||
public void check() throws FHIRException {
|
||||
rule(componentDelimiter != fieldDelimiter, "Delimiter Error: \""+componentDelimiter+"\" is used for both CPComponent and CPField");
|
||||
rule(subComponentDelimiter != fieldDelimiter, "Delimiter Error: \""+subComponentDelimiter+"\" is used for both CPSubComponent and CPField");
|
||||
rule(subComponentDelimiter != componentDelimiter, "Delimiter Error: \""+subComponentDelimiter+"\" is used for both CPSubComponent and CPComponent");
|
||||
rule(repetitionDelimiter != fieldDelimiter, "Delimiter Error: \""+repetitionDelimiter+"\" is used for both Repetition and CPField");
|
||||
rule(repetitionDelimiter != componentDelimiter, "Delimiter Error: \""+repetitionDelimiter+"\" is used for both Repetition and CPComponent");
|
||||
rule(repetitionDelimiter != subComponentDelimiter, "Delimiter Error: \""+repetitionDelimiter+"\" is used for both Repetition and CPSubComponent");
|
||||
rule(escapeCharacter != fieldDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and CPField");
|
||||
rule(escapeCharacter != componentDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and CPComponent");
|
||||
rule(escapeCharacter != subComponentDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and CPSubComponent");
|
||||
rule(escapeCharacter != repetitionDelimiter, "Delimiter Error: \""+escapeCharacter+"\" is used for both Escape and Repetition");
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see whether ch is a delimiter character (vertical bar parser support)
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public boolean isDelimiter(char ch) {
|
||||
return ch == escapeCharacter || ch == repetitionDelimiter || ch == fieldDelimiter || ch == subComponentDelimiter || ch == componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see whether ch is a cell delimiter char (vertical bar parser support)
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public boolean isCellDelimiter(char ch) {
|
||||
return ch == repetitionDelimiter || ch == fieldDelimiter || ch == subComponentDelimiter || ch == componentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* get the escapeUrlParam for a character
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public String getEscape(char ch) {
|
||||
if (ch == escapeCharacter)
|
||||
return escapeCharacter + "E" + escapeCharacter;
|
||||
else if (ch == fieldDelimiter)
|
||||
return escapeCharacter + "F" + escapeCharacter;
|
||||
else if (ch == componentDelimiter)
|
||||
return escapeCharacter + "S" + escapeCharacter;
|
||||
else if (ch == subComponentDelimiter)
|
||||
return escapeCharacter + "T" + escapeCharacter;
|
||||
else if (ch == repetitionDelimiter)
|
||||
return escapeCharacter + "R" + escapeCharacter;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* build the MSH-2 content
|
||||
* @return
|
||||
*/
|
||||
public String forMSH2() {
|
||||
return "" + componentDelimiter + repetitionDelimiter + escapeCharacter + subComponentDelimiter;
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see whether ch represents a delimiter escapeUrlParam
|
||||
* @param ch
|
||||
* @return
|
||||
*/
|
||||
public boolean isDelimiterEscape(char ch) {
|
||||
return ch == 'F' || ch == 'S' || ch == 'E' || ch == 'T' || ch == 'R';
|
||||
}
|
||||
|
||||
/**
|
||||
* get escapeUrlParam for ch in an escapeUrlParam
|
||||
* @param ch
|
||||
* @return
|
||||
* @throws DefinitionException
|
||||
* @throws FHIRException
|
||||
*/
|
||||
public char getDelimiterEscapeChar(char ch) throws DefinitionException {
|
||||
if (ch == 'E')
|
||||
return escapeCharacter;
|
||||
else if (ch == 'F')
|
||||
return fieldDelimiter;
|
||||
else if (ch == 'S')
|
||||
return componentDelimiter;
|
||||
else if (ch == 'T')
|
||||
return subComponentDelimiter;
|
||||
else if (ch == 'R')
|
||||
return repetitionDelimiter;
|
||||
else
|
||||
throw new DefinitionException("internal error in getDelimiterEscapeChar");
|
||||
}
|
||||
}
|
||||
|
||||
public class VerticalBarParserReader {
|
||||
|
||||
|
||||
private BufferedInputStream stream;
|
||||
private String charsetName;
|
||||
private InputStreamReader reader = null;
|
||||
private boolean finished;
|
||||
private char peeked;
|
||||
private char lastValue;
|
||||
private int offset;
|
||||
private int lineNumber;
|
||||
|
||||
public VerticalBarParserReader(BufferedInputStream stream, String charsetName) throws FHIRException {
|
||||
super();
|
||||
setStream(stream);
|
||||
setCharsetName(charsetName);
|
||||
open();
|
||||
}
|
||||
|
||||
public String getCharsetName() {
|
||||
return charsetName;
|
||||
}
|
||||
|
||||
public void setCharsetName(String charsetName) {
|
||||
this.charsetName = charsetName;
|
||||
}
|
||||
|
||||
public BufferedInputStream getStream() {
|
||||
return stream;
|
||||
}
|
||||
|
||||
public void setStream(BufferedInputStream stream) {
|
||||
this.stream = stream;
|
||||
}
|
||||
|
||||
private void open() throws FHIRException {
|
||||
try {
|
||||
stream.mark(2048);
|
||||
reader = new InputStreamReader(stream, charsetName);
|
||||
offset = 0;
|
||||
lineNumber = 0;
|
||||
lastValue = ' ';
|
||||
next();
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void next() throws IOException, FHIRException {
|
||||
finished = !reader.ready();
|
||||
if (!finished) {
|
||||
char[] temp = new char[1];
|
||||
rule(reader.read(temp, 0, 1) == 1, "unable to read 1 character from the stream");
|
||||
peeked = temp[0];
|
||||
}
|
||||
}
|
||||
|
||||
public String read(int charCount) throws FHIRException {
|
||||
String value = "";
|
||||
for (int i = 0; i < charCount; i++)
|
||||
value = value + read();
|
||||
return value;
|
||||
}
|
||||
|
||||
public void skipEOL () throws FHIRException {
|
||||
while (!finished && (peek() == '\r' || peek() == '\n'))
|
||||
read();
|
||||
}
|
||||
|
||||
public char read () throws FHIRException {
|
||||
rule(!finished, "No more content to read");
|
||||
char value = peek();
|
||||
offset++;
|
||||
if (value == '\r' || value == '\n') {
|
||||
if (lastValue != '\r' || value != '\n')
|
||||
lineNumber++;
|
||||
}
|
||||
lastValue = value;
|
||||
try {
|
||||
next();
|
||||
} catch (Exception e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean isFinished () {
|
||||
return finished;
|
||||
}
|
||||
|
||||
public char peek() throws FHIRException {
|
||||
rule(!finished, "Cannot peek");
|
||||
return peeked;
|
||||
}
|
||||
|
||||
public void mark() {
|
||||
stream.mark(2048);
|
||||
}
|
||||
|
||||
public void reset() throws FHIRException {
|
||||
try {
|
||||
stream.reset();
|
||||
} catch (IOException e) {
|
||||
throw new FHIRException(e);
|
||||
}
|
||||
open();
|
||||
}
|
||||
|
||||
public boolean IsEOL() throws FHIRException {
|
||||
return peek() == '\r' || peek() == '\n';
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
public int getOffset() {
|
||||
return offset;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public VerticalBarParser(IWorkerContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
private String charset = "ASCII";
|
||||
private Delimiters delimiters = new Delimiters();
|
||||
|
||||
@Override
|
||||
public Element parse(InputStream stream) throws IOException, FHIRFormatError, DefinitionException, FHIRException {
|
||||
StructureDefinition sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/v2/StructureDefinition/Message");
|
||||
Element message = new Element("Message", new Property(context, sd.getSnapshot().getElementFirstRep(), sd));
|
||||
VerticalBarParserReader reader = new VerticalBarParserReader(new BufferedInputStream(stream), charset);
|
||||
|
||||
preDecode(reader);
|
||||
while (!reader.isFinished()) // && (getOptions().getSegmentLimit() == 0 || getOptions().getSegmentLimit() > message.getSegments().size()))
|
||||
readSegment(message, reader);
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
private void preDecode(VerticalBarParserReader reader) throws FHIRException {
|
||||
reader.skipEOL();
|
||||
String temp = reader.read(3);
|
||||
rule(temp.equals("MSH") || temp.equals("FHS"), "Found '" + temp + "' looking for 'MSH' or 'FHS'");
|
||||
readDelimiters(reader);
|
||||
// readVersion(message); - probably don't need to do that?
|
||||
// readCharacterSet();
|
||||
reader.reset(); // ready to read message now
|
||||
}
|
||||
|
||||
private void rule(boolean test, String msg) throws FHIRException {
|
||||
if (!test)
|
||||
throw new FHIRException(msg);
|
||||
}
|
||||
|
||||
private void readDelimiters(VerticalBarParserReader reader) throws FHIRException {
|
||||
delimiters.setFieldDelimiter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setComponentDelimiter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setRepetitionDelimiter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setEscapeCharacter(reader.read());
|
||||
if (!(reader.peek() == delimiters.getFieldDelimiter()))
|
||||
delimiters.setSubComponentDelimiter(reader.read());
|
||||
delimiters.check();
|
||||
}
|
||||
|
||||
private void readSegment(Element message, VerticalBarParserReader reader) throws FHIRException {
|
||||
Element segment = new Element("segment", message.getProperty().getChild("segment"));
|
||||
message.getChildren().add(segment);
|
||||
Element segmentCode = new Element("code", segment.getProperty().getChild("code"));
|
||||
segment.getChildren().add(segmentCode);
|
||||
segmentCode.setValue(reader.read(3));
|
||||
|
||||
int index = 0;
|
||||
while (!reader.isFinished() && !reader.IsEOL()) {
|
||||
index++;
|
||||
readField(reader, segment, index);
|
||||
if (!reader.isFinished() && !reader.IsEOL())
|
||||
rule(reader.read() == delimiters.getFieldDelimiter(), "Expected to find field delimiter");
|
||||
}
|
||||
if (!reader.isFinished())
|
||||
reader.skipEOL();
|
||||
}
|
||||
|
||||
|
||||
|
||||
private void readField(VerticalBarParserReader reader, Element segment, int index) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void compose(Element e, OutputStream destination, OutputStyle style, String base) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,21 +1,35 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.api.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.api.SummaryEnum;
|
||||
import ca.uhn.fhir.rest.client.apache.ApacheHttpRequest;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import com.google.common.base.Charsets;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.http.*;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hamcrest.core.StringContains;
|
||||
|
@ -23,29 +37,23 @@ import org.hamcrest.core.StringEndsWith;
|
|||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.r4.model.Bundle.BundleEntryComponent;
|
||||
import org.junit.*;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.base.resource.BaseConformance;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.client.apache.ApacheHttpRequest;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.client.api.ServerValidationModeEnum;
|
||||
import ca.uhn.fhir.rest.client.interceptor.CapturingInterceptor;
|
||||
import ca.uhn.fhir.rest.param.*;
|
||||
import ca.uhn.fhir.rest.server.exceptions.*;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class ClientR4Test {
|
||||
|
||||
|
@ -569,7 +577,7 @@ public class ClientR4Test {
|
|||
DateParam date = new DateParam("2001-01-01");
|
||||
client.getObservationByNameValueDate(new CompositeParam<StringParam, DateParam>(str, date));
|
||||
|
||||
assertEquals("http://foo/Observation?" + Observation.SP_CODE_VALUE_DATE + "=" + URLEncoder.encode("FOO\\$BAR$2001-01-01", "UTF-8"), capt.getValue().getURI().toString());
|
||||
assertEquals("http://foo/Observation?" + Observation.SP_CODE_VALUE_DATE + "=" + UrlUtil.escapeUrlParam("FOO\\$BAR$2001-01-01"), capt.getValue().getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,45 +1,6 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.*;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.*;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.r4.model.Bundle.BundleType;
|
||||
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
|
||||
import org.junit.*;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.api.*;
|
||||
import ca.uhn.fhir.rest.api.Constants;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
|
@ -49,7 +10,43 @@ import ca.uhn.fhir.rest.client.impl.BaseClient;
|
|||
import ca.uhn.fhir.rest.client.impl.GenericClient;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.*;
|
||||
import ca.uhn.fhir.util.BundleUtil;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import ca.uhn.fhir.util.UrlUtil;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.input.ReaderInputStream;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.Header;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.hamcrest.core.StringContains;
|
||||
import org.hl7.fhir.r4.model.*;
|
||||
import org.hl7.fhir.r4.model.Bundle.BundleType;
|
||||
import org.hl7.fhir.r4.model.Bundle.HTTPVerb;
|
||||
import org.junit.*;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class GenericClientTest {
|
||||
|
||||
|
@ -782,7 +779,7 @@ public class GenericClientTest {
|
|||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
|
||||
assertEquals("http://foo/Observation?" + Observation.SP_CODE_VALUE_DATE + "=" + URLEncoder.encode("FOO\\$BAR$2001-01-01", "UTF-8"), capt.getValue().getURI().toString());
|
||||
assertEquals("http://foo/Observation?" + Observation.SP_CODE_VALUE_DATE + "=" + UrlUtil.escapeUrlParam("FOO\\$BAR$2001-01-01"), capt.getValue().getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
@ -1025,7 +1022,7 @@ public class GenericClientTest {
|
|||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient?name=" + URLEncoder.encode("AAA,BBB,C\\,C", "UTF-8"), capt.getAllValues().get(1).getURI().toString());
|
||||
assertEquals("http://example.com/fhir/Patient?name=" + UrlUtil.escapeUrlParam("AAA,BBB,C\\,C"), capt.getAllValues().get(1).getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
@ -1116,7 +1113,7 @@ public class GenericClientTest {
|
|||
.returnBundle(Bundle.class)
|
||||
.execute();
|
||||
|
||||
assertEquals("http://example.com/fhir/Patient?identifier=" + URLEncoder.encode("A|B,C|D", "UTF-8"), capt.getAllValues().get(2).getURI().toString());
|
||||
assertEquals("http://example.com/fhir/Patient?identifier=" + UrlUtil.escapeUrlParam("A|B,C|D"), capt.getAllValues().get(2).getURI().toString());
|
||||
|
||||
}
|
||||
|
||||
|
@ -1152,7 +1149,7 @@ public class GenericClientTest {
|
|||
String url = capt.getAllValues().get(index).getURI().toString();
|
||||
assertThat(url, Matchers.startsWith(wantPrefix));
|
||||
assertEquals(wantValue, UrlUtil.unescape(url.substring(wantPrefix.length())));
|
||||
assertEquals(UrlUtil.escape(wantValue), url.substring(wantPrefix.length()));
|
||||
assertEquals(UrlUtil.escapeUrlParam(wantValue), url.substring(wantPrefix.length()));
|
||||
index++;
|
||||
|
||||
response = client.search()
|
||||
|
@ -1164,7 +1161,7 @@ public class GenericClientTest {
|
|||
url = capt.getAllValues().get(index).getURI().toString();
|
||||
assertThat(url, Matchers.startsWith(wantPrefix));
|
||||
assertEquals(wantValue, UrlUtil.unescape(url.substring(wantPrefix.length())));
|
||||
assertEquals(UrlUtil.escape(wantValue), url.substring(wantPrefix.length()));
|
||||
assertEquals(UrlUtil.escapeUrlParam(wantValue), url.substring(wantPrefix.length()));
|
||||
index++;
|
||||
}
|
||||
|
||||
|
@ -1234,8 +1231,8 @@ public class GenericClientTest {
|
|||
.execute();
|
||||
|
||||
assertThat(capt.getValue().getURI().toString(), containsString("http://example.com/fhir/Patient?"));
|
||||
assertThat(capt.getValue().getURI().toString(), containsString("_include=" + UrlUtil.escape(Patient.INCLUDE_ORGANIZATION.getValue())));
|
||||
assertThat(capt.getValue().getURI().toString(), containsString("_include%3Arecurse=" + UrlUtil.escape(Patient.INCLUDE_LINK.getValue())));
|
||||
assertThat(capt.getValue().getURI().toString(), containsString("_include=" + UrlUtil.escapeUrlParam(Patient.INCLUDE_ORGANIZATION.getValue())));
|
||||
assertThat(capt.getValue().getURI().toString(), containsString("_include%3Arecurse=" + UrlUtil.escapeUrlParam(Patient.INCLUDE_LINK.getValue())));
|
||||
assertThat(capt.getValue().getURI().toString(), containsString("_include=*"));
|
||||
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class GraphQLR4ProviderTest {
|
|||
@Test
|
||||
public void testGraphInstance() throws Exception {
|
||||
String query = "{name{family,given}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -80,7 +80,7 @@ public class GraphQLR4ProviderTest {
|
|||
@Test
|
||||
public void testGraphInstanceWithFhirpath() throws Exception {
|
||||
String query = "{name(fhirpath:\"family.exists()\"){text,given,family}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -104,7 +104,7 @@ public class GraphQLR4ProviderTest {
|
|||
@Test
|
||||
public void testGraphSystemInstance() throws Exception {
|
||||
String query = "{Patient(id:123){id,name{given,family}}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -132,7 +132,7 @@ public class GraphQLR4ProviderTest {
|
|||
@Test
|
||||
public void testGraphSystemList() throws Exception {
|
||||
String query = "{PatientList(name:\"pet\"){name{family,given}}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
|
|
@ -91,7 +91,7 @@ public class GraphQLR4RawTest {
|
|||
ourNextRetVal = "{\"foo\"}";
|
||||
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escape("{name{family,given}}"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escapeUrlParam("{name{family,given}}"));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -114,7 +114,7 @@ public class GraphQLR4RawTest {
|
|||
ourNextRetVal = "{\"foo\"}";
|
||||
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Condition/123/$graphql?query=" + UrlUtil.escape("{name{family,given}}"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Condition/123/$graphql?query=" + UrlUtil.escapeUrlParam("{name{family,given}}"));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -132,7 +132,7 @@ public class GraphQLR4RawTest {
|
|||
ourNextRetVal = "{\"foo\"}";
|
||||
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escape("{name{family,given}}"));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escapeUrlParam("{name{family,given}}"));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
|
|
@ -131,25 +131,25 @@ public class SearchR4Test {
|
|||
httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?identifier=foo%7Cbar&_format=" + Constants.CT_FHIR_JSON_NEW);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
// Fetch the next page
|
||||
httpGet = new HttpGet(linkNext);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
// Fetch the next page
|
||||
httpGet = new HttpGet(linkNext);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
// Fetch the next page
|
||||
httpGet = new HttpGet(linkNext);
|
||||
bundle = executeAndReturnLinkNext(httpGet, EncodingEnum.JSON);
|
||||
linkNext = bundle.getLink(Constants.LINK_NEXT).getUrl();
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escape(Constants.CT_FHIR_JSON_NEW)));
|
||||
assertThat(linkNext, containsString("_format=" + UrlUtil.escapeUrlParam(Constants.CT_FHIR_JSON_NEW)));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static ca.uhn.fhir.util.UrlUtil.escape;
|
||||
import static ca.uhn.fhir.util.UrlUtil.escapeUrlParam;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
|
@ -110,10 +110,10 @@ public class SearchSearchServerDstu1Test {
|
|||
b.append("http://localhost:");
|
||||
b.append(ourPort);
|
||||
b.append("/Patient?");
|
||||
b.append(escape("findPatientWithAndList")).append('=').append(escape("NE\\,NE,NE\\,NE")).append('&');
|
||||
b.append(escape("findPatientWithAndList")).append('=').append(escape("NE\\\\NE")).append('&');
|
||||
b.append(escape("findPatientWithAndList:exact")).append('=').append(escape("E\\$E")).append('&');
|
||||
b.append(escape("findPatientWithAndList:exact")).append('=').append(escape("E\\|E")).append('&');
|
||||
b.append(escapeUrlParam("findPatientWithAndList")).append('=').append(escapeUrlParam("NE\\,NE,NE\\,NE")).append('&');
|
||||
b.append(escapeUrlParam("findPatientWithAndList")).append('=').append(escapeUrlParam("NE\\\\NE")).append('&');
|
||||
b.append(escapeUrlParam("findPatientWithAndList:exact")).append('=').append(escapeUrlParam("E\\$E")).append('&');
|
||||
b.append(escapeUrlParam("findPatientWithAndList:exact")).append('=').append(escapeUrlParam("E\\|E")).append('&');
|
||||
|
||||
HttpGet httpGet = new HttpGet(b.toString());
|
||||
|
||||
|
@ -416,7 +416,7 @@ public class SearchSearchServerDstu1Test {
|
|||
|
||||
@Test
|
||||
public void testSearchWithTokenParameter() throws Exception {
|
||||
String token = UrlUtil.escape("http://www.dmix.gov/vista/2957|301");
|
||||
String token = UrlUtil.escapeUrlParam("http://www.dmix.gov/vista/2957|301");
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?tokenParam=" + token);
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
|
|
|
@ -1,472 +1,472 @@
|
|||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
package org.hl7.fhir.utilities.xml;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.ls.DOMImplementationLS;
|
||||
import org.w3c.dom.ls.LSSerializer;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public class XMLUtil {
|
||||
|
||||
public static final String SPACE_CHAR = "\u00A0";
|
||||
|
||||
public static boolean isNMToken(String name) {
|
||||
if (name == null)
|
||||
return false;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
if (!isNMTokenChar(name.charAt(i)))
|
||||
return false;
|
||||
return name.length() > 0;
|
||||
}
|
||||
|
||||
public static boolean isNMTokenChar(char c) {
|
||||
return isLetter(c) || isDigit(c) || c == '.' || c == '-' || c == '_' || c == ':' || isCombiningChar(c) || isExtender(c);
|
||||
}
|
||||
|
||||
private static boolean isDigit(char c) {
|
||||
return (c >= '\u0030' && c <= '\u0039') || (c >= '\u0660' && c <= '\u0669') || (c >= '\u06F0' && c <= '\u06F9') ||
|
||||
(c >= '\u0966' && c <= '\u096F') || (c >= '\u09E6' && c <= '\u09EF') || (c >= '\u0A66' && c <= '\u0A6F') ||
|
||||
(c >= '\u0AE6' && c <= '\u0AEF') || (c >= '\u0B66' && c <= '\u0B6F') || (c >= '\u0BE7' && c <= '\u0BEF') ||
|
||||
(c >= '\u0C66' && c <= '\u0C6F') || (c >= '\u0CE6' && c <= '\u0CEF') || (c >= '\u0D66' && c <= '\u0D6F') ||
|
||||
(c >= '\u0E50' && c <= '\u0E59') || (c >= '\u0ED0' && c <= '\u0ED9') || (c >= '\u0F20' && c <= '\u0F29');
|
||||
}
|
||||
|
||||
private static boolean isCombiningChar(char c) {
|
||||
return (c >= '\u0300' && c <= '\u0345') || (c >= '\u0360' && c <= '\u0361') || (c >= '\u0483' && c <= '\u0486') ||
|
||||
(c >= '\u0591' && c <= '\u05A1') || (c >= '\u05A3' && c <= '\u05B9') || (c >= '\u05BB' && c <= '\u05BD') ||
|
||||
c == '\u05BF' || (c >= '\u05C1' && c <= '\u05C2') || c == '\u05C4' || (c >= '\u064B' && c <= '\u0652') ||
|
||||
c == '\u0670' || (c >= '\u06D6' && c <= '\u06DC') || (c >= '\u06DD' && c <= '\u06DF') || (c >= '\u06E0' && c <= '\u06E4') ||
|
||||
(c >= '\u06E7' && c <= '\u06E8') || (c >= '\u06EA' && c <= '\u06ED') || (c >= '\u0901' && c <= '\u0903') || c == '\u093C' ||
|
||||
(c >= '\u093E' && c <= '\u094C') || c == '\u094D' || (c >= '\u0951' && c <= '\u0954') || (c >= '\u0962' && c <= '\u0963') ||
|
||||
(c >= '\u0981' && c <= '\u0983') || c == '\u09BC' || c == '\u09BE' || c == '\u09BF' || (c >= '\u09C0' && c <= '\u09C4') ||
|
||||
(c >= '\u09C7' && c <= '\u09C8') || (c >= '\u09CB' && c <= '\u09CD') || c == '\u09D7' || (c >= '\u09E2' && c <= '\u09E3') ||
|
||||
c == '\u0A02' || c == '\u0A3C' || c == '\u0A3E' || c == '\u0A3F' || (c >= '\u0A40' && c <= '\u0A42') ||
|
||||
(c >= '\u0A47' && c <= '\u0A48') || (c >= '\u0A4B' && c <= '\u0A4D') || (c >= '\u0A70' && c <= '\u0A71') ||
|
||||
(c >= '\u0A81' && c <= '\u0A83') || c == '\u0ABC' || (c >= '\u0ABE' && c <= '\u0AC5') || (c >= '\u0AC7' && c <= '\u0AC9') ||
|
||||
(c >= '\u0ACB' && c <= '\u0ACD') || (c >= '\u0B01' && c <= '\u0B03') || c == '\u0B3C' || (c >= '\u0B3E' && c <= '\u0B43') ||
|
||||
(c >= '\u0B47' && c <= '\u0B48') || (c >= '\u0B4B' && c <= '\u0B4D') || (c >= '\u0B56' && c <= '\u0B57') ||
|
||||
(c >= '\u0B82' && c <= '\u0B83') || (c >= '\u0BBE' && c <= '\u0BC2') || (c >= '\u0BC6' && c <= '\u0BC8') ||
|
||||
(c >= '\u0BCA' && c <= '\u0BCD') || c == '\u0BD7' || (c >= '\u0C01' && c <= '\u0C03') || (c >= '\u0C3E' && c <= '\u0C44') ||
|
||||
(c >= '\u0C46' && c <= '\u0C48') || (c >= '\u0C4A' && c <= '\u0C4D') || (c >= '\u0C55' && c <= '\u0C56') ||
|
||||
(c >= '\u0C82' && c <= '\u0C83') || (c >= '\u0CBE' && c <= '\u0CC4') || (c >= '\u0CC6' && c <= '\u0CC8') ||
|
||||
(c >= '\u0CCA' && c <= '\u0CCD') || (c >= '\u0CD5' && c <= '\u0CD6') || (c >= '\u0D02' && c <= '\u0D03') ||
|
||||
(c >= '\u0D3E' && c <= '\u0D43') || (c >= '\u0D46' && c <= '\u0D48') || (c >= '\u0D4A' && c <= '\u0D4D') || c == '\u0D57' ||
|
||||
c == '\u0E31' || (c >= '\u0E34' && c <= '\u0E3A') || (c >= '\u0E47' && c <= '\u0E4E') || c == '\u0EB1' ||
|
||||
(c >= '\u0EB4' && c <= '\u0EB9') || (c >= '\u0EBB' && c <= '\u0EBC') || (c >= '\u0EC8' && c <= '\u0ECD') ||
|
||||
(c >= '\u0F18' && c <= '\u0F19') || c == '\u0F35' || c == '\u0F37' || c == '\u0F39' || c == '\u0F3E' || c == '\u0F3F' ||
|
||||
(c >= '\u0F71' && c <= '\u0F84') || (c >= '\u0F86' && c <= '\u0F8B') || (c >= '\u0F90' && c <= '\u0F95') || c == '\u0F97' ||
|
||||
(c >= '\u0F99' && c <= '\u0FAD') || (c >= '\u0FB1' && c <= '\u0FB7') || c == '\u0FB9' || (c >= '\u20D0' && c <= '\u20DC') ||
|
||||
c == '\u20E1' || (c >= '\u302A' && c <= '\u302F') || c == '\u3099' || c == '\u309A';
|
||||
}
|
||||
|
||||
private static boolean isExtender(char c) {
|
||||
return c == '\u00B7' || c == '\u02D0' || c == '\u02D1' || c == '\u0387' || c == '\u0640' || c == '\u0E46' ||
|
||||
c == '\u0EC6' || c == '\u3005' || (c >= '\u3031' && c <= '\u3035') || (c >= '\u309D' && c <= '\u309E') ||
|
||||
(c >= '\u30FC' && c <= '\u30FE');
|
||||
}
|
||||
|
||||
private static boolean isLetter(char c) {
|
||||
return isBaseChar(c) || isIdeographic(c);
|
||||
}
|
||||
|
||||
private static boolean isBaseChar(char c) {
|
||||
return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A') || (c >= '\u00C0' && c <= '\u00D6') ||
|
||||
(c >= '\u00D8' && c <= '\u00F6') || (c >= '\u00F8' && c <= '\u00FF') || (c >= '\u0100' && c <= '\u0131') ||
|
||||
(c >= '\u0134' && c <= '\u013E') || (c >= '\u0141' && c <= '\u0148') || (c >= '\u014A' && c <= '\u017E') ||
|
||||
(c >= '\u0180' && c <= '\u01C3') || (c >= '\u01CD' && c <= '\u01F0') || (c >= '\u01F4' && c <= '\u01F5') ||
|
||||
(c >= '\u01FA' && c <= '\u0217') || (c >= '\u0250' && c <= '\u02A8') || (c >= '\u02BB' && c <= '\u02C1') ||
|
||||
c == '\u0386' || (c >= '\u0388' && c <= '\u038A') || c == '\u038C' || (c >= '\u038E' && c <= '\u03A1') ||
|
||||
(c >= '\u03A3' && c <= '\u03CE') || (c >= '\u03D0' && c <= '\u03D6') || c == '\u03DA' || c == '\u03DC' || c == '\u03DE' ||
|
||||
c == '\u03E0' || (c >= '\u03E2' && c <= '\u03F3') || (c >= '\u0401' && c <= '\u040C') || (c >= '\u040E' && c <= '\u044F') ||
|
||||
(c >= '\u0451' && c <= '\u045C') || (c >= '\u045E' && c <= '\u0481') || (c >= '\u0490' && c <= '\u04C4') ||
|
||||
(c >= '\u04C7' && c <= '\u04C8') || (c >= '\u04CB' && c <= '\u04CC') || (c >= '\u04D0' && c <= '\u04EB') ||
|
||||
(c >= '\u04EE' && c <= '\u04F5') || (c >= '\u04F8' && c <= '\u04F9') || (c >= '\u0531' && c <= '\u0556') ||
|
||||
c == '\u0559' || (c >= '\u0561' && c <= '\u0586') || (c >= '\u05D0' && c <= '\u05EA') || (c >= '\u05F0' && c <= '\u05F2') ||
|
||||
(c >= '\u0621' && c <= '\u063A') || (c >= '\u0641' && c <= '\u064A') || (c >= '\u0671' && c <= '\u06B7') ||
|
||||
(c >= '\u06BA' && c <= '\u06BE') || (c >= '\u06C0' && c <= '\u06CE') || (c >= '\u06D0' && c <= '\u06D3') ||
|
||||
c == '\u06D5' || (c >= '\u06E5' && c <= '\u06E6') || (c >= '\u0905' && c <= '\u0939') || c == '\u093D' ||
|
||||
(c >= '\u0958' && c <= '\u0961') || (c >= '\u0985' && c <= '\u098C') || (c >= '\u098F' && c <= '\u0990') ||
|
||||
(c >= '\u0993' && c <= '\u09A8') || (c >= '\u09AA' && c <= '\u09B0') || c == '\u09B2' ||
|
||||
(c >= '\u09B6' && c <= '\u09B9') || (c >= '\u09DC' && c <= '\u09DD') || (c >= '\u09DF' && c <= '\u09E1') ||
|
||||
(c >= '\u09F0' && c <= '\u09F1') || (c >= '\u0A05' && c <= '\u0A0A') || (c >= '\u0A0F' && c <= '\u0A10') ||
|
||||
(c >= '\u0A13' && c <= '\u0A28') || (c >= '\u0A2A' && c <= '\u0A30') || (c >= '\u0A32' && c <= '\u0A33') ||
|
||||
(c >= '\u0A35' && c <= '\u0A36') || (c >= '\u0A38' && c <= '\u0A39') || (c >= '\u0A59' && c <= '\u0A5C') ||
|
||||
c == '\u0A5E' || (c >= '\u0A72' && c <= '\u0A74') || (c >= '\u0A85' && c <= '\u0A8B') || c == '\u0A8D' ||
|
||||
(c >= '\u0A8F' && c <= '\u0A91') || (c >= '\u0A93' && c <= '\u0AA8') || (c >= '\u0AAA' && c <= '\u0AB0') ||
|
||||
(c >= '\u0AB2' && c <= '\u0AB3') || (c >= '\u0AB5' && c <= '\u0AB9') || c == '\u0ABD' || c == '\u0AE0' ||
|
||||
(c >= '\u0B05' && c <= '\u0B0C') || (c >= '\u0B0F' && c <= '\u0B10') || (c >= '\u0B13' && c <= '\u0B28') ||
|
||||
(c >= '\u0B2A' && c <= '\u0B30') || (c >= '\u0B32' && c <= '\u0B33') || (c >= '\u0B36' && c <= '\u0B39') ||
|
||||
c == '\u0B3D' || (c >= '\u0B5C' && c <= '\u0B5D') || (c >= '\u0B5F' && c <= '\u0B61') ||
|
||||
(c >= '\u0B85' && c <= '\u0B8A') || (c >= '\u0B8E' && c <= '\u0B90') || (c >= '\u0B92' && c <= '\u0B95') ||
|
||||
(c >= '\u0B99' && c <= '\u0B9A') || c == '\u0B9C' || (c >= '\u0B9E' && c <= '\u0B9F') ||
|
||||
(c >= '\u0BA3' && c <= '\u0BA4') || (c >= '\u0BA8' && c <= '\u0BAA') || (c >= '\u0BAE' && c <= '\u0BB5') ||
|
||||
(c >= '\u0BB7' && c <= '\u0BB9') || (c >= '\u0C05' && c <= '\u0C0C') || (c >= '\u0C0E' && c <= '\u0C10') ||
|
||||
(c >= '\u0C12' && c <= '\u0C28') || (c >= '\u0C2A' && c <= '\u0C33') || (c >= '\u0C35' && c <= '\u0C39') ||
|
||||
(c >= '\u0C60' && c <= '\u0C61') || (c >= '\u0C85' && c <= '\u0C8C') || (c >= '\u0C8E' && c <= '\u0C90') ||
|
||||
(c >= '\u0C92' && c <= '\u0CA8') || (c >= '\u0CAA' && c <= '\u0CB3') || (c >= '\u0CB5' && c <= '\u0CB9') ||
|
||||
c == '\u0CDE' || (c >= '\u0CE0' && c <= '\u0CE1') || (c >= '\u0D05' && c <= '\u0D0C') ||
|
||||
(c >= '\u0D0E' && c <= '\u0D10') || (c >= '\u0D12' && c <= '\u0D28') || (c >= '\u0D2A' && c <= '\u0D39') ||
|
||||
(c >= '\u0D60' && c <= '\u0D61') || (c >= '\u0E01' && c <= '\u0E2E') || c == '\u0E30' ||
|
||||
(c >= '\u0E32' && c <= '\u0E33') || (c >= '\u0E40' && c <= '\u0E45') || (c >= '\u0E81' && c <= '\u0E82') ||
|
||||
c == '\u0E84' || (c >= '\u0E87' && c <= '\u0E88') || c == '\u0E8A' || c == '\u0E8D' || (c >= '\u0E94' && c <= '\u0E97') ||
|
||||
(c >= '\u0E99' && c <= '\u0E9F') || (c >= '\u0EA1' && c <= '\u0EA3') || c == '\u0EA5' || c == '\u0EA7' ||
|
||||
(c >= '\u0EAA' && c <= '\u0EAB') || (c >= '\u0EAD' && c <= '\u0EAE') || c == '\u0EB0' ||
|
||||
(c >= '\u0EB2' && c <= '\u0EB3') || c == '\u0EBD' || (c >= '\u0EC0' && c <= '\u0EC4') ||
|
||||
(c >= '\u0F40' && c <= '\u0F47') || (c >= '\u0F49' && c <= '\u0F69') || (c >= '\u10A0' && c <= '\u10C5') ||
|
||||
(c >= '\u10D0' && c <= '\u10F6') || c == '\u1100' || (c >= '\u1102' && c <= '\u1103') ||
|
||||
(c >= '\u1105' && c <= '\u1107') || c == '\u1109' || (c >= '\u110B' && c <= '\u110C') ||
|
||||
(c >= '\u110E' && c <= '\u1112') || c == '\u113C' || c == '\u113E' || c == '\u1140' || c == '\u114C' ||
|
||||
c == '\u114E' || c == '\u1150' || (c >= '\u1154' && c <= '\u1155') || c == '\u1159' ||
|
||||
(c >= '\u115F' && c <= '\u1161') || c == '\u1163' || c == '\u1165' || c == '\u1167' || c == '\u1169' ||
|
||||
(c >= '\u116D' && c <= '\u116E') || (c >= '\u1172' && c <= '\u1173') || c == '\u1175' ||
|
||||
c == '\u119E' || c == '\u11A8' || c == '\u11AB' || (c >= '\u11AE' && c <= '\u11AF') ||
|
||||
(c >= '\u11B7' && c <= '\u11B8') || c == '\u11BA' || (c >= '\u11BC' && c <= '\u11C2') ||
|
||||
c == '\u11EB' || c == '\u11F0' || c == '\u11F9' || (c >= '\u1E00' && c <= '\u1E9B') || (c >= '\u1EA0' && c <= '\u1EF9') ||
|
||||
(c >= '\u1F00' && c <= '\u1F15') || (c >= '\u1F18' && c <= '\u1F1D') || (c >= '\u1F20' && c <= '\u1F45') ||
|
||||
(c >= '\u1F48' && c <= '\u1F4D') || (c >= '\u1F50' && c <= '\u1F57') || c == '\u1F59' || c == '\u1F5B' || c == '\u1F5D' ||
|
||||
(c >= '\u1F5F' && c <= '\u1F7D') || (c >= '\u1F80' && c <= '\u1FB4') || (c >= '\u1FB6' && c <= '\u1FBC') ||
|
||||
c == '\u1FBE' || (c >= '\u1FC2' && c <= '\u1FC4') || (c >= '\u1FC6' && c <= '\u1FCC') ||
|
||||
(c >= '\u1FD0' && c <= '\u1FD3') || (c >= '\u1FD6' && c <= '\u1FDB') || (c >= '\u1FE0' && c <= '\u1FEC') ||
|
||||
(c >= '\u1FF2' && c <= '\u1FF4') || (c >= '\u1FF6' && c <= '\u1FFC') || c == '\u2126' ||
|
||||
(c >= '\u212A' && c <= '\u212B') || c == '\u212E' || (c >= '\u2180' && c <= '\u2182') ||
|
||||
(c >= '\u3041' && c <= '\u3094') || (c >= '\u30A1' && c <= '\u30FA') || (c >= '\u3105' && c <= '\u312C') ||
|
||||
(c >= '\uAC00' && c <= '\uD7A3');
|
||||
}
|
||||
|
||||
private static boolean isIdeographic(char c) {
|
||||
return (c >= '\u4E00' && c <= '\u9FA5') || c == '\u3007' || (c >= '\u3021' && c <= '\u3029');
|
||||
}
|
||||
|
||||
public static String determineEncoding(InputStream stream) throws IOException {
|
||||
stream.mark(20000);
|
||||
try {
|
||||
int b0 = stream.read();
|
||||
int b1 = stream.read();
|
||||
int b2 = stream.read();
|
||||
int b3 = stream.read();
|
||||
|
||||
if (b0 == 0xFE && b1 == 0xFF)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0xFF && b1 == 0xFE)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF )
|
||||
return "UTF-8";
|
||||
else if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0x3C && b1 == 0x3F && b2 == 0x78 && b3 == 0x6D) {
|
||||
// UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS, EUC, or any other 7-bit, 8-bit, or mixed-width encoding
|
||||
// which ensures that the characters of ASCII have their normal positions, width, and values; the actual encoding
|
||||
// declaration must be read to detect which of these applies, but since all of these encodings use the same bit patterns
|
||||
// for the relevant ASCII characters, the encoding declaration itself may be read reliably
|
||||
InputStreamReader rdr = new InputStreamReader(stream, "US-ASCII");
|
||||
String hdr = readFirstLine(rdr);
|
||||
return extractEncoding(hdr);
|
||||
} else
|
||||
return null;
|
||||
} finally {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractEncoding(String hdr) {
|
||||
int i = hdr.indexOf("encoding=");
|
||||
if (i == -1)
|
||||
return null;
|
||||
hdr = hdr.substring(i+9);
|
||||
char sep = hdr.charAt(0);
|
||||
hdr = hdr.substring(1);
|
||||
i = hdr.indexOf(sep);
|
||||
if (i == -1)
|
||||
return null;
|
||||
return hdr.substring(0, i);
|
||||
}
|
||||
|
||||
private static String readFirstLine(InputStreamReader rdr) throws IOException {
|
||||
char[] buf = new char[1];
|
||||
StringBuffer bldr = new StringBuffer();
|
||||
rdr.read(buf);
|
||||
while (buf[0] != '>') {
|
||||
bldr.append(buf[0]);
|
||||
rdr.read(buf);
|
||||
}
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
|
||||
public static boolean charSetImpliesAscii(String charset) {
|
||||
return charset.equals("ISO-8859-1") || charset.equals("US-ASCII");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the raw characters to XML escape characters.
|
||||
*
|
||||
* @param rawContent
|
||||
* @param charset Null when charset is not known, so we assume it's unicode
|
||||
* @param isNoLines
|
||||
* @return escape string
|
||||
*/
|
||||
public static String escapeXML(String rawContent, String charset, boolean isNoLines) {
|
||||
if (rawContent == null)
|
||||
return "";
|
||||
else {
|
||||
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("&#x"+Integer.toHexString(ch).toUpperCase()+";");
|
||||
else if (isNoLines) {
|
||||
if (ch == '\r')
|
||||
sb.append("
");
|
||||
else if (ch != '\n')
|
||||
sb.append(ch);
|
||||
}
|
||||
else
|
||||
sb.append(ch);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static Element getFirstChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getFirstChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Element getNextSibling(Element e) {
|
||||
Node n = e.getNextSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static void getNamedChildren(Element e, String name, List<Element> set) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null) {
|
||||
if (name.equals(c.getLocalName()) || name.equals(c.getNodeName()) )
|
||||
set.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(Element r) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
Node n = r.getFirstChild();
|
||||
boolean ws = false;
|
||||
while (n != null) {
|
||||
if (n.getNodeType() == Node.TEXT_NODE) {
|
||||
String t = n.getTextContent().trim();
|
||||
if (Utilities.noString(t))
|
||||
ws = true;
|
||||
else {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(t);
|
||||
}
|
||||
}
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(htmlToXmlEscapedPlainText((Element) n));
|
||||
if (r.getNodeName().equals("br") || r.getNodeName().equals("p"))
|
||||
s.append("\r\n");
|
||||
}
|
||||
n = n.getNextSibling();
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(String definition) throws ParserConfigurationException, SAXException, IOException {
|
||||
return htmlToXmlEscapedPlainText(parseToDom("<div>"+definition+"</div>").getDocumentElement());
|
||||
}
|
||||
|
||||
public static String elementToString(Element el) {
|
||||
if (el == null)
|
||||
return "";
|
||||
Document document = el.getOwnerDocument();
|
||||
DOMImplementationLS domImplLS = (DOMImplementationLS) document
|
||||
.getImplementation();
|
||||
LSSerializer serializer = domImplLS.createLSSerializer();
|
||||
return serializer.writeToString(el);
|
||||
}
|
||||
|
||||
public static String getNamedChildValue(Element element, String name) {
|
||||
Element e = getNamedChild(element, name);
|
||||
return e == null ? null : e.getAttribute("value");
|
||||
}
|
||||
|
||||
public static void setNamedChildValue(Element element, String name, String value) throws FHIRException {
|
||||
Element e = getNamedChild(element, name);
|
||||
if (e == null)
|
||||
throw new FHIRException("unable to find element "+name);
|
||||
e.setAttribute("value", value);
|
||||
}
|
||||
|
||||
|
||||
public static void getNamedChildrenWithWildcard(Element focus, String name, List<Element> children) {
|
||||
Element c = getFirstChild(focus);
|
||||
while (c != null) {
|
||||
String n = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
|
||||
if (name.equals(n) || (name.endsWith("[x]") && n.startsWith(name.substring(0, name.length()-3))))
|
||||
children.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void getNamedChildrenWithTails(Element focus, String name, List<Element> children, Set<String> typeTails) {
|
||||
Element c = getFirstChild(focus);
|
||||
while (c != null) {
|
||||
String n = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
|
||||
if (n.equals(name) || (!n.equals("responseCode") && (n.startsWith(name) && typeTails.contains(n.substring(name.length())))))
|
||||
children.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c != null;
|
||||
}
|
||||
|
||||
public static Document parseToDom(String content) throws ParserConfigurationException, SAXException, IOException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(false);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.parse(new ByteArrayInputStream(content.getBytes()));
|
||||
}
|
||||
|
||||
public static Document parseFileToDom(String filename) throws ParserConfigurationException, SAXException, IOException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(false);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.parse(new FileInputStream(filename));
|
||||
}
|
||||
|
||||
public static Element getLastChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getLastChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getPrevSibling(Element e) {
|
||||
Node n = e.getPreviousSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static String getNamedChildAttribute(Element element, String name, String aname) {
|
||||
Element e = getNamedChild(element, name);
|
||||
return e == null ? null : e.getAttribute(aname);
|
||||
}
|
||||
|
||||
public static void writeDomToFile(Document doc, String filename) throws TransformerException {
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
DOMSource source = new DOMSource(doc);
|
||||
StreamResult streamResult = new StreamResult(new File(filename));
|
||||
transformer.transform(source, streamResult);
|
||||
}
|
||||
|
||||
public static String getXsiType(org.w3c.dom.Element element) {
|
||||
Attr a = element.getAttributeNodeNS("http://www.w3.org/2001/XMLSchema-instance", "type");
|
||||
return (a == null ? null : a.getTextContent());
|
||||
|
||||
}
|
||||
|
||||
public static String getDirectText(org.w3c.dom.Element node) {
|
||||
Node n = node.getFirstChild();
|
||||
StringBuilder b = new StringBuilder();
|
||||
while (n != null) {
|
||||
if (n.getNodeType() == Node.TEXT_NODE)
|
||||
b.append(n.getTextContent());
|
||||
n = n.getNextSibling();
|
||||
}
|
||||
return b.toString().trim();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
/*
|
||||
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.
|
||||
|
||||
*/
|
||||
package org.hl7.fhir.utilities.xml;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.utilities.Utilities;
|
||||
import org.w3c.dom.Attr;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.ls.DOMImplementationLS;
|
||||
import org.w3c.dom.ls.LSSerializer;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public class XMLUtil {
|
||||
|
||||
public static final String SPACE_CHAR = "\u00A0";
|
||||
|
||||
public static boolean isNMToken(String name) {
|
||||
if (name == null)
|
||||
return false;
|
||||
for (int i = 0; i < name.length(); i++)
|
||||
if (!isNMTokenChar(name.charAt(i)))
|
||||
return false;
|
||||
return name.length() > 0;
|
||||
}
|
||||
|
||||
public static boolean isNMTokenChar(char c) {
|
||||
return isLetter(c) || isDigit(c) || c == '.' || c == '-' || c == '_' || c == ':' || isCombiningChar(c) || isExtender(c);
|
||||
}
|
||||
|
||||
private static boolean isDigit(char c) {
|
||||
return (c >= '\u0030' && c <= '\u0039') || (c >= '\u0660' && c <= '\u0669') || (c >= '\u06F0' && c <= '\u06F9') ||
|
||||
(c >= '\u0966' && c <= '\u096F') || (c >= '\u09E6' && c <= '\u09EF') || (c >= '\u0A66' && c <= '\u0A6F') ||
|
||||
(c >= '\u0AE6' && c <= '\u0AEF') || (c >= '\u0B66' && c <= '\u0B6F') || (c >= '\u0BE7' && c <= '\u0BEF') ||
|
||||
(c >= '\u0C66' && c <= '\u0C6F') || (c >= '\u0CE6' && c <= '\u0CEF') || (c >= '\u0D66' && c <= '\u0D6F') ||
|
||||
(c >= '\u0E50' && c <= '\u0E59') || (c >= '\u0ED0' && c <= '\u0ED9') || (c >= '\u0F20' && c <= '\u0F29');
|
||||
}
|
||||
|
||||
private static boolean isCombiningChar(char c) {
|
||||
return (c >= '\u0300' && c <= '\u0345') || (c >= '\u0360' && c <= '\u0361') || (c >= '\u0483' && c <= '\u0486') ||
|
||||
(c >= '\u0591' && c <= '\u05A1') || (c >= '\u05A3' && c <= '\u05B9') || (c >= '\u05BB' && c <= '\u05BD') ||
|
||||
c == '\u05BF' || (c >= '\u05C1' && c <= '\u05C2') || c == '\u05C4' || (c >= '\u064B' && c <= '\u0652') ||
|
||||
c == '\u0670' || (c >= '\u06D6' && c <= '\u06DC') || (c >= '\u06DD' && c <= '\u06DF') || (c >= '\u06E0' && c <= '\u06E4') ||
|
||||
(c >= '\u06E7' && c <= '\u06E8') || (c >= '\u06EA' && c <= '\u06ED') || (c >= '\u0901' && c <= '\u0903') || c == '\u093C' ||
|
||||
(c >= '\u093E' && c <= '\u094C') || c == '\u094D' || (c >= '\u0951' && c <= '\u0954') || (c >= '\u0962' && c <= '\u0963') ||
|
||||
(c >= '\u0981' && c <= '\u0983') || c == '\u09BC' || c == '\u09BE' || c == '\u09BF' || (c >= '\u09C0' && c <= '\u09C4') ||
|
||||
(c >= '\u09C7' && c <= '\u09C8') || (c >= '\u09CB' && c <= '\u09CD') || c == '\u09D7' || (c >= '\u09E2' && c <= '\u09E3') ||
|
||||
c == '\u0A02' || c == '\u0A3C' || c == '\u0A3E' || c == '\u0A3F' || (c >= '\u0A40' && c <= '\u0A42') ||
|
||||
(c >= '\u0A47' && c <= '\u0A48') || (c >= '\u0A4B' && c <= '\u0A4D') || (c >= '\u0A70' && c <= '\u0A71') ||
|
||||
(c >= '\u0A81' && c <= '\u0A83') || c == '\u0ABC' || (c >= '\u0ABE' && c <= '\u0AC5') || (c >= '\u0AC7' && c <= '\u0AC9') ||
|
||||
(c >= '\u0ACB' && c <= '\u0ACD') || (c >= '\u0B01' && c <= '\u0B03') || c == '\u0B3C' || (c >= '\u0B3E' && c <= '\u0B43') ||
|
||||
(c >= '\u0B47' && c <= '\u0B48') || (c >= '\u0B4B' && c <= '\u0B4D') || (c >= '\u0B56' && c <= '\u0B57') ||
|
||||
(c >= '\u0B82' && c <= '\u0B83') || (c >= '\u0BBE' && c <= '\u0BC2') || (c >= '\u0BC6' && c <= '\u0BC8') ||
|
||||
(c >= '\u0BCA' && c <= '\u0BCD') || c == '\u0BD7' || (c >= '\u0C01' && c <= '\u0C03') || (c >= '\u0C3E' && c <= '\u0C44') ||
|
||||
(c >= '\u0C46' && c <= '\u0C48') || (c >= '\u0C4A' && c <= '\u0C4D') || (c >= '\u0C55' && c <= '\u0C56') ||
|
||||
(c >= '\u0C82' && c <= '\u0C83') || (c >= '\u0CBE' && c <= '\u0CC4') || (c >= '\u0CC6' && c <= '\u0CC8') ||
|
||||
(c >= '\u0CCA' && c <= '\u0CCD') || (c >= '\u0CD5' && c <= '\u0CD6') || (c >= '\u0D02' && c <= '\u0D03') ||
|
||||
(c >= '\u0D3E' && c <= '\u0D43') || (c >= '\u0D46' && c <= '\u0D48') || (c >= '\u0D4A' && c <= '\u0D4D') || c == '\u0D57' ||
|
||||
c == '\u0E31' || (c >= '\u0E34' && c <= '\u0E3A') || (c >= '\u0E47' && c <= '\u0E4E') || c == '\u0EB1' ||
|
||||
(c >= '\u0EB4' && c <= '\u0EB9') || (c >= '\u0EBB' && c <= '\u0EBC') || (c >= '\u0EC8' && c <= '\u0ECD') ||
|
||||
(c >= '\u0F18' && c <= '\u0F19') || c == '\u0F35' || c == '\u0F37' || c == '\u0F39' || c == '\u0F3E' || c == '\u0F3F' ||
|
||||
(c >= '\u0F71' && c <= '\u0F84') || (c >= '\u0F86' && c <= '\u0F8B') || (c >= '\u0F90' && c <= '\u0F95') || c == '\u0F97' ||
|
||||
(c >= '\u0F99' && c <= '\u0FAD') || (c >= '\u0FB1' && c <= '\u0FB7') || c == '\u0FB9' || (c >= '\u20D0' && c <= '\u20DC') ||
|
||||
c == '\u20E1' || (c >= '\u302A' && c <= '\u302F') || c == '\u3099' || c == '\u309A';
|
||||
}
|
||||
|
||||
private static boolean isExtender(char c) {
|
||||
return c == '\u00B7' || c == '\u02D0' || c == '\u02D1' || c == '\u0387' || c == '\u0640' || c == '\u0E46' ||
|
||||
c == '\u0EC6' || c == '\u3005' || (c >= '\u3031' && c <= '\u3035') || (c >= '\u309D' && c <= '\u309E') ||
|
||||
(c >= '\u30FC' && c <= '\u30FE');
|
||||
}
|
||||
|
||||
private static boolean isLetter(char c) {
|
||||
return isBaseChar(c) || isIdeographic(c);
|
||||
}
|
||||
|
||||
private static boolean isBaseChar(char c) {
|
||||
return (c >= '\u0041' && c <= '\u005A') || (c >= '\u0061' && c <= '\u007A') || (c >= '\u00C0' && c <= '\u00D6') ||
|
||||
(c >= '\u00D8' && c <= '\u00F6') || (c >= '\u00F8' && c <= '\u00FF') || (c >= '\u0100' && c <= '\u0131') ||
|
||||
(c >= '\u0134' && c <= '\u013E') || (c >= '\u0141' && c <= '\u0148') || (c >= '\u014A' && c <= '\u017E') ||
|
||||
(c >= '\u0180' && c <= '\u01C3') || (c >= '\u01CD' && c <= '\u01F0') || (c >= '\u01F4' && c <= '\u01F5') ||
|
||||
(c >= '\u01FA' && c <= '\u0217') || (c >= '\u0250' && c <= '\u02A8') || (c >= '\u02BB' && c <= '\u02C1') ||
|
||||
c == '\u0386' || (c >= '\u0388' && c <= '\u038A') || c == '\u038C' || (c >= '\u038E' && c <= '\u03A1') ||
|
||||
(c >= '\u03A3' && c <= '\u03CE') || (c >= '\u03D0' && c <= '\u03D6') || c == '\u03DA' || c == '\u03DC' || c == '\u03DE' ||
|
||||
c == '\u03E0' || (c >= '\u03E2' && c <= '\u03F3') || (c >= '\u0401' && c <= '\u040C') || (c >= '\u040E' && c <= '\u044F') ||
|
||||
(c >= '\u0451' && c <= '\u045C') || (c >= '\u045E' && c <= '\u0481') || (c >= '\u0490' && c <= '\u04C4') ||
|
||||
(c >= '\u04C7' && c <= '\u04C8') || (c >= '\u04CB' && c <= '\u04CC') || (c >= '\u04D0' && c <= '\u04EB') ||
|
||||
(c >= '\u04EE' && c <= '\u04F5') || (c >= '\u04F8' && c <= '\u04F9') || (c >= '\u0531' && c <= '\u0556') ||
|
||||
c == '\u0559' || (c >= '\u0561' && c <= '\u0586') || (c >= '\u05D0' && c <= '\u05EA') || (c >= '\u05F0' && c <= '\u05F2') ||
|
||||
(c >= '\u0621' && c <= '\u063A') || (c >= '\u0641' && c <= '\u064A') || (c >= '\u0671' && c <= '\u06B7') ||
|
||||
(c >= '\u06BA' && c <= '\u06BE') || (c >= '\u06C0' && c <= '\u06CE') || (c >= '\u06D0' && c <= '\u06D3') ||
|
||||
c == '\u06D5' || (c >= '\u06E5' && c <= '\u06E6') || (c >= '\u0905' && c <= '\u0939') || c == '\u093D' ||
|
||||
(c >= '\u0958' && c <= '\u0961') || (c >= '\u0985' && c <= '\u098C') || (c >= '\u098F' && c <= '\u0990') ||
|
||||
(c >= '\u0993' && c <= '\u09A8') || (c >= '\u09AA' && c <= '\u09B0') || c == '\u09B2' ||
|
||||
(c >= '\u09B6' && c <= '\u09B9') || (c >= '\u09DC' && c <= '\u09DD') || (c >= '\u09DF' && c <= '\u09E1') ||
|
||||
(c >= '\u09F0' && c <= '\u09F1') || (c >= '\u0A05' && c <= '\u0A0A') || (c >= '\u0A0F' && c <= '\u0A10') ||
|
||||
(c >= '\u0A13' && c <= '\u0A28') || (c >= '\u0A2A' && c <= '\u0A30') || (c >= '\u0A32' && c <= '\u0A33') ||
|
||||
(c >= '\u0A35' && c <= '\u0A36') || (c >= '\u0A38' && c <= '\u0A39') || (c >= '\u0A59' && c <= '\u0A5C') ||
|
||||
c == '\u0A5E' || (c >= '\u0A72' && c <= '\u0A74') || (c >= '\u0A85' && c <= '\u0A8B') || c == '\u0A8D' ||
|
||||
(c >= '\u0A8F' && c <= '\u0A91') || (c >= '\u0A93' && c <= '\u0AA8') || (c >= '\u0AAA' && c <= '\u0AB0') ||
|
||||
(c >= '\u0AB2' && c <= '\u0AB3') || (c >= '\u0AB5' && c <= '\u0AB9') || c == '\u0ABD' || c == '\u0AE0' ||
|
||||
(c >= '\u0B05' && c <= '\u0B0C') || (c >= '\u0B0F' && c <= '\u0B10') || (c >= '\u0B13' && c <= '\u0B28') ||
|
||||
(c >= '\u0B2A' && c <= '\u0B30') || (c >= '\u0B32' && c <= '\u0B33') || (c >= '\u0B36' && c <= '\u0B39') ||
|
||||
c == '\u0B3D' || (c >= '\u0B5C' && c <= '\u0B5D') || (c >= '\u0B5F' && c <= '\u0B61') ||
|
||||
(c >= '\u0B85' && c <= '\u0B8A') || (c >= '\u0B8E' && c <= '\u0B90') || (c >= '\u0B92' && c <= '\u0B95') ||
|
||||
(c >= '\u0B99' && c <= '\u0B9A') || c == '\u0B9C' || (c >= '\u0B9E' && c <= '\u0B9F') ||
|
||||
(c >= '\u0BA3' && c <= '\u0BA4') || (c >= '\u0BA8' && c <= '\u0BAA') || (c >= '\u0BAE' && c <= '\u0BB5') ||
|
||||
(c >= '\u0BB7' && c <= '\u0BB9') || (c >= '\u0C05' && c <= '\u0C0C') || (c >= '\u0C0E' && c <= '\u0C10') ||
|
||||
(c >= '\u0C12' && c <= '\u0C28') || (c >= '\u0C2A' && c <= '\u0C33') || (c >= '\u0C35' && c <= '\u0C39') ||
|
||||
(c >= '\u0C60' && c <= '\u0C61') || (c >= '\u0C85' && c <= '\u0C8C') || (c >= '\u0C8E' && c <= '\u0C90') ||
|
||||
(c >= '\u0C92' && c <= '\u0CA8') || (c >= '\u0CAA' && c <= '\u0CB3') || (c >= '\u0CB5' && c <= '\u0CB9') ||
|
||||
c == '\u0CDE' || (c >= '\u0CE0' && c <= '\u0CE1') || (c >= '\u0D05' && c <= '\u0D0C') ||
|
||||
(c >= '\u0D0E' && c <= '\u0D10') || (c >= '\u0D12' && c <= '\u0D28') || (c >= '\u0D2A' && c <= '\u0D39') ||
|
||||
(c >= '\u0D60' && c <= '\u0D61') || (c >= '\u0E01' && c <= '\u0E2E') || c == '\u0E30' ||
|
||||
(c >= '\u0E32' && c <= '\u0E33') || (c >= '\u0E40' && c <= '\u0E45') || (c >= '\u0E81' && c <= '\u0E82') ||
|
||||
c == '\u0E84' || (c >= '\u0E87' && c <= '\u0E88') || c == '\u0E8A' || c == '\u0E8D' || (c >= '\u0E94' && c <= '\u0E97') ||
|
||||
(c >= '\u0E99' && c <= '\u0E9F') || (c >= '\u0EA1' && c <= '\u0EA3') || c == '\u0EA5' || c == '\u0EA7' ||
|
||||
(c >= '\u0EAA' && c <= '\u0EAB') || (c >= '\u0EAD' && c <= '\u0EAE') || c == '\u0EB0' ||
|
||||
(c >= '\u0EB2' && c <= '\u0EB3') || c == '\u0EBD' || (c >= '\u0EC0' && c <= '\u0EC4') ||
|
||||
(c >= '\u0F40' && c <= '\u0F47') || (c >= '\u0F49' && c <= '\u0F69') || (c >= '\u10A0' && c <= '\u10C5') ||
|
||||
(c >= '\u10D0' && c <= '\u10F6') || c == '\u1100' || (c >= '\u1102' && c <= '\u1103') ||
|
||||
(c >= '\u1105' && c <= '\u1107') || c == '\u1109' || (c >= '\u110B' && c <= '\u110C') ||
|
||||
(c >= '\u110E' && c <= '\u1112') || c == '\u113C' || c == '\u113E' || c == '\u1140' || c == '\u114C' ||
|
||||
c == '\u114E' || c == '\u1150' || (c >= '\u1154' && c <= '\u1155') || c == '\u1159' ||
|
||||
(c >= '\u115F' && c <= '\u1161') || c == '\u1163' || c == '\u1165' || c == '\u1167' || c == '\u1169' ||
|
||||
(c >= '\u116D' && c <= '\u116E') || (c >= '\u1172' && c <= '\u1173') || c == '\u1175' ||
|
||||
c == '\u119E' || c == '\u11A8' || c == '\u11AB' || (c >= '\u11AE' && c <= '\u11AF') ||
|
||||
(c >= '\u11B7' && c <= '\u11B8') || c == '\u11BA' || (c >= '\u11BC' && c <= '\u11C2') ||
|
||||
c == '\u11EB' || c == '\u11F0' || c == '\u11F9' || (c >= '\u1E00' && c <= '\u1E9B') || (c >= '\u1EA0' && c <= '\u1EF9') ||
|
||||
(c >= '\u1F00' && c <= '\u1F15') || (c >= '\u1F18' && c <= '\u1F1D') || (c >= '\u1F20' && c <= '\u1F45') ||
|
||||
(c >= '\u1F48' && c <= '\u1F4D') || (c >= '\u1F50' && c <= '\u1F57') || c == '\u1F59' || c == '\u1F5B' || c == '\u1F5D' ||
|
||||
(c >= '\u1F5F' && c <= '\u1F7D') || (c >= '\u1F80' && c <= '\u1FB4') || (c >= '\u1FB6' && c <= '\u1FBC') ||
|
||||
c == '\u1FBE' || (c >= '\u1FC2' && c <= '\u1FC4') || (c >= '\u1FC6' && c <= '\u1FCC') ||
|
||||
(c >= '\u1FD0' && c <= '\u1FD3') || (c >= '\u1FD6' && c <= '\u1FDB') || (c >= '\u1FE0' && c <= '\u1FEC') ||
|
||||
(c >= '\u1FF2' && c <= '\u1FF4') || (c >= '\u1FF6' && c <= '\u1FFC') || c == '\u2126' ||
|
||||
(c >= '\u212A' && c <= '\u212B') || c == '\u212E' || (c >= '\u2180' && c <= '\u2182') ||
|
||||
(c >= '\u3041' && c <= '\u3094') || (c >= '\u30A1' && c <= '\u30FA') || (c >= '\u3105' && c <= '\u312C') ||
|
||||
(c >= '\uAC00' && c <= '\uD7A3');
|
||||
}
|
||||
|
||||
private static boolean isIdeographic(char c) {
|
||||
return (c >= '\u4E00' && c <= '\u9FA5') || c == '\u3007' || (c >= '\u3021' && c <= '\u3029');
|
||||
}
|
||||
|
||||
public static String determineEncoding(InputStream stream) throws IOException {
|
||||
stream.mark(20000);
|
||||
try {
|
||||
int b0 = stream.read();
|
||||
int b1 = stream.read();
|
||||
int b2 = stream.read();
|
||||
int b3 = stream.read();
|
||||
|
||||
if (b0 == 0xFE && b1 == 0xFF)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0xFF && b1 == 0xFE)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0xEF && b1 == 0xBB && b2 == 0xBF )
|
||||
return "UTF-8";
|
||||
else if (b0 == 0x00 && b1 == 0x3C && b2 == 0x00 && b3 == 0x3F)
|
||||
return "UTF-16BE";
|
||||
else if (b0 == 0x3C && b1 == 0x00 && b2 == 0x3F && b3 == 0x00)
|
||||
return "UTF-16LE";
|
||||
else if (b0 == 0x3C && b1 == 0x3F && b2 == 0x78 && b3 == 0x6D) {
|
||||
// UTF-8, ISO 646, ASCII, some part of ISO 8859, Shift-JIS, EUC, or any other 7-bit, 8-bit, or mixed-width encoding
|
||||
// which ensures that the characters of ASCII have their normal positions, width, and values; the actual encoding
|
||||
// declaration must be read to detect which of these applies, but since all of these encodings use the same bit patterns
|
||||
// for the relevant ASCII characters, the encoding declaration itself may be read reliably
|
||||
InputStreamReader rdr = new InputStreamReader(stream, "US-ASCII");
|
||||
String hdr = readFirstLine(rdr);
|
||||
return extractEncoding(hdr);
|
||||
} else
|
||||
return null;
|
||||
} finally {
|
||||
stream.reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static String extractEncoding(String hdr) {
|
||||
int i = hdr.indexOf("encoding=");
|
||||
if (i == -1)
|
||||
return null;
|
||||
hdr = hdr.substring(i+9);
|
||||
char sep = hdr.charAt(0);
|
||||
hdr = hdr.substring(1);
|
||||
i = hdr.indexOf(sep);
|
||||
if (i == -1)
|
||||
return null;
|
||||
return hdr.substring(0, i);
|
||||
}
|
||||
|
||||
private static String readFirstLine(InputStreamReader rdr) throws IOException {
|
||||
char[] buf = new char[1];
|
||||
StringBuffer bldr = new StringBuffer();
|
||||
rdr.read(buf);
|
||||
while (buf[0] != '>') {
|
||||
bldr.append(buf[0]);
|
||||
rdr.read(buf);
|
||||
}
|
||||
return bldr.toString();
|
||||
}
|
||||
|
||||
|
||||
public static boolean charSetImpliesAscii(String charset) {
|
||||
return charset.equals("ISO-8859-1") || charset.equals("US-ASCII");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts the raw characters to XML escapeUrlParam characters.
|
||||
*
|
||||
* @param rawContent
|
||||
* @param charset Null when charset is not known, so we assume it's unicode
|
||||
* @param isNoLines
|
||||
* @return escapeUrlParam string
|
||||
*/
|
||||
public static String escapeXML(String rawContent, String charset, boolean isNoLines) {
|
||||
if (rawContent == null)
|
||||
return "";
|
||||
else {
|
||||
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("&#x"+Integer.toHexString(ch).toUpperCase()+";");
|
||||
else if (isNoLines) {
|
||||
if (ch == '\r')
|
||||
sb.append("
");
|
||||
else if (ch != '\n')
|
||||
sb.append(ch);
|
||||
}
|
||||
else
|
||||
sb.append(ch);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static Element getFirstChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getFirstChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public static Element getNextSibling(Element e) {
|
||||
Node n = e.getNextSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getNextSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static void getNamedChildren(Element e, String name, List<Element> set) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null) {
|
||||
if (name.equals(c.getLocalName()) || name.equals(c.getNodeName()) )
|
||||
set.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(Element r) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
Node n = r.getFirstChild();
|
||||
boolean ws = false;
|
||||
while (n != null) {
|
||||
if (n.getNodeType() == Node.TEXT_NODE) {
|
||||
String t = n.getTextContent().trim();
|
||||
if (Utilities.noString(t))
|
||||
ws = true;
|
||||
else {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(t);
|
||||
}
|
||||
}
|
||||
if (n.getNodeType() == Node.ELEMENT_NODE) {
|
||||
if (ws)
|
||||
s.append(" ");
|
||||
ws = false;
|
||||
s.append(htmlToXmlEscapedPlainText((Element) n));
|
||||
if (r.getNodeName().equals("br") || r.getNodeName().equals("p"))
|
||||
s.append("\r\n");
|
||||
}
|
||||
n = n.getNextSibling();
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
public static String htmlToXmlEscapedPlainText(String definition) throws ParserConfigurationException, SAXException, IOException {
|
||||
return htmlToXmlEscapedPlainText(parseToDom("<div>"+definition+"</div>").getDocumentElement());
|
||||
}
|
||||
|
||||
public static String elementToString(Element el) {
|
||||
if (el == null)
|
||||
return "";
|
||||
Document document = el.getOwnerDocument();
|
||||
DOMImplementationLS domImplLS = (DOMImplementationLS) document
|
||||
.getImplementation();
|
||||
LSSerializer serializer = domImplLS.createLSSerializer();
|
||||
return serializer.writeToString(el);
|
||||
}
|
||||
|
||||
public static String getNamedChildValue(Element element, String name) {
|
||||
Element e = getNamedChild(element, name);
|
||||
return e == null ? null : e.getAttribute("value");
|
||||
}
|
||||
|
||||
public static void setNamedChildValue(Element element, String name, String value) throws FHIRException {
|
||||
Element e = getNamedChild(element, name);
|
||||
if (e == null)
|
||||
throw new FHIRException("unable to find element "+name);
|
||||
e.setAttribute("value", value);
|
||||
}
|
||||
|
||||
|
||||
public static void getNamedChildrenWithWildcard(Element focus, String name, List<Element> children) {
|
||||
Element c = getFirstChild(focus);
|
||||
while (c != null) {
|
||||
String n = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
|
||||
if (name.equals(n) || (name.endsWith("[x]") && n.startsWith(name.substring(0, name.length()-3))))
|
||||
children.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static void getNamedChildrenWithTails(Element focus, String name, List<Element> children, Set<String> typeTails) {
|
||||
Element c = getFirstChild(focus);
|
||||
while (c != null) {
|
||||
String n = c.getLocalName() != null ? c.getLocalName() : c.getNodeName();
|
||||
if (n.equals(name) || (!n.equals("responseCode") && (n.startsWith(name) && typeTails.contains(n.substring(name.length())))))
|
||||
children.add(c);
|
||||
c = getNextSibling(c);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean hasNamedChild(Element e, String name) {
|
||||
Element c = getFirstChild(e);
|
||||
while (c != null && !name.equals(c.getLocalName()) && !name.equals(c.getNodeName()))
|
||||
c = getNextSibling(c);
|
||||
return c != null;
|
||||
}
|
||||
|
||||
public static Document parseToDom(String content) throws ParserConfigurationException, SAXException, IOException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(false);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.parse(new ByteArrayInputStream(content.getBytes()));
|
||||
}
|
||||
|
||||
public static Document parseFileToDom(String filename) throws ParserConfigurationException, SAXException, IOException {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
factory.setNamespaceAware(false);
|
||||
DocumentBuilder builder = factory.newDocumentBuilder();
|
||||
return builder.parse(new FileInputStream(filename));
|
||||
}
|
||||
|
||||
public static Element getLastChild(Element e) {
|
||||
if (e == null)
|
||||
return null;
|
||||
Node n = e.getLastChild();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static Element getPrevSibling(Element e) {
|
||||
Node n = e.getPreviousSibling();
|
||||
while (n != null && n.getNodeType() != Node.ELEMENT_NODE)
|
||||
n = n.getPreviousSibling();
|
||||
return (Element) n;
|
||||
}
|
||||
|
||||
public static String getNamedChildAttribute(Element element, String name, String aname) {
|
||||
Element e = getNamedChild(element, name);
|
||||
return e == null ? null : e.getAttribute(aname);
|
||||
}
|
||||
|
||||
public static void writeDomToFile(Document doc, String filename) throws TransformerException {
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
DOMSource source = new DOMSource(doc);
|
||||
StreamResult streamResult = new StreamResult(new File(filename));
|
||||
transformer.transform(source, streamResult);
|
||||
}
|
||||
|
||||
public static String getXsiType(org.w3c.dom.Element element) {
|
||||
Attr a = element.getAttributeNodeNS("http://www.w3.org/2001/XMLSchema-instance", "type");
|
||||
return (a == null ? null : a.getTextContent());
|
||||
|
||||
}
|
||||
|
||||
public static String getDirectText(org.w3c.dom.Element node) {
|
||||
Node n = node.getFirstChild();
|
||||
StringBuilder b = new StringBuilder();
|
||||
while (n != null) {
|
||||
if (n.getNodeType() == Node.TEXT_NODE)
|
||||
b.append(n.getTextContent());
|
||||
n = n.getNextSibling();
|
||||
}
|
||||
return b.toString().trim();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ public class GraphQLDstu3ProviderTest {
|
|||
@Ignore
|
||||
public void testGraphInstance() throws Exception {
|
||||
String query = "{name{family,given}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -84,7 +84,7 @@ public class GraphQLDstu3ProviderTest {
|
|||
@Ignore
|
||||
public void testGraphInstanceWithFhirpath() throws Exception {
|
||||
String query = "{name(fhirpath:\"family.exists()\"){text,given,family}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/123/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -109,7 +109,7 @@ public class GraphQLDstu3ProviderTest {
|
|||
@org.junit.Ignore
|
||||
public void testGraphSystemInstance() throws Exception {
|
||||
String query = "{Patient(id:123){id,name{given,family}}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
@ -138,7 +138,7 @@ public class GraphQLDstu3ProviderTest {
|
|||
@Ignore
|
||||
public void testGraphSystemList() throws Exception {
|
||||
String query = "{PatientList(name:\"pet\"){name{family,given}}}";
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escape(query));
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/$graphql?query=" + UrlUtil.escapeUrlParam(query));
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
try {
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent(), StandardCharsets.UTF_8);
|
||||
|
|
|
@ -11,6 +11,12 @@
|
|||
Fix a crash in JPA server when performing a recursive
|
||||
<![CDATA[<code>_include</code>]]> which doesn't actually find any matches.
|
||||
</action>
|
||||
<action type="fix" issue="796">
|
||||
When encoding URL parameter values, HAPI FHIR would incorrectly escape
|
||||
a space (" ") as a plus ("+") insetad of as "%20" as required by
|
||||
RFC 3986. This affects client calls, as well as URLs generated by
|
||||
the server (e.g. REST HOOK calls). Thanks to James Daily for reporting!
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.1.0" date="2017-11-23">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue