diff --git a/hapi-fhir-base/.classpath b/hapi-fhir-base/.classpath index 550e3f2ae04..e1d24bcb895 100644 --- a/hapi-fhir-base/.classpath +++ b/hapi-fhir-base/.classpath @@ -28,9 +28,9 @@ - + - + diff --git a/hapi-fhir-base/.pom.xml.swp b/hapi-fhir-base/.pom.xml.swp new file mode 100644 index 00000000000..be35e502ff3 Binary files /dev/null and b/hapi-fhir-base/.pom.xml.swp differ diff --git a/hapi-fhir-base/.settings/org.eclipse.jdt.core.prefs b/hapi-fhir-base/.settings/org.eclipse.jdt.core.prefs index 1c96a5fe526..b664603cdf2 100644 --- a/hapi-fhir-base/.settings/org.eclipse.jdt.core.prefs +++ b/hapi-fhir-base/.settings/org.eclipse.jdt.core.prefs @@ -7,9 +7,9 @@ org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nul org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate @@ -97,4 +97,4 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=warning org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/hapi-fhir-base/.settings/org.eclipse.wst.common.project.facet.core.xml b/hapi-fhir-base/.settings/org.eclipse.wst.common.project.facet.core.xml index 5c9bd7532ab..f4bf050d007 100644 --- a/hapi-fhir-base/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/hapi-fhir-base/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,5 +1,5 @@ - + diff --git a/hapi-fhir-base/pom.xml b/hapi-fhir-base/pom.xml index e22ca1503d5..b3ff987be3c 100644 --- a/hapi-fhir-base/pom.xml +++ b/hapi-fhir-base/pom.xml @@ -203,6 +203,11 @@ hapi-fhir-structures-dstu 0.9-SNAPSHOT + + org.slf4j + slf4j-android + ${slf4j_version} + @@ -225,10 +230,13 @@ javax.json:javax.json-api --> ca.uhn.hapi.fhir:hapi-fhir-structures-dstu + ca.uhn.hapi.fhir:hapi-fhir-structures-dstu org.glassfish:javax.json org.codehaus.woodstox:woodstox-core-asl javax.xml.stream:stax-api org.codehaus.woodstox:stax2-api + org.slf4j:slf4j* + org.apache.commons:* diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java index 8dd8adb918a..deff67d9239 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/api/BundleEntry.java @@ -210,10 +210,21 @@ public class BundleEntry extends BaseBundle { return myTitle; } + /** + * @deprecated DSTU2 Note: As of DSTU2, bundle entries no longer have an updated time (this bit of metadata has been moved + * to the resource <meta/> element so it is redundant here). In preparation for DSTU2, it is recommended that you + * migrate code away from using this method and over to using resource metadata instead. + */ public InstantDt getUpdated() { if (myUpdated == null) { myUpdated = new InstantDt(); } + if (myUpdated.isEmpty() && myResource != null) { + InstantDt resourceUpdated = ResourceMetadataKeyEnum.UPDATED.get(myResource); + if (resourceUpdated!=null && !resourceUpdated.isEmpty()) { + return resourceUpdated; + } + } return myUpdated; } @@ -279,6 +290,11 @@ public class BundleEntry extends BaseBundle { myStatus = theStatus; } + /** + * @deprecated DSTU2 Note: As of DSTU2, bundle entries no longer have an updated time (this bit of metadata has been moved + * to the resource <meta/> element so it is redundant here). In preparation for DSTU2, it is recommended that you + * migrate code away from using this method and over to using resource metadata instead. + */ public void setUpdated(InstantDt theUpdated) { Validate.notNull(theUpdated, "Updated may not be null"); myUpdated = theUpdated; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java index 56a11a432d2..6be9dfe7fd2 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseMethodBinding.java @@ -34,7 +34,9 @@ import java.util.Set; import java.util.TreeSet; import ca.uhn.fhir.rest.annotation.*; + import org.apache.commons.io.IOUtils; +import org.hl7.fhir.instance.model.IBaseResource; import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; @@ -435,7 +437,7 @@ public abstract class BaseMethodBinding implements IClientResponseHandler if (theReturnType == null) { return false; } - if (!IResource.class.isAssignableFrom(theReturnType)) { + if (!IBaseResource.class.isAssignableFrom(theReturnType)) { return false; } return true; diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java index b84d89360ee..166c37640ce 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/BaseResourceReturningMethodBinding.java @@ -34,6 +34,8 @@ import java.util.Set; import javax.servlet.http.HttpServletResponse; +import org.hl7.fhir.instance.model.IBaseResource; + import ca.uhn.fhir.context.ConfigurationException; import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.model.api.Bundle; @@ -90,7 +92,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding) theMethod.getGenericReturnType())) { throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' should return a Conformance resource class, returns: " + theMethod.getReturnType()); } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java index 119a169aae9..e3c6315245f 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/method/ReadMethodBinding.java @@ -222,7 +222,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem } public static HttpGetClientInvocation createAbsoluteReadInvocation(IdDt theId) { - return new HttpGetClientInvocation(theId.getValue()); + return new HttpGetClientInvocation(theId.toVersionless().getValue()); } public static HttpGetClientInvocation createAbsoluteVReadInvocation(IdDt theId) { diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java index 75714e824cf..b216e9a0b4d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/RestfulServer.java @@ -41,6 +41,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException; import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException; import ca.uhn.fhir.rest.server.exceptions.NotModifiedException; import ca.uhn.fhir.rest.server.interceptor.IServerInterceptor; +import ca.uhn.fhir.util.ReflectionUtil; import ca.uhn.fhir.util.VersionUtil; import org.apache.commons.lang3.StringUtils; @@ -196,7 +197,7 @@ public class RestfulServer extends HttpServlet { private int findResourceMethods(Object theProvider, Class clazz) throws ConfigurationException { int count = 0; - for (Method m : clazz.getDeclaredMethods()) { + for (Method m : ReflectionUtil.getDeclaredMethods(clazz)) { BaseMethodBinding foundMethodBinding = BaseMethodBinding.bindMethod(m, myFhirContext, theProvider); if (foundMethodBinding == null) { continue; @@ -263,7 +264,7 @@ public class RestfulServer extends HttpServlet { findSystemMethods(theSystemProvider, supertype); } - for (Method m : clazz.getDeclaredMethods()) { + for (Method m : ReflectionUtil.getDeclaredMethods(clazz)) { if (Modifier.isPublic(m.getModifiers())) { ourLog.debug("Scanning public method: {}#{}", theSystemProvider.getClass(), m.getName()); @@ -797,7 +798,7 @@ public class RestfulServer extends HttpServlet { } private void invokeDestroy(Object theProvider, Class clazz) { - for (Method m : clazz.getDeclaredMethods()) { + for (Method m : ReflectionUtil.getDeclaredMethods(clazz)) { Destroy destroy = m.getAnnotation(Destroy.class); if (destroy != null) { try { @@ -1392,7 +1393,7 @@ public class RestfulServer extends HttpServlet { if (theServer.getETagSupport() == ETagSupportEnum.ENABLED) { if (theResource.getId().hasVersionIdPart()) { - theHttpResponse.addHeader(Constants.HEADER_ETAG, '"' + theResource.getId().getVersionIdPart() + '"'); + theHttpResponse.addHeader(Constants.HEADER_ETAG, "W/\"" + theResource.getId().getVersionIdPart() + '"'); } } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java index cad97b25091..0a8ccbdaf6d 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/util/ReflectionUtil.java @@ -26,6 +26,8 @@ import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.lang.reflect.WildcardType; +import java.util.HashSet; +import java.util.LinkedHashSet; public class ReflectionUtil { @@ -83,4 +85,19 @@ public class ReflectionUtil { return type; } + public static LinkedHashSet getDeclaredMethods(Class theClazz) { + LinkedHashSet retVal = new LinkedHashSet(); + for (Method next : theClazz.getDeclaredMethods()) { + try { + Method method = theClazz.getMethod(next.getName(), next.getParameterTypes()); + retVal.add(method); + } catch (NoSuchMethodException e) { + retVal.add(next); + } catch (SecurityException e) { + retVal.add(next); + } + } + return retVal; + } + } diff --git a/hapi-fhir-structures-dev/src/test/java/ca/uhn/fhir/rest/server/ETagServerTest.java b/hapi-fhir-structures-dev/src/test/java/ca/uhn/fhir/rest/server/ETagServerTest.java index 2423f7869cd..fe6bbd55814 100644 --- a/hapi-fhir-structures-dev/src/test/java/ca/uhn/fhir/rest/server/ETagServerTest.java +++ b/hapi-fhir-structures-dev/src/test/java/ca/uhn/fhir/rest/server/ETagServerTest.java @@ -69,7 +69,7 @@ public class ETagServerTest { Header cl = status.getFirstHeader(Constants.HEADER_ETAG_LC); assertNotNull(cl); - assertEquals("\"222\"", cl.getValue()); + assertEquals("W/\"222\"", cl.getValue()); } diff --git a/hapi-fhir-structures-dstu/.settings/org.eclipse.wst.common.project.facet.core.xml b/hapi-fhir-structures-dstu/.settings/org.eclipse.wst.common.project.facet.core.xml index 5c9bd7532ab..f4bf050d007 100644 --- a/hapi-fhir-structures-dstu/.settings/org.eclipse.wst.common.project.facet.core.xml +++ b/hapi-fhir-structures-dstu/.settings/org.eclipse.wst.common.project.facet.core.xml @@ -1,5 +1,5 @@ - + diff --git a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/provider/ServerConformanceProvider.java b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/provider/ServerConformanceProvider.java index 84ced6418b7..14a678a45d5 100644 --- a/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/provider/ServerConformanceProvider.java +++ b/hapi-fhir-structures-dstu/src/main/java/ca/uhn/fhir/rest/server/provider/ServerConformanceProvider.java @@ -97,6 +97,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider classes = ClassPath.from(Thread.currentThread().getContextClassLoader()).getTopLevelClasses(BaseServerResponseException.class.getPackage().getName()); @@ -35,8 +36,12 @@ public class ExceptionTest { if (next == UnclassifiedServerFailureException.class) { continue; } + if (next == ResourceVersionNotSpecifiedException.class) { + // This one is deprocated + continue; + } - assertTrue(BaseServerResponseException.isExceptionTypeRegistered(next)); + assertTrue("Type " + next + " is not registered", BaseServerResponseException.isExceptionTypeRegistered(next)); if (next == AuthenticationException.class) { continue; diff --git a/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java b/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java index b99671c1697..0980ac024c1 100644 --- a/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java +++ b/hapi-fhir-testpage-overlay/src/main/java/ca/uhn/fhir/to/Controller.java @@ -45,6 +45,7 @@ import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirVersionEnum; import ca.uhn.fhir.context.RuntimeResourceDefinition; import ca.uhn.fhir.model.api.Bundle; +import ca.uhn.fhir.model.api.BundleEntry; import ca.uhn.fhir.model.api.ExtensionDt; import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.Include; @@ -58,6 +59,7 @@ import ca.uhn.fhir.model.primitive.DateTimeDt; import ca.uhn.fhir.model.primitive.DecimalDt; import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.StringDt; +import ca.uhn.fhir.narrative.INarrativeGenerator; import ca.uhn.fhir.parser.DataFormatException; import ca.uhn.fhir.rest.client.GenericClient; import ca.uhn.fhir.rest.client.IClientInterceptor; @@ -85,7 +87,7 @@ public class Controller { private TesterConfig myConfig; private Map myContexts = new HashMap(); - + private List myFilterHeaders; @Autowired @@ -343,9 +345,9 @@ public class Controller { haveSearchParams = extractSearchParamsDstu1(conformance, resourceName, includes, sortParams, queries, haveSearchParams, queryIncludes); break; default: - throw new IllegalStateException("Unknown FHIR version: "+theRequest.getFhirVersion(myConfig)); + throw new IllegalStateException("Unknown FHIR version: " + theRequest.getFhirVersion(myConfig)); } - + theModel.put("includes", includes); theModel.put("queries", queries); theModel.put("haveSearchParams", haveSearchParams); @@ -366,7 +368,8 @@ public class Controller { return "resource"; } - private boolean extractSearchParamsDstu1(IResource theConformance, String resourceName, TreeSet includes, TreeSet sortParams, List queries, boolean haveSearchParams, List> queryIncludes) { + private boolean extractSearchParamsDstu1(IResource theConformance, String resourceName, TreeSet includes, TreeSet sortParams, List queries, boolean haveSearchParams, + List> queryIncludes) { Conformance conformance = (Conformance) theConformance; for (Rest nextRest : conformance.getRest()) { for (RestResource nextRes : nextRest.getResource()) { @@ -414,8 +417,9 @@ public class Controller { return haveSearchParams; } - private boolean extractSearchParamsDev(IResource theConformance, String resourceName, TreeSet includes, TreeSet sortParams, List queries, boolean haveSearchParams, List> queryIncludes) { - ca.uhn.fhir.model.dev.resource.Conformance conformance = (ca.uhn.fhir.model.dev.resource.Conformance)theConformance; + private boolean extractSearchParamsDev(IResource theConformance, String resourceName, TreeSet includes, TreeSet sortParams, List queries, boolean haveSearchParams, + List> queryIncludes) { + ca.uhn.fhir.model.dev.resource.Conformance conformance = (ca.uhn.fhir.model.dev.resource.Conformance) theConformance; for (ca.uhn.fhir.model.dev.resource.Conformance.Rest nextRest : conformance.getRest()) { for (ca.uhn.fhir.model.dev.resource.Conformance.RestResource nextRes : nextRest.getResource()) { if (nextRes.getTypeElement().getValue().equals(resourceName)) { @@ -456,7 +460,7 @@ public class Controller { IQuery query; if (isNotBlank(theReq.getParameter("resource"))) { try { - query = search.forResource((Class)getResourceType(theRequest, theReq).getImplementingClass()); + query = search.forResource((Class) getResourceType(theRequest, theReq).getImplementingClass()); } catch (ServletException e) { theModel.put("errorMsg", e.toString()); return "resource"; @@ -913,7 +917,7 @@ public class Controller { private FhirContext getContext(HomeRequest theRequest) { FhirVersionEnum version = theRequest.getFhirVersion(myConfig); FhirContext retVal = myContexts.get(version); - if (retVal==null) { + if (retVal == null) { retVal = new FhirContext(version); myContexts.put(version, retVal); } @@ -956,13 +960,13 @@ public class Controller { } List values; - boolean addToWhere=true; + boolean addToWhere = true; if ("token".equals(nextType)) { if (isBlank(parts.get(2))) { return true; } values = Collections.singletonList(StringUtils.join(parts, "")); - addToWhere=false; + addToWhere = false; theQuery.where(new TokenClientParam(nextName + nextQualifier).exactly().systemAndCode(parts.get(0), parts.get(2))); } else if ("date".equals(nextType)) { values = new ArrayList(); @@ -991,13 +995,13 @@ public class Controller { theClientCodeJsonWriter.write("value", nextValue); theClientCodeJsonWriter.writeEnd(); if (addToWhere) { - theQuery.where(new StringClientParam(nextName + nextQualifier).matches().value(nextValue)); + theQuery.where(new StringClientParam(nextName + nextQualifier).matches().value(nextValue)); } } if (StringUtils.isNotBlank(theReq.getParameter("param." + paramIdxString + ".0.name"))) { - handleSearchParam(paramIdxString + ".0", theReq, theQuery , theClientCodeJsonWriter); + handleSearchParam(paramIdxString + ".0", theReq, theQuery, theClientCodeJsonWriter); } return true; @@ -1010,7 +1014,7 @@ public class Controller { case DSTU1: return loadAndAddConfDstu1(theRequest, theModel); } - throw new IllegalStateException("Unknown version: "+theRequest.getFhirVersion(myConfig)); + throw new IllegalStateException("Unknown version: " + theRequest.getFhirVersion(myConfig)); } private Conformance loadAndAddConfDstu1(final HomeRequest theRequest, final ModelMap theModel) { @@ -1018,7 +1022,7 @@ public class Controller { Conformance conformance; try { - conformance = (Conformance)client.conformance(); + conformance = (Conformance) client.conformance(); } catch (Exception e) { ourLog.warn("Failed to load conformance statement", e); theModel.put("errorMsg", "Failed to load conformance statement, error was: " + e.toString()); @@ -1077,7 +1081,7 @@ public class Controller { ca.uhn.fhir.model.dev.resource.Conformance conformance; try { - conformance = (ca.uhn.fhir.model.dev.resource.Conformance)client.conformance(); + conformance = (ca.uhn.fhir.model.dev.resource.Conformance) client.conformance(); } catch (Exception e) { ourLog.warn("Failed to load conformance statement", e); theModel.put("errorMsg", "Failed to load conformance statement, error was: " + e.toString()); @@ -1226,6 +1230,22 @@ public class Controller { } } + /* + * DSTU2 no longer has a title in the bundle format, but it's still + * useful here.. + */ + if (bundle != null) { + INarrativeGenerator gen = getContext(theRequest).getNarrativeGenerator(); + if (gen != null) { + for (BundleEntry next : bundle.getEntries()) { + if (next.getTitle().isEmpty() && next.getResource() != null) { + String title = gen.generateTitle(next.getResource()); + next.getTitle().setValue(title); + } + } + } + } + resultDescription.append(" (").append(resultBody.length() + " bytes)"); Header[] requestHeaders = lastRequest != null ? applyHeaderFilters(lastRequest.getAllHeaders()) : new Header[0]; diff --git a/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/result.html b/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/result.html index e5a80628986..f6b263c208f 100644 --- a/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/result.html +++ b/hapi-fhir-testpage-overlay/src/main/webapp/WEB-INF/templates/result.html @@ -167,7 +167,7 @@ $("#outerForm").attr("action", "page").submit(); }); - +
@@ -175,10 +175,10 @@ - + - + @@ -196,7 +196,7 @@ -
- + @@ -206,7 +206,7 @@
+