Performance improvements
This commit is contained in:
parent
794db6a141
commit
bfd6329303
|
@ -6,7 +6,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.validation.ResourceValidator;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
import ca.uhn.fhir.validation.ValidationFailureException;
|
||||
|
||||
public class ValidatorExamples {
|
||||
|
@ -24,7 +24,7 @@ public class ValidatorExamples {
|
|||
p.addTelecom().setSystem(ContactSystemEnum.PHONE).setValue("416 123-4567");
|
||||
|
||||
// Request a validator and apply it
|
||||
ResourceValidator val = ctx.newValidator();
|
||||
FhirValidator val = ctx.newValidator();
|
||||
try {
|
||||
|
||||
val.validate(p);
|
||||
|
|
|
@ -608,7 +608,7 @@
|
|||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>findbugs-maven-plugin</artifactId>
|
||||
<version>2.5.3</version>
|
||||
<version>3.0.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
|
|
@ -118,6 +118,9 @@
|
|||
Resource of type "List" failed to parse from a bundle correctly. Thanks to David Hay of Orion Health
|
||||
for reporting!
|
||||
</action>
|
||||
<action type="fix">
|
||||
QuantityParam correctly encodes approximate (~) prefix to values
|
||||
</action>
|
||||
</release>
|
||||
<release version="0.5" date="2014-Jul-30">
|
||||
<action type="add">
|
||||
|
|
|
@ -45,7 +45,7 @@ import ca.uhn.fhir.rest.client.RestfulClientFactory;
|
|||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
import ca.uhn.fhir.validation.ResourceValidator;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
|
||||
/**
|
||||
* The FHIR context is the central starting point for the use of the HAPI FHIR API. It should be created once, and then
|
||||
|
@ -251,8 +251,8 @@ public class FhirContext {
|
|||
return new FhirTerser(this);
|
||||
}
|
||||
|
||||
public ResourceValidator newValidator() {
|
||||
return new ResourceValidator(this);
|
||||
public FhirValidator newValidator() {
|
||||
return new FhirValidator(this);
|
||||
}
|
||||
|
||||
public ViewGenerator newViewGenerator() {
|
||||
|
|
|
@ -703,6 +703,9 @@ class ParserState<T> {
|
|||
myStack = theState;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theData The string value
|
||||
*/
|
||||
public void string(String theData) {
|
||||
// ignore by default
|
||||
}
|
||||
|
@ -711,6 +714,9 @@ class ParserState<T> {
|
|||
// allow an implementor to override
|
||||
}
|
||||
|
||||
/**
|
||||
* @param theNextEvent The XML event
|
||||
*/
|
||||
public void xmlEvent(XMLEvent theNextEvent) {
|
||||
// ignore
|
||||
}
|
||||
|
@ -1198,7 +1204,7 @@ class ParserState<T> {
|
|||
BaseRuntimeElementDefinition<?> definition;
|
||||
if (myResourceType == null) {
|
||||
definition = myContext.getResourceDefinition(theLocalPart);
|
||||
if (!(definition instanceof RuntimeResourceDefinition)) {
|
||||
if ((definition == null)) {
|
||||
throw new DataFormatException("Element '" + theLocalPart + "' is not a resource, expected a resource at this position");
|
||||
}
|
||||
} else {
|
||||
|
@ -1258,16 +1264,16 @@ class ParserState<T> {
|
|||
}
|
||||
|
||||
myContext.newTerser().visit(myInstance, new IModelVisitor() {
|
||||
|
||||
|
||||
@Override
|
||||
public void acceptUndeclaredExtension(ISupportsUndeclaredExtensions theContainingElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition, ExtensionDt theNextExt) {
|
||||
acceptElement(theNextExt.getValue(), null, null);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void acceptElement(IElement theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||
if (theElement instanceof ResourceReferenceDt) {
|
||||
ResourceReferenceDt nextRef = (ResourceReferenceDt)theElement;
|
||||
ResourceReferenceDt nextRef = (ResourceReferenceDt) theElement;
|
||||
String ref = nextRef.getReference().getValue();
|
||||
if (isNotBlank(ref)) {
|
||||
if (ref.startsWith("#")) {
|
||||
|
@ -1282,7 +1288,7 @@ class ParserState<T> {
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -948,7 +948,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
|
||||
}
|
||||
|
||||
private class SortInternal implements ISort {
|
||||
private static class SortInternal implements ISort {
|
||||
|
||||
private SearchInternal myFor;
|
||||
private String myParamName;
|
||||
|
|
|
@ -22,7 +22,7 @@ package ca.uhn.fhir.rest.method;
|
|||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
@ -30,36 +30,36 @@ import ca.uhn.fhir.rest.param.CompositeParam;
|
|||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
|
||||
class BaseBinder<T> {
|
||||
private Class<? extends IQueryParameterType>[] myCompositeTypes;
|
||||
private List<Class<? extends IQueryParameterType>> myCompositeTypes;
|
||||
private Constructor<? extends T> myConstructor;
|
||||
private final Class<? extends T> myType;
|
||||
|
||||
public BaseBinder(Class<? extends T> theType, Class<? extends IQueryParameterType>[] theCompositeTypes) {
|
||||
public BaseBinder(Class<? extends T> theType, List<Class<? extends IQueryParameterType>> theCompositeTypes) {
|
||||
myType = theType;
|
||||
myCompositeTypes = theCompositeTypes;
|
||||
|
||||
if (myType.equals(CompositeParam.class)) {
|
||||
if (myCompositeTypes.length != 2) {
|
||||
throw new ConfigurationException("Search parameter of type " + myType.getName() + " must have 2 composite types declared in parameter annotation, found " + theCompositeTypes.length);
|
||||
if (myCompositeTypes.size() != 2) {
|
||||
throw new ConfigurationException("Search parameter of type " + myType.getName() + " must have 2 composite types declared in parameter annotation, found " + theCompositeTypes.size());
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Class<?>[] types = new Class<?>[myCompositeTypes.length];
|
||||
for (int i = 0; i < myCompositeTypes.length; i++) {
|
||||
types[i] = myCompositeTypes[i].getClass();
|
||||
Class<?>[] types = new Class<?>[myCompositeTypes.size()];
|
||||
for (int i = 0; i < myCompositeTypes.size(); i++) {
|
||||
types[i] = myCompositeTypes.get(i).getClass();
|
||||
}
|
||||
myConstructor = myType.getConstructor(types);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new ConfigurationException("Query parameter type " + theType.getName() + " has no constructor with types " + Arrays.asList(theCompositeTypes));
|
||||
throw new ConfigurationException("Query parameter type " + theType.getName() + " has no constructor with types " + theCompositeTypes);
|
||||
}
|
||||
}
|
||||
|
||||
public T newInstance() {
|
||||
try {
|
||||
final Object[] args = new Object[myCompositeTypes.length];
|
||||
for (int i = 0; i < myCompositeTypes.length;i++) {
|
||||
args[i] = myCompositeTypes[i];//.newInstance();
|
||||
final Object[] args = new Object[myCompositeTypes.size()];
|
||||
for (int i = 0; i < myCompositeTypes.size();i++) {
|
||||
args[i] = myCompositeTypes.get(i);//.newInstance();
|
||||
}
|
||||
|
||||
T dt = myConstructor.newInstance(args);
|
||||
|
|
|
@ -163,7 +163,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
throw new InternalErrorException("Method " + getMethod().getName() + " in type " + getMethod().getDeclaringClass().getCanonicalName()
|
||||
+ " returned null, which is not allowed for create operation");
|
||||
}
|
||||
if (response.getCreated() == null || response.getCreated() == Boolean.TRUE) {
|
||||
if (response.getCreated() == null || Boolean.TRUE.equals(response.getCreated())) {
|
||||
servletResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||
} else {
|
||||
servletResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
||||
|
@ -172,7 +172,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
break;
|
||||
|
||||
case UPDATE:
|
||||
if (response.getCreated() == null || response.getCreated() == Boolean.FALSE) {
|
||||
if (response.getCreated() == null || Boolean.FALSE.equals(response.getCreated())) {
|
||||
servletResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
||||
} else {
|
||||
servletResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
public enum OtherOperationTypeEnum {
|
||||
|
||||
METADATA("metadata"),
|
||||
|
|
|
@ -31,7 +31,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
|
||||
final class QueryParameterAndBinder extends BaseBinder<IQueryParameterAnd<?>> implements IParamBinder {
|
||||
|
||||
QueryParameterAndBinder(Class<? extends IQueryParameterAnd<?>> theType, Class<? extends IQueryParameterType>[] theCompositeTypes) {
|
||||
QueryParameterAndBinder(Class<? extends IQueryParameterAnd<?>> theType, List<Class<? extends IQueryParameterType>> theCompositeTypes) {
|
||||
super(theType, theCompositeTypes);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
|
||||
final class QueryParameterOrBinder extends BaseBinder<IQueryParameterOr<?>> implements IParamBinder {
|
||||
|
||||
QueryParameterOrBinder(Class<? extends IQueryParameterOr<?>> theType, Class<? extends IQueryParameterType>[] theCompositeTypes) {
|
||||
QueryParameterOrBinder(Class<? extends IQueryParameterOr<?>> theType, List<Class<? extends IQueryParameterType>> theCompositeTypes) {
|
||||
super(theType, theCompositeTypes);
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
|||
|
||||
final class QueryParameterTypeBinder extends BaseBinder<IQueryParameterType> implements IParamBinder {
|
||||
|
||||
QueryParameterTypeBinder(Class<? extends IQueryParameterType> theType, Class<? extends IQueryParameterType>[] theCompositeTypes) {
|
||||
QueryParameterTypeBinder(Class<? extends IQueryParameterType> theType, List<Class<? extends IQueryParameterType>> theCompositeTypes) {
|
||||
super(theType, theCompositeTypes);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
||||
|
|
|
@ -21,7 +21,9 @@ package ca.uhn.fhir.rest.method;
|
|||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -105,8 +107,8 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
ourParamTypes.put(CompositeOrListParam.class, SearchParamTypeEnum.COMPOSITE);
|
||||
ourParamTypes.put(CompositeAndListParam.class, SearchParamTypeEnum.COMPOSITE);
|
||||
}
|
||||
private Class<? extends IQueryParameterType>[] myCompositeTypes;
|
||||
private Class<? extends IResource>[] myDeclaredTypes;
|
||||
private List<Class<? extends IQueryParameterType>> myCompositeTypes;
|
||||
private List<Class<? extends IResource>> myDeclaredTypes;
|
||||
private String myDescription;
|
||||
private String myName;
|
||||
private IParamBinder myParamBinder;
|
||||
|
@ -140,8 +142,8 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public Class<? extends IResource>[] getDeclaredTypes() {
|
||||
return myDeclaredTypes;
|
||||
public List<Class<? extends IResource>> getDeclaredTypes() {
|
||||
return Collections.unmodifiableList(myDeclaredTypes);
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
|
@ -188,11 +190,11 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
}
|
||||
|
||||
public void setCompositeTypes(Class<? extends IQueryParameterType>[] theCompositeTypes) {
|
||||
myCompositeTypes = theCompositeTypes;
|
||||
myCompositeTypes = Arrays.asList(theCompositeTypes);
|
||||
}
|
||||
|
||||
public void setDeclaredTypes(Class<? extends IResource>[] theTypes) {
|
||||
myDeclaredTypes = theTypes;
|
||||
myDeclaredTypes = Arrays.asList(theTypes);
|
||||
}
|
||||
|
||||
public void setDescription(String theDescription) {
|
||||
|
|
|
@ -184,7 +184,7 @@ public class ParameterUtil {
|
|||
*/
|
||||
public static String escape(String theValue) {
|
||||
if (theValue == null) {
|
||||
return theValue;
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ package ca.uhn.fhir.rest.param;
|
|||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static ca.uhn.fhir.rest.param.ParameterUtil.*;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
|
@ -163,27 +164,27 @@ public class QuantityParam extends BaseParam implements IQueryParameterType {
|
|||
|
||||
@Override
|
||||
public String getValueAsQueryToken() {
|
||||
if (super.getMissing()!=null) {
|
||||
if (super.getMissing() != null) {
|
||||
return super.getValueAsQueryToken();
|
||||
}
|
||||
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
if (myQuantity.getComparator() != null) {
|
||||
b.append(ParameterUtil.escape(myQuantity.getComparator().getValue()));
|
||||
} else if (myApproximate) {
|
||||
if (myApproximate) {
|
||||
b.append('~');
|
||||
} else {
|
||||
b.append(defaultString(escape(myQuantity.getComparator().getValue())));
|
||||
}
|
||||
|
||||
if (!myQuantity.getValue().isEmpty()) {
|
||||
b.append(ParameterUtil.escape(myQuantity.getValue().getValueAsString()));
|
||||
b.append(defaultString(escape(myQuantity.getValue().getValueAsString())));
|
||||
}
|
||||
b.append('|');
|
||||
if (!myQuantity.getSystem().isEmpty()) {
|
||||
b.append(ParameterUtil.escape(myQuantity.getSystem().getValueAsString()));
|
||||
b.append(defaultString(escape(myQuantity.getSystem().getValueAsString())));
|
||||
}
|
||||
b.append('|');
|
||||
if (!myQuantity.getUnits().isEmpty()) {
|
||||
b.append(ParameterUtil.escape(myQuantity.getUnits().getValueAsString()));
|
||||
b.append(defaultString(escape(myQuantity.getUnits().getValueAsString())));
|
||||
}
|
||||
|
||||
return b.toString();
|
||||
|
@ -195,7 +196,9 @@ public class QuantityParam extends BaseParam implements IQueryParameterType {
|
|||
|
||||
public void setApproximate(boolean theApproximate) {
|
||||
myApproximate = theApproximate;
|
||||
myQuantity.setComparator((QuantityCompararatorEnum) null);
|
||||
if (theApproximate) {
|
||||
myQuantity.setComparator((QuantityCompararatorEnum) null);
|
||||
}
|
||||
}
|
||||
|
||||
public QuantityParam setComparator(QuantityCompararatorEnum theComparator) {
|
||||
|
@ -254,14 +257,14 @@ public class QuantityParam extends BaseParam implements IQueryParameterType {
|
|||
clear();
|
||||
|
||||
super.setValueAsQueryToken(theQualifier, theValue);
|
||||
if (getMissing()!=null) {
|
||||
if (getMissing() != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (theValue == null) {
|
||||
return;
|
||||
}
|
||||
List<String> parts = ParameterUtil.splitParameterString(theValue, true);
|
||||
List<String> parts = ParameterUtil.splitParameterString(theValue, '|', true);
|
||||
|
||||
if (parts.size() > 0 && StringUtils.isNotBlank(parts.get(0))) {
|
||||
if (parts.get(0).startsWith("~")) {
|
||||
|
@ -273,7 +276,8 @@ public class QuantityParam extends BaseParam implements IQueryParameterType {
|
|||
myQuantity.setValue(new BigDecimal(parts.get(0).substring(2)));
|
||||
} else if (parts.get(0).startsWith("<")) {
|
||||
myQuantity.setComparator(QuantityCompararatorEnum.LESSTHAN);
|
||||
myQuantity.setValue(new BigDecimal(parts.get(0).substring(1)));
|
||||
String valStr = parts.get(0).substring(1);
|
||||
myQuantity.setValue(new BigDecimal(valStr));
|
||||
} else if (parts.get(0).startsWith(">=")) {
|
||||
myQuantity.setComparator(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS);
|
||||
myQuantity.setValue(new BigDecimal(parts.get(0).substring(2)));
|
||||
|
@ -300,7 +304,7 @@ public class QuantityParam extends BaseParam implements IQueryParameterType {
|
|||
b.append("value", myQuantity.getValue().getValueAsString());
|
||||
b.append("system", myQuantity.getSystem().getValueAsString());
|
||||
b.append("units", myQuantity.getUnits().getValueAsString());
|
||||
if (getMissing()!=null) {
|
||||
if (getMissing() != null) {
|
||||
b.append("missing", getMissing());
|
||||
}
|
||||
return b.toString();
|
||||
|
|
|
@ -41,4 +41,4 @@ enum AddProfileTagEnum {
|
|||
* it is an instance of a class that extends a built in type, but adds or constrains it)
|
||||
*/
|
||||
ONLY_FOR_CUSTOM
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,12 +54,12 @@ public class FifoMemoryPagingProvider implements IPagingProvider {
|
|||
return myBundleProviders.get(theId);
|
||||
}
|
||||
|
||||
public synchronized void setDefaultPageSize(int theDefaultPageSize) {
|
||||
public void setDefaultPageSize(int theDefaultPageSize) {
|
||||
Validate.isTrue(theDefaultPageSize > 0, "size must be greater than 0");
|
||||
myDefaultPageSize = theDefaultPageSize;
|
||||
}
|
||||
|
||||
public synchronized void setMaximumPageSize(int theMaximumPageSize) {
|
||||
public void setMaximumPageSize(int theMaximumPageSize) {
|
||||
Validate.isTrue(theMaximumPageSize > 0, "size must be greater than 0");
|
||||
myMaximumPageSize = theMaximumPageSize;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.rest.server.interceptor;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.rest.server.interceptor;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.Map.Entry;
|
||||
|
@ -90,7 +110,7 @@ public class LoggingInterceptor extends InterceptorAdapter {
|
|||
myMessageFormat = theMessageFormat;
|
||||
}
|
||||
|
||||
private final class MyLookup extends StrLookup<String> {
|
||||
private static final class MyLookup extends StrLookup<String> {
|
||||
private final HttpServletRequest myRequest;
|
||||
private final RequestDetails myRequestDetails;
|
||||
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
package ca.uhn.fhir.rest.server.interceptor;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.rest.method.RequestDetails;
|
||||
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
|
||||
public class ResponseValidatingInterceptor extends InterceptorAdapter {
|
||||
|
||||
private FhirValidator myValidator;
|
||||
|
||||
/**
|
||||
* Returns the validator used ny this interceptor
|
||||
*/
|
||||
public FhirValidator getValidator() {
|
||||
return myValidator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the validator instance to use. Must not be null.
|
||||
*/
|
||||
public void setValidator(FhirValidator theValidator) {
|
||||
Validate.notNull(theValidator, "Validator must not be null");
|
||||
myValidator = theValidator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, TagList theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, Bundle theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean outgoingResponse(RequestDetails theRequestDetails, IResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -145,11 +145,11 @@ public class FhirTerser {
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public void acceptElement(IElement theElement, BaseRuntimeChildDefinition theChildDefinition, BaseRuntimeElementDefinition<?> theDefinition) {
|
||||
if (theElement.isEmpty()) {
|
||||
if (theElement == null || theElement.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (theElement != null && theType.isAssignableFrom(theElement.getClass())) {
|
||||
if (theType.isAssignableFrom(theElement.getClass())) {
|
||||
retVal.add((T) theElement);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
@ -18,18 +38,18 @@ import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
|||
* To obtain a resource validator, call {@link FhirContext#newValidator()}
|
||||
* </p>
|
||||
*/
|
||||
public class ResourceValidator {
|
||||
public class FhirValidator {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ResourceValidator.class);
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirValidator.class);
|
||||
|
||||
private FhirContext myContext;
|
||||
private List<IValidator> myValidators = new ArrayList<IValidator>();
|
||||
|
||||
/**
|
||||
* Constructor (this should not be called directly, but rather {@link FhirContext#newValidator()} should be called
|
||||
* to obtain an instance of {@link ResourceValidator})
|
||||
* to obtain an instance of {@link FhirValidator})
|
||||
*/
|
||||
public ResourceValidator(FhirContext theFhirContext) {
|
||||
public FhirValidator(FhirContext theFhirContext) {
|
||||
myContext = theFhirContext;
|
||||
setValidateBaseSchema(true);
|
||||
setValidateBaseSchematron(true);
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
|
||||
interface IValidator {
|
||||
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
public class Problem {
|
||||
|
||||
private String myDescription;
|
||||
|
|
|
@ -1,11 +1,33 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringReader;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.XMLConstants;
|
||||
import javax.xml.transform.Source;
|
||||
|
@ -21,74 +43,42 @@ import org.xml.sax.SAXException;
|
|||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome.Issue;
|
||||
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
|
||||
|
||||
class SchemaBaseValidator implements IValidator {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaBaseValidator.class);
|
||||
private Map<Class<? extends IResource>, Schema> myClassToSchema = new HashMap<Class<? extends IResource>, Schema>();
|
||||
|
||||
private Schema loadSchema(final IResource theResource, ValidationContext theValidationCtx) {
|
||||
Source baseSource = loadXml(theValidationCtx, theResource, null, "fhir-single.xsd");
|
||||
|
||||
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
schemaFactory.setResourceResolver(new LSResourceResolver() {
|
||||
@Override
|
||||
public LSInput resolveResource(String theType, String theNamespaceURI, String thePublicId, String theSystemId, String theBaseURI) {
|
||||
if ("xml.xsd".equals(theSystemId) || "xhtml1-strict.xsd".equals(theSystemId)) {
|
||||
LSInputImpl input = new LSInputImpl();
|
||||
input.setPublicId(thePublicId);
|
||||
input.setSystemId(theSystemId);
|
||||
input.setBaseURI(theBaseURI);
|
||||
String pathToBase = theResource.getClass().getPackage().getName().replace('.', '/') + '/' + theSystemId;
|
||||
InputStream baseIs = ResourceValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
||||
if (baseIs == null) {
|
||||
throw new ValidationFailureException("No FHIR-BASE schema found");
|
||||
}
|
||||
|
||||
ourLog.debug("Loading schema: {}", theSystemId);
|
||||
byte[] schema;
|
||||
try {
|
||||
schema = IOUtils.toByteArray(new InputStreamReader(baseIs, "UTF-8"));
|
||||
} catch (IOException e) {
|
||||
throw new ValidationFailureException("Failed to load schema " + theSystemId, e);
|
||||
}
|
||||
|
||||
// Account for BOM in UTF-8 text (this seems to choke Java 6's built in XML reader)
|
||||
int offset = 0;
|
||||
if (schema[0] == (byte) 0xEF && schema[1] == (byte) 0xBB && schema[2] == (byte) 0xBF) {
|
||||
offset = 3;
|
||||
}
|
||||
|
||||
try {
|
||||
input.setCharacterStream(new InputStreamReader(new ByteArrayInputStream(schema, offset, schema.length - offset), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ValidationFailureException("Failed to load schema " + theSystemId, e);
|
||||
}
|
||||
|
||||
return input;
|
||||
|
||||
}
|
||||
|
||||
throw new ConfigurationException("Unknown schema: " + theBaseURI);
|
||||
private Schema loadSchema(final Class<? extends IResource> theClass, ValidationContext theValidationCtx) {
|
||||
synchronized (myClassToSchema) {
|
||||
Schema schema = myClassToSchema.get(theClass);
|
||||
if (schema != null) {
|
||||
return schema;
|
||||
}
|
||||
});
|
||||
|
||||
Schema schema;
|
||||
try {
|
||||
schema = schemaFactory.newSchema(new Source[] { baseSource });
|
||||
} catch (SAXException e) {
|
||||
throw new ConfigurationException("Could not load/parse schema file", e);
|
||||
Source baseSource = loadXml(theValidationCtx, theClass, null, "fhir-single.xsd");
|
||||
|
||||
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
||||
schemaFactory.setResourceResolver(new MyResourceResolver(theClass));
|
||||
|
||||
try {
|
||||
schema = schemaFactory.newSchema(new Source[] { baseSource });
|
||||
} catch (SAXException e) {
|
||||
throw new ConfigurationException("Could not load/parse schema file", e);
|
||||
}
|
||||
myClassToSchema.put(theClass, schema);
|
||||
return schema;
|
||||
}
|
||||
return schema;
|
||||
}
|
||||
|
||||
private Source loadXml(ValidationContext theCtx, IResource theResource, String theSystemId, String theSchemaName) {
|
||||
Class<? extends IResource> baseResourceClass = theCtx.getFhirContext().getResourceDefinition(theResource).getBaseDefinition().getImplementingClass();
|
||||
private Source loadXml(ValidationContext theCtx, Class<? extends IResource> theClass, String theSystemId, String theSchemaName) {
|
||||
Class<? extends IResource> baseResourceClass = theCtx.getFhirContext().getResourceDefinition(theClass).getBaseDefinition().getImplementingClass();
|
||||
Package pack = baseResourceClass.getPackage();
|
||||
String pathToBase = pack.getName().replace('.', '/') + '/' + theSchemaName;
|
||||
InputStream baseIs = ResourceValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
||||
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
||||
if (baseIs == null) {
|
||||
throw new ValidationFailureException("No FHIR-BASE schema found");
|
||||
}
|
||||
|
@ -98,10 +88,12 @@ class SchemaBaseValidator implements IValidator {
|
|||
|
||||
@Override
|
||||
public void validate(ValidationContext theContext) {
|
||||
Schema schema = loadSchema(theContext.getOperationOutcome(), theContext);
|
||||
OperationOutcome outcome = theContext.getOperationOutcome();
|
||||
|
||||
Schema schema = loadSchema(outcome.getClass(), theContext);
|
||||
try {
|
||||
Validator validator = schema.newValidator();
|
||||
ErrorHandler handler = new ErrorHandler(theContext);
|
||||
MyErrorHandler handler = new MyErrorHandler(theContext);
|
||||
validator.setErrorHandler(handler);
|
||||
validator.validate(new StreamSource(new StringReader(theContext.getXmlEncodedResource())));
|
||||
} catch (SAXException e) {
|
||||
|
@ -112,11 +104,59 @@ class SchemaBaseValidator implements IValidator {
|
|||
}
|
||||
}
|
||||
|
||||
public class ErrorHandler implements org.xml.sax.ErrorHandler {
|
||||
private static final class MyResourceResolver implements LSResourceResolver {
|
||||
private final Class<? extends IResource> myClass;
|
||||
|
||||
private MyResourceResolver(Class<? extends IResource> theClass) {
|
||||
myClass = theClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LSInput resolveResource(String theType, String theNamespaceURI, String thePublicId, String theSystemId, String theBaseURI) {
|
||||
if ("xml.xsd".equals(theSystemId) || "xhtml1-strict.xsd".equals(theSystemId)) {
|
||||
LSInputImpl input = new LSInputImpl();
|
||||
input.setPublicId(thePublicId);
|
||||
input.setSystemId(theSystemId);
|
||||
input.setBaseURI(theBaseURI);
|
||||
String pathToBase = myClass.getPackage().getName().replace('.', '/') + '/' + theSystemId;
|
||||
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
||||
if (baseIs == null) {
|
||||
throw new ValidationFailureException("No FHIR-BASE schema found");
|
||||
}
|
||||
|
||||
ourLog.debug("Loading schema: {}", theSystemId);
|
||||
byte[] schema;
|
||||
try {
|
||||
schema = IOUtils.toByteArray(new InputStreamReader(baseIs, "UTF-8"));
|
||||
} catch (IOException e) {
|
||||
throw new ValidationFailureException("Failed to load schema " + theSystemId, e);
|
||||
}
|
||||
|
||||
// Account for BOM in UTF-8 text (this seems to choke Java 6's built in XML reader)
|
||||
int offset = 0;
|
||||
if (schema[0] == (byte) 0xEF && schema[1] == (byte) 0xBB && schema[2] == (byte) 0xBF) {
|
||||
offset = 3;
|
||||
}
|
||||
|
||||
try {
|
||||
input.setCharacterStream(new InputStreamReader(new ByteArrayInputStream(schema, offset, schema.length - offset), "UTF-8"));
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new ValidationFailureException("Failed to load schema " + theSystemId, e);
|
||||
}
|
||||
|
||||
return input;
|
||||
|
||||
}
|
||||
|
||||
throw new ConfigurationException("Unknown schema: " + theBaseURI);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyErrorHandler implements org.xml.sax.ErrorHandler {
|
||||
|
||||
private ValidationContext myContext;
|
||||
|
||||
public ErrorHandler(ValidationContext theContext) {
|
||||
public MyErrorHandler(ValidationContext theContext) {
|
||||
myContext = theContext;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,35 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.StringReader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.transform.stream.StreamSource;
|
||||
|
||||
import org.oclc.purl.dsdl.svrl.SchematronOutputType;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome.Issue;
|
||||
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
|
||||
|
@ -21,37 +42,28 @@ import com.phloc.schematron.xslt.SchematronResourceSCH;
|
|||
|
||||
public class SchematronBaseValidator implements IValidator {
|
||||
|
||||
private Map<Class<? extends IResource>, ISchematronResource> myClassToSchematron = new HashMap<Class<? extends IResource>, ISchematronResource>();
|
||||
|
||||
@Override
|
||||
public void validate(ValidationContext theCtx) {
|
||||
|
||||
IResource resource = theCtx.getResource();
|
||||
RuntimeResourceDefinition baseDef = theCtx.getFhirContext().getResourceDefinition(resource).getBaseDefinition();
|
||||
Class<? extends IResource> baseResourceClass = baseDef.getImplementingClass();
|
||||
Package pack = baseResourceClass.getPackage();
|
||||
|
||||
String pathToBase = pack.getName().replace('.', '/') + '/' + baseDef.getName().toLowerCase() + ".sch";
|
||||
InputStream baseIs = ResourceValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
||||
if (baseIs == null) {
|
||||
throw new ValidationFailureException("No schematron found for resource type: " + baseDef.getImplementingClass().getCanonicalName());
|
||||
}
|
||||
|
||||
ISchematronResource sch = SchematronResourceSCH.fromClassPath(pathToBase);
|
||||
ISchematronResource sch = getSchematron(theCtx);
|
||||
StreamSource source = new StreamSource(new StringReader(theCtx.getXmlEncodedResource()));
|
||||
|
||||
SchematronOutputType results = SchematronHelper.applySchematron(sch, source);
|
||||
if (results == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
IResourceErrorGroup errors = SchematronHelper.convertToResourceErrorGroup(results, baseDef.getName());
|
||||
|
||||
|
||||
IResourceErrorGroup errors = SchematronHelper.convertToResourceErrorGroup(results, theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName());
|
||||
|
||||
if (errors.getAllErrors().containsOnlySuccess()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
for (IResourceError next : errors.getAllErrors().getAllResourceErrors()) {
|
||||
Issue issue = theCtx.getOperationOutcome().addIssue();
|
||||
switch(next.getErrorLevel()) {
|
||||
switch (next.getErrorLevel()) {
|
||||
case ERROR:
|
||||
issue.setSeverity(IssueSeverityEnum.ERROR);
|
||||
break;
|
||||
|
@ -65,13 +77,37 @@ public class SchematronBaseValidator implements IValidator {
|
|||
case SUCCESS:
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
issue.getDetails().setValue(next.getAsString(Locale.getDefault()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private ISchematronResource getSchematron(ValidationContext theCtx) {
|
||||
Class<? extends IResource> resource = theCtx.getResource().getClass();
|
||||
Class<? extends IResource> baseResourceClass = theCtx.getFhirContext().getResourceDefinition(resource).getBaseDefinition().getImplementingClass();
|
||||
|
||||
return getSchematronAndCache(theCtx, baseResourceClass);
|
||||
}
|
||||
|
||||
private ISchematronResource getSchematronAndCache(ValidationContext theCtx, Class<? extends IResource> theClass) {
|
||||
synchronized (myClassToSchematron) {
|
||||
ISchematronResource retVal = myClassToSchematron.get(theClass);
|
||||
if (retVal != null) {
|
||||
return retVal;
|
||||
}
|
||||
Package pack = theClass.getPackage();
|
||||
|
||||
String pathToBase = pack.getName().replace('.', '/') + '/' + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName().toLowerCase() + ".sch";
|
||||
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
|
||||
if (baseIs == null) {
|
||||
throw new ValidationFailureException("No schematron found for resource type: " + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getImplementingClass().getCanonicalName());
|
||||
}
|
||||
|
||||
retVal = SchematronResourceSCH.fromClassPath(pathToBase);
|
||||
myClassToSchematron.put(theClass, retVal);
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
|
|
|
@ -1,5 +1,25 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
|
||||
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
|
||||
|
||||
public class QuantityParamTest {
|
||||
|
||||
@Test
|
||||
public void testFull() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "<5.4|http://unitsofmeasure.org|mg");
|
||||
assertEquals(QuantityCompararatorEnum.LESSTHAN,p.getComparator());
|
||||
assertEquals("5.4", p.getValue().getValueAsString());
|
||||
assertEquals("http://unitsofmeasure.org", p.getSystem().getValueAsString());
|
||||
assertEquals("mg", p.getUnits());
|
||||
assertEquals("<5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testApproximate() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "~5.4|http://unitsofmeasure.org|mg");
|
||||
assertEquals(null,p.getComparator());
|
||||
assertEquals(true, p.isApproximate());
|
||||
assertEquals("5.4", p.getValue().getValueAsString());
|
||||
assertEquals("http://unitsofmeasure.org", p.getSystem().getValueAsString());
|
||||
assertEquals("mg", p.getUnits());
|
||||
assertEquals("~5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoQualifier() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "5.4|http://unitsofmeasure.org|mg");
|
||||
assertEquals(null, p.getComparator());
|
||||
assertEquals("5.4", p.getValue().getValueAsString());
|
||||
assertEquals("http://unitsofmeasure.org", p.getSystem().getValueAsString());
|
||||
assertEquals("mg", p.getUnits());
|
||||
assertEquals("5.4|http://unitsofmeasure.org|mg", p.getValueAsQueryToken());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testNoUnits() {
|
||||
QuantityParam p = new QuantityParam();
|
||||
p.setValueAsQueryToken(null, "5.4");
|
||||
assertEquals(null, p.getComparator());
|
||||
assertEquals("5.4", p.getValue().getValueAsString());
|
||||
assertEquals(null, p.getSystem().getValueAsString());
|
||||
assertEquals(null, p.getUnits());
|
||||
assertEquals("5.4||", p.getValueAsQueryToken());
|
||||
}
|
||||
|
||||
}
|
|
@ -22,7 +22,7 @@ public class ResourceValidatorTest {
|
|||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml"));
|
||||
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res);
|
||||
|
||||
ResourceValidator val = ourCtx.newValidator();
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.setValidateBaseSchema(true);
|
||||
val.setValidateBaseSchematron(false);
|
||||
|
||||
|
@ -48,7 +48,7 @@ public class ResourceValidatorTest {
|
|||
String res = IOUtils.toString(getClass().getClassLoader().getResourceAsStream("patient-example-dicom.xml"));
|
||||
Patient p = ourCtx.newXmlParser().parseResource(Patient.class, res);
|
||||
|
||||
ResourceValidator val = ourCtx.newValidator();
|
||||
FhirValidator val = ourCtx.newValidator();
|
||||
val.setValidateBaseSchema(false);
|
||||
val.setValidateBaseSchematron(true);
|
||||
|
||||
|
|
Loading…
Reference in New Issue