Improve documentation on exception handling for servers

This commit is contained in:
jamesagnew 2014-08-20 22:46:15 -04:00
parent 45253cba5d
commit 731d369be0
20 changed files with 394 additions and 63 deletions

View File

@ -0,0 +1,100 @@
package example;
import java.io.IOException;
import java.lang.annotation.Documented;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
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.api.Tag;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.api.TemporalPrecisionEnum;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.rest.annotation.TagListParam;
import ca.uhn.fhir.model.dstu.composite.CodingDt;
import ca.uhn.fhir.model.dstu.resource.Conformance;
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.resource.Organization;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.dstu.valueset.QuantityCompararatorEnum;
import ca.uhn.fhir.model.primitive.DecimalDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.annotation.AddTags;
import ca.uhn.fhir.rest.annotation.Count;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.DeleteTags;
import ca.uhn.fhir.rest.annotation.GetTags;
import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.IncludeParam;
import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.annotation.OptionalParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.annotation.Since;
import ca.uhn.fhir.rest.annotation.Sort;
import ca.uhn.fhir.rest.annotation.Transaction;
import ca.uhn.fhir.rest.annotation.TransactionParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.api.SortOrderEnum;
import ca.uhn.fhir.rest.api.SortSpec;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.rest.client.api.IRestfulClient;
import ca.uhn.fhir.rest.param.CompositeParam;
import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.QuantityParam;
import ca.uhn.fhir.rest.param.ReferenceParam;
import ca.uhn.fhir.rest.param.StringAndListParam;
import ca.uhn.fhir.rest.param.StringOrListParam;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.param.TokenOrListParam;
import ca.uhn.fhir.rest.param.TokenParam;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
@SuppressWarnings("unused")
public abstract class ServerExceptionsExample implements IResourceProvider {
private boolean databaseIsDown;
//START SNIPPET: returnOO
@Read
public Patient read(@IdParam IdDt theId) {
if (databaseIsDown) {
OperationOutcome oo = new OperationOutcome();
oo.addIssue().setSeverity(IssueSeverityEnum.FATAL).setDetails("Database is down");
throw new InternalErrorException("Database is down", oo);
}
Patient patient = new Patient(); // populate this
return patient;
}
//END SNIPPET: returnOO
}

View File

@ -308,56 +308,6 @@
<escapeHTML>false</escapeHTML> <escapeHTML>false</escapeHTML>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.16</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.5.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.4</version>
<reportSets>
<reportSet>
<id>normal</id>
<reports>
<report>jxr</report>
</reports>
</reportSet>
<reportSet>
<id>restful-server-example</id>
<reports>
<report>jxr</report>
</reports>
<configuration>
<sourcePath>../restful-server-example/src/main/java</sourcePath>
<destDir>${project.reporting.outputDirectory}/rse-xref</destDir>
<outputDirectory>tmp</outputDirectory>
<reportOutputDirectory>rse-xref</reportOutputDirectory>
</configuration>
</reportSet>
</reportSets>
</plugin>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId> <artifactId>maven-project-info-reports-plugin</artifactId>
@ -600,6 +550,74 @@
</build> </build>
<profiles> <profiles>
<profile>
<id>MINI</id>
</profile>
<profile>
<id>DEFAULT</id>
<!--
The default profile has a bunch of the site plugins that
take longer to execute, so that they can be skipped for
testing the site build
-->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.16</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<configuration>
</configuration>
<reportSets>
<reportSet>
<id>default</id>
<reports>
<report>javadoc</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>2.5.3</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>2.4</version>
<reportSets>
<reportSet>
<id>normal</id>
<reports>
<report>jxr</report>
</reports>
</reportSet>
<reportSet>
<id>restful-server-example</id>
<reports>
<report>jxr</report>
</reports>
<configuration>
<sourcePath>../restful-server-example/src/main/java</sourcePath>
<destDir>${project.reporting.outputDirectory}/rse-xref</destDir>
<outputDirectory>tmp</outputDirectory>
<reportOutputDirectory>rse-xref</reportOutputDirectory>
</configuration>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
</profile>
<profile> <profile>
<id>DIST</id> <id>DIST</id>
<build> <build>

View File

@ -94,6 +94,9 @@
of the name "reference" for the actual reference. Thanks to of the name "reference" for the actual reference. Thanks to
Ricky Nguyen for reporting and tracking down the issue! Ricky Nguyen for reporting and tracking down the issue!
</action> </action>
<action type="fix">
Rename NotImpementedException to NotImplementedException (to correct typo)
</action>
</release> </release>
<release version="0.5" date="2014-Jul-30"> <release version="0.5" date="2014-Jul-30">
<action type="add"> <action type="add">

View File

@ -46,9 +46,10 @@ public abstract class BaseServerResponseException extends RuntimeException {
registerExceptionType(ResourceVersionConflictException.STATUS_CODE, ResourceVersionConflictException.class); registerExceptionType(ResourceVersionConflictException.STATUS_CODE, ResourceVersionConflictException.class);
registerExceptionType(UnprocessableEntityException.STATUS_CODE, UnprocessableEntityException.class); registerExceptionType(UnprocessableEntityException.STATUS_CODE, UnprocessableEntityException.class);
registerExceptionType(ResourceGoneException.STATUS_CODE, ResourceGoneException.class); registerExceptionType(ResourceGoneException.STATUS_CODE, ResourceGoneException.class);
registerExceptionType(NotImplementedOperationException.STATUS_CODE, NotImplementedOperationException.class);
} }
private final OperationOutcome myOperationOutcome; private OperationOutcome myOperationOutcome;
private String myResponseBody; private String myResponseBody;
private String myResponseMimeType; private String myResponseMimeType;
private int myStatusCode; private int myStatusCode;
@ -186,6 +187,17 @@ public abstract class BaseServerResponseException extends RuntimeException {
return myStatusCode; return myStatusCode;
} }
/**
* Sets the OperationOutcome resource associated with this exception. In server
* implementations, this is the OperartionOutcome resource to include with the HTTP response. In
* client implementations you should not call this method.
*
* @param theOperationOutcome The OperationOutcome resource
*/
public void setOperationOutcome(OperationOutcome theOperationOutcome) {
myOperationOutcome = theOperationOutcome;
}
/** /**
* This method is currently only called internally by HAPI, it should not be called by user code. * This method is currently only called internally by HAPI, it should not be called by user code.
*/ */
@ -200,6 +212,13 @@ public abstract class BaseServerResponseException extends RuntimeException {
myResponseMimeType = theResponseMimeType; myResponseMimeType = theResponseMimeType;
} }
/**
* For unit tests only
*/
static boolean isExceptionTypeRegistered(Class<?> theType) {
return ourStatusCodeToExceptionType.values().contains(theType);
}
public static BaseServerResponseException newInstance(int theStatusCode, String theMessage) { public static BaseServerResponseException newInstance(int theStatusCode, String theMessage) {
if (ourStatusCodeToExceptionType.containsKey(theStatusCode)) { if (ourStatusCodeToExceptionType.containsKey(theStatusCode)) {
try { try {

View File

@ -53,7 +53,7 @@ public class InternalErrorException extends BaseServerResponseException {
* @param theOperationOutcome The OperationOutcome resource to return to the client * @param theOperationOutcome The OperationOutcome resource to return to the client
*/ */
public InternalErrorException(String theMessage, OperationOutcome theOperationOutcome) { public InternalErrorException(String theMessage, OperationOutcome theOperationOutcome) {
super(theMessage, theOperationOutcome); super(STATUS_CODE, theMessage, theOperationOutcome);
} }
public InternalErrorException(String theMessage) { public InternalErrorException(String theMessage) {

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions; package ca.uhn.fhir.rest.server.exceptions;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
/* /*
@ -44,4 +45,16 @@ public class InvalidRequestException extends BaseServerResponseException {
super(STATUS_CODE, theMessage); super(STATUS_CODE, theMessage);
} }
/**
* Constructor
*
* @param theMessage
* The message
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public InvalidRequestException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
} }

View File

@ -1,5 +1,6 @@
package ca.uhn.fhir.rest.server.exceptions; package ca.uhn.fhir.rest.server.exceptions;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
/* /*
@ -36,6 +37,17 @@ public class MethodNotAllowedException extends BaseServerResponseException {
public static final int STATUS_CODE = Constants.STATUS_HTTP_405_METHOD_NOT_ALLOWED; public static final int STATUS_CODE = Constants.STATUS_HTTP_405_METHOD_NOT_ALLOWED;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/**
* Constructor
*
* @param theMessage
* The message
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public MethodNotAllowedException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
public MethodNotAllowedException(String error) { public MethodNotAllowedException(String error) {
super(STATUS_CODE, error); super(STATUS_CODE, error);
} }

View File

@ -1,4 +1,5 @@
package ca.uhn.fhir.rest.server.exceptions; package ca.uhn.fhir.rest.server.exceptions;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
/* /*
@ -37,12 +38,24 @@ import ca.uhn.fhir.rest.server.Constants;
* *
* *
*/ */
public class NotImpementedOperationException extends BaseServerResponseException { public class NotImplementedOperationException extends BaseServerResponseException {
public static final int STATUS_CODE = Constants.STATUS_HTTP_501_NOT_IMPLEMENTED; public static final int STATUS_CODE = Constants.STATUS_HTTP_501_NOT_IMPLEMENTED;
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public NotImpementedOperationException(String theMessage) { public NotImplementedOperationException(String theMessage) {
super(STATUS_CODE, theMessage); super(STATUS_CODE, theMessage);
} }
/**
* Constructor
*
* @param theMessage
* The message
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public NotImplementedOperationException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
} }

View File

@ -22,11 +22,12 @@ package ca.uhn.fhir.rest.server.exceptions;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt; import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.primitive.IdDt; import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
/** /**
* Represents an <b>HTTP 410 Resource Gone</b> response, which gvenerally * Represents an <b>HTTP 410 Resource Gone</b> response, which geenerally
* indicates that the resource has been deleted * indicates that the resource has been deleted
*/ */
public class ResourceGoneException extends BaseServerResponseException { public class ResourceGoneException extends BaseServerResponseException {
@ -45,6 +46,17 @@ public class ResourceGoneException extends BaseServerResponseException {
super(STATUS_CODE, "Resource of type " + theClass.getSimpleName() + " with ID " + thePatientId + " is gone/deleted"); super(STATUS_CODE, "Resource of type " + theClass.getSimpleName() + " with ID " + thePatientId + " is gone/deleted");
} }
/**
* Constructor
*
* @param theMessage
* The message
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public ResourceGoneException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
public ResourceGoneException(String theMessage) { public ResourceGoneException(String theMessage) {
super(STATUS_CODE, theMessage); super(STATUS_CODE, theMessage);
} }

View File

@ -43,6 +43,17 @@ public class ResourceNotFoundException extends BaseServerResponseException {
super(STATUS_CODE, createErrorMessage(theClass, theId), theOperationOutcome); super(STATUS_CODE, createErrorMessage(theClass, theId), theOperationOutcome);
} }
/**
* Constructor
*
* @param theMessage
* The message
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public ResourceNotFoundException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
/** /**
* @deprecated This doesn't make sense, since an identifier is not a resource ID and shouldn't generate a 404 if it isn't found - Should be removed * @deprecated This doesn't make sense, since an identifier is not a resource ID and shouldn't generate a 404 if it isn't found - Should be removed
*/ */

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server.exceptions;
* #L% * #L%
*/ */
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.rest.annotation.Delete; import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.Update; import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
@ -36,4 +37,16 @@ public class ResourceVersionConflictException extends BaseServerResponseExceptio
public ResourceVersionConflictException(String error) { public ResourceVersionConflictException(String error) {
super(STATUS_CODE, error); super(STATUS_CODE, error);
} }
/**
* Constructor
*
* @param theMessage
* The message
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public ResourceVersionConflictException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
} }

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server.exceptions;
* #L% * #L%
*/ */
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.rest.annotation.Update; import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.server.Constants; import ca.uhn.fhir.rest.server.Constants;
@ -35,4 +36,16 @@ public class ResourceVersionNotSpecifiedException extends BaseServerResponseExce
public ResourceVersionNotSpecifiedException(String error) { public ResourceVersionNotSpecifiedException(String error) {
super(STATUS_CODE, error); super(STATUS_CODE, error);
} }
/**
* Constructor
*
* @param theMessage
* The message
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public ResourceVersionNotSpecifiedException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
} }

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.rest.server.exceptions; package ca.uhn.fhir.rest.server.exceptions;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
/* /*
* #%L * #%L
* HAPI FHIR - Core Library * HAPI FHIR - Core Library
@ -38,6 +40,19 @@ public class UnclassifiedServerFailureException extends BaseServerResponseExcept
super(theStatusCode, theMessage); super(theStatusCode, theMessage);
} }
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code to return (e.g. 404 if you wish to return an HTTP 404 status)
* @param theMessage
* The message to add to the status line
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public UnclassifiedServerFailureException(int theStatusCode, String theMessage, OperationOutcome theOperationOutcome) {
super(theStatusCode, theMessage, theOperationOutcome);
}
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
} }

View File

@ -38,6 +38,18 @@ public class UnprocessableEntityException extends BaseServerResponseException {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public static final int STATUS_CODE = Constants.STATUS_HTTP_422_UNPROCESSABLE_ENTITY; public static final int STATUS_CODE = Constants.STATUS_HTTP_422_UNPROCESSABLE_ENTITY;
/**
* Constructor
*
* @param theMessage
* The message to add to the status line
* @param theOperationOutcome The OperationOutcome resource to return to the client
*/
public UnprocessableEntityException(String theMessage, OperationOutcome theOperationOutcome) {
super(STATUS_CODE, theMessage, theOperationOutcome);
}
/** /**
* Constructor which accepts an {@link OperationOutcome} resource which will be supplied in the response * Constructor which accepts an {@link OperationOutcome} resource which will be supplied in the response
*/ */

View File

@ -127,12 +127,16 @@ public class FhirTerser {
* message. Specifying a type of {@link IResource} would return the resource itself, as well as any contained * message. Specifying a type of {@link IResource} would return the resource itself, as well as any contained
* resources. * resources.
* </p> * </p>
* <p>
* Note on scope: This method will descend into any contained resources ({@link IResource#getContained()}) as well, but will not
* decend into linked resources (e.g. {@link ResourceReferenceDt#getResource()})
* </p>
* *
* @param theResourceT * @param theResource
* The resource instance to search. Must not be null. * The resource instance to search. Must not be null.
* @param theType * @param theType
* The type to search for. Must not be null. * The type to search for. Must not be null.
* @return * @return Returns a list of all matching elements
*/ */
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(IResource theResource, final Class<T> theType) { public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(IResource theResource, final Class<T> theType) {
final ArrayList<T> retVal = new ArrayList<T>(); final ArrayList<T> retVal = new ArrayList<T>();

View File

@ -416,6 +416,10 @@
case, you may pass one into the constructor of the case, you may pass one into the constructor of the
exception you are throwing. exception you are throwing.
</p> </p>
<macro name="snippet">
<param name="id" value="returnOO" />
<param name="file" value="examples/src/main/java/example/ServerExceptionsExample.java" />
</macro>
</subsection> </subsection>
</section> </section>

View File

@ -1,4 +1,4 @@
package ca.uhn.fhir.rest.server.exception; package ca.uhn.fhir.rest.server.exceptions;
import static org.junit.Assert.*; import static org.junit.Assert.*;
@ -10,6 +10,7 @@ import org.mockito.internal.matchers.GreaterThan;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome; import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException; import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException; import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.UnclassifiedServerFailureException;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.reflect.ClassPath; import com.google.common.reflect.ClassPath;
@ -29,12 +30,21 @@ public class ExceptionTest {
Class<?> next = Class.forName(classInfo.getName()); Class<?> next = Class.forName(classInfo.getName());
assertNotNull(next); assertNotNull(next);
if (next == AuthenticationException.class) { if (next == getClass()) {
continue; continue;
} }
if (next == BaseServerResponseException.class) { if (next == BaseServerResponseException.class) {
continue; continue;
} }
if (next == UnclassifiedServerFailureException.class) {
continue;
}
assertTrue(BaseServerResponseException.isExceptionTypeRegistered(next));
if (next == AuthenticationException.class) {
continue;
}
try { try {
next.getConstructor(String.class, OperationOutcome.class); next.getConstructor(String.class, OperationOutcome.class);

View File

@ -0,0 +1,59 @@
package ca.uhn.fhir.util;
import static org.junit.Assert.*;
import java.util.List;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
import ca.uhn.fhir.model.dstu.resource.Observation;
public class FhirTerserTest {
@Test
public void testTerser() {
//@formatter:off
String msg = "<Observation xmlns=\"http://hl7.org/fhir\">\n" +
" <text>\n" +
" <status value=\"empty\"/>\n" +
" <div xmlns=\"http://www.w3.org/1999/xhtml\"/>\n" +
" </text>\n" +
" <!-- The test code - may not be correct -->\n" +
" <name>\n" +
" <coding>\n" +
" <system value=\"http://loinc.org\"/>\n" +
" <code value=\"43151-0\"/>\n" +
" <display value=\"Glucose Meter Device Panel\"/>\n" +
" </coding>\n" +
" </name>\n" +
" <valueQuantity>\n" +
" <value value=\"7.7\"/>\n" +
" <units value=\"mmol/L\"/>\n" +
" <system value=\"http://unitsofmeasure.org\"/>\n" +
" </valueQuantity>\n" +
" <appliesDateTime value=\"2014-05-28T22:12:21Z\"/>\n" +
" <status value=\"final\"/>\n" +
" <reliability value=\"ok\"/>\n" +
" <subject>\n" +
" <reference value=\"cid:patient@bundle\"/>\n" +
" </subject>\n" +
" <performer>\n" +
" <reference value=\"cid:device@bundle\"></reference>\n" +
" </performer>\n" +
"</Observation>";
//@formatter:on
Observation parsed = ourCtx.newXmlParser().parseResource(Observation.class, msg);
FhirTerser t = ourCtx.newTerser();
List<ResourceReferenceDt> elems = t.getAllPopulatedChildElementsOfType(parsed, ResourceReferenceDt.class);
assertEquals(2, elems.size());
assertEquals("cid:patient@bundle", elems.get(0).getReference().getValue());
assertEquals("cid:device@bundle", elems.get(1).getReference().getValue());
}
private static FhirContext ourCtx = new FhirContext();
}

View File

@ -12,7 +12,7 @@
<dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base"> <dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type> <dependency-type>uses</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.6-SNAPSHOT/hapi-fhir-testpage-overlay-0.6-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependency-type>consumes</dependency-type> <dependency-type>consumes</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">

View File

@ -6,7 +6,7 @@
<dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base"> <dependent-module archiveName="hapi-fhir-base-0.6-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type> <dependency-type>uses</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.6-SNAPSHOT/hapi-fhir-testpage-overlay-0.6-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependency-type>consumes</dependency-type> <dependency-type>consumes</dependency-type>
</dependent-module> </dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF"> <dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">