Conflicts:
	hapi-tinder-plugin/src/main/resources/vm/resource.vm
	hapi-tinder-plugin/src/main/resources/vm/resource_dstu.vm
This commit is contained in:
lmds1 2014-11-10 18:17:29 -05:00
commit 039e5655a8
80 changed files with 6008 additions and 594 deletions

View File

@ -18,14 +18,11 @@
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.8-SNAPSHOT</version>
<<<<<<< HEAD
=======
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId>
<version>0.8-SNAPSHOT</version>
>>>>>>> versions
</dependency>
<dependency>
<groupId>javax.servlet</groupId>

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>0.8-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-base-examples</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - Examples (for site)</name>
<dependencies>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.8-SNAPSHOT</version>
<<<<<<< HEAD:hapi-fhir-base/examples/pom.xml
=======
<<<<<<< HEAD
=======
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2:examples/pom.xml.orig
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId>
<version>0.8-SNAPSHOT</version>
<<<<<<< HEAD:hapi-fhir-base/examples/pom.xml
=======
>>>>>>> versions
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2:examples/pom.xml.orig
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,29 @@
package example;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
//START SNIPPET: interceptor
public class RequestCounterInterceptor extends InterceptorAdapter
{
private int myRequestCount;
public int getRequestCount() {
return myRequestCount;
}
/**
* Override the incomingRequestPreProcessed method, which is called
* for each incoming request before any processing is done
*/
@Override
public boolean incomingRequestPreProcessed(HttpServletRequest theRequest, HttpServletResponse theResponse) {
myRequestCount++;
return true;
}
}
//END SNIPPET: interceptor

View File

@ -0,0 +1,42 @@
package example;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
//START SNIPPET: interceptor
public class RequestExceptionInterceptor extends InterceptorAdapter
{
@Override
public boolean handleException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theServletRequest,
HttpServletResponse theServletResponse) throws ServletException, IOException {
// If the exception is a built-in type, it defines the correct status
// code to return. Otherwise default to 500.
if (theException instanceof BaseServerResponseException) {
theServletResponse.setStatus(((BaseServerResponseException) theException).getStatusCode());
} else {
theServletResponse.setStatus(Constants.STATUS_HTTP_500_INTERNAL_ERROR);
}
// Provide a response ourself
theServletResponse.setContentType("text/plain");
theServletResponse.getWriter().append("Failed to process!");
theServletResponse.getWriter().close();
// Since we handled this response in the interceptor, we must return false
// to stop processing immediately
return false;
}
}
//END SNIPPET: interceptor

View File

@ -3,6 +3,9 @@ package example;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.ExtensionDt;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
@ -11,12 +14,13 @@ import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.StringDt;
import ca.uhn.fhir.parser.DataFormatException;
import ca.uhn.fhir.rest.server.interceptor.InterceptorAdapter;
public class ServerInterceptors {
@SuppressWarnings("unused")
public static void main(String[] args) throws DataFormatException, IOException {
// START SNIPPET: resourceExtension
// Create an example patient

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hapi-deployable-pom</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -22,6 +22,7 @@
<reportSets>
<reportSet>
<reports>
<report>scm</report>
</reports>
</reportSet>
</reportSets>
@ -39,6 +40,7 @@
<configuration>
<links>
<link>http://docs.oracle.com/javaee/7/api</link>
<link>http://jamesagnew.github.io/hapi-fhir/apidocs</link>
</links>
</configuration>
</reportSet>

View File

@ -0,0 +1,127 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>0.8-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>hapi-deployable-pom</artifactId>
<packaging>pom</packaging>
<name>HAPI FHIR - Deployable Artifact Parent POM</name>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.7</version>
<<<<<<< HEAD
<reportSets>
<reportSet>
<reports>
=======
<inherited>false</inherited>
<reportSets>
<reportSet>
<reports>
<report>scm</report>
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven_javadoc_plugin_version}</version>
<reportSets>
<reportSet>
<id>default</id>
<reports>
<report>javadoc</report>
</reports>
<configuration>
<links>
<link>http://docs.oracle.com/javaee/7/api</link>
<<<<<<< HEAD
=======
<link>http://jamesagnew.github.io/hapi-fhir/apidocs</link>
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
</links>
</configuration>
</reportSet>
</reportSets>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>DIST</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<inherited>true</inherited>
<configuration>
<minmemory>128m</minmemory>
<maxmemory>1g</maxmemory>
<linksource>true</linksource>
<verbose>false</verbose>
<debug>false</debug>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven_source_plugin_version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>${maven_license_plugin_version}</version>
<executions>
<execution>
<id>first</id>
<goals>
<goal>update-file-header</goal>
</goals>
<phase>process-sources</phase>
<configuration>
<licenseName>apache_v2</licenseName>
<canUpdateDescription>true</canUpdateDescription>
<canUpdateCopyright>true</canUpdateCopyright>
<roots>
<root>src/main/java</root>
</roots>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,55 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>0.8-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-base-examples</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - Examples (for site)</name>
<dependencies>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.8-SNAPSHOT</version>
<<<<<<< HEAD
=======
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-structures-dstu</artifactId>
<version>0.8-SNAPSHOT</version>
>>>>>>> versions
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -15,13 +15,6 @@
<name>HAPI FHIR - Core Library</name>
<distributionManagement>
<site>
<id>git.server</id>
<url>scm:git:git@github.com:jamesagnew/hapi-fhir.git</url>
</site>
</distributionManagement>
<dependencies>
<!-- JSON -->
@ -214,6 +207,8 @@
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>

View File

@ -34,6 +34,7 @@ import ca.uhn.fhir.i18n.HapiLocalizer;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Binary;
import ca.uhn.fhir.model.view.ViewGenerator;
import ca.uhn.fhir.narrative.INarrativeGenerator;
import ca.uhn.fhir.parser.DataFormatException;
@ -167,7 +168,12 @@ public class FhirContext {
try {
String className = myNameToResourceType.get(resourceName.toLowerCase());
if (className == null) {
throw new DataFormatException("Unknown resource name[" + resourceName + "]");
if ("binary".equals(resourceName.toLowerCase())) {
// Binary is not generated so it's not in the list of potential resources
className = Binary.class.getName();
} else {
throw new DataFormatException("Unknown resource name[" + resourceName + "]");
}
}
Class<?> clazz = Class.forName(className);
if (IResource.class.isAssignableFrom(clazz)) {

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.context;
* 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.

View File

@ -48,6 +48,18 @@ public class RuntimeChildAny extends RuntimeChildChoiceDefinition {
if (next.equals(XhtmlDt.class)) {
continue;
}
BaseRuntimeElementDefinition<?> nextDef = theClassToElementDefinitions.get(next);
if (nextDef instanceof IRuntimeDatatypeDefinition) {
if (((IRuntimeDatatypeDefinition) nextDef).isSpecialization()) {
/*
* Things like BoundCodeDt shoudn't be considered as valid options for an "any" choice, since
* we'll already have CodeDt as an option
*/
continue;
}
}
if (IResource.class.isAssignableFrom(next) || IDatatype.class.isAssignableFrom(next)) {
choiceTypes.add(next);
}

View File

@ -23,6 +23,7 @@ package ca.uhn.fhir.model.api;
import java.util.HashMap;
import java.util.Map;
import ca.uhn.fhir.rest.gclient.StringClientParam;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
@ -50,6 +51,17 @@ public abstract class BaseResource extends BaseElement implements IResource {
@SearchParamDefinition(name="_id", path="", description="The ID of the resource", type="string" )
public static final String SP_RES_ID = "_id";
/**
* <b>Fluent Client</b> search parameter constant for <b>_id</b>
* <p>
* Description: <b>the _id of a resource</b><br/>
* Type: <b>string</b><br/>
* Path: <b>Resource._id</b><br/>
* </p>
*/
public static final StringClientParam RES_ID = new StringClientParam(BaseResource.SP_RES_ID);
@Child(name = "contained", order = 2, min = 0, max = 1)
private ContainedDt myContained;

View File

@ -31,13 +31,33 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
/**
* Keys in this map refer to <b>resource metadata keys</b>, which are keys used to access information about specific resource instances that live outside of the resource body. Typically, these are
* data elements which are sent/receieved in HTTP Headers along with read/create resource requests, or properties which can be found in bundle entries.
* <p>
* To access or set resource metadata values, every resource has a metadata map, and this class provides convenient getters/setters for interacting with that map. For example, to get a resource's
* {@link UPDATED} value, which is the "last updated" time for that resource, use the following code:
* </p>
* <p>
* <code>InstantDt updated = ResourceMetadataKeyEnum.UPDATED.get(resource);</code>
* <p>
* <p>
* To set this value, use the following:
* </p>
* <p>
* <code>InstantDt update = new InstantDt("2011-01-02T11:22:33.0000Z"); // populate with the actual time<br/>
* ResourceMetadataKeyEnum.UPDATED.put(resource, update);</code>
* </p>
* <p>
* Note that this class is not a Java Enum, and can therefore be extended (this is why it is not actually an Enum). Users of HAPI-FHIR are able to create their own classes extending this class to
* define their own keys for storage in resource metadata if needed.
* </p>
*/
public abstract class ResourceMetadataKeyEnum<T> {
/**
* If present and populated with a date/time (as an instance of {@link InstantDt}),
* this value is an indication that the resource is in the deleted state. This key
* is only used in a limited number of scenarios, such as POSTing transaction bundles
* to a server, or returning resource history.
* If present and populated with a date/time (as an instance of {@link InstantDt}), this value is an indication that the resource is in the deleted state. This key is only used in a limited number
* of scenarios, such as POSTing transaction bundles to a server, or returning resource history.
* <p>
* Values for this key are of type <b>{@link InstantDt}</b>
* </p>
@ -55,9 +75,7 @@ public abstract class ResourceMetadataKeyEnum<T> {
};
/**
* The value for this key represents a previous ID used to identify
* this resource. This key is currently only used internally during
* transaction method processing.
* The value for this key represents a previous ID used to identify this resource. This key is currently only used internally during transaction method processing.
* <p>
* Values for this key are of type <b>{@link IdDt}</b>
* </p>
@ -73,18 +91,14 @@ public abstract class ResourceMetadataKeyEnum<T> {
theResource.getResourceMetadata().put(PREVIOUS_ID, theObject);
}
};
/**
* The value for this key is the bundle entry <b>Published</b> time. This is
* defined by FHIR as "Time resource copied into the feed", which is
* generally best left to the current time.
* The value for this key is the bundle entry <b>Published</b> time. This is defined by FHIR as "Time resource copied into the feed", which is generally best left to the current time.
* <p>
* Values for this key are of type <b>{@link InstantDt}</b>
* </p>
* <p>
* <b>Server Note</b>: In servers, it is generally advisable to leave this
* value <code>null</code>, in which case the server will substitute the
* current time automatically.
* <b>Server Note</b>: In servers, it is generally advisable to leave this value <code>null</code>, in which case the server will substitute the current time automatically.
* </p>
*
* @see InstantDt
@ -122,7 +136,8 @@ public abstract class ResourceMetadataKeyEnum<T> {
return (TagList) retValObj;
}
}
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + TAG_LIST.name() + " - Expected " + TagList.class.getCanonicalName());
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + TAG_LIST.name() + " - Expected "
+ TagList.class.getCanonicalName());
}
@Override
@ -132,9 +147,7 @@ public abstract class ResourceMetadataKeyEnum<T> {
};
/**
* If present and populated with a string (as an instance of {@link String}),
* this value contains the title for this resource, as supplied in any bundles containing the
* resource.
* If present and populated with a string (as an instance of {@link String}), this value contains the title for this resource, as supplied in any bundles containing the resource.
* <p>
* Values for this key are of type <b>{@link String}</b>
* </p>
@ -150,13 +163,10 @@ public abstract class ResourceMetadataKeyEnum<T> {
theResource.getResourceMetadata().put(TITLE, theObject);
}
};
/**
* The value for this key is the bundle entry <b>Updated</b> time. This is
* defined by FHIR as "Last Updated for resource". This value is also used
* for populating the "Last-Modified" header in the case of methods that
* return a single resource (read, vread, etc.)
* The value for this key is the bundle entry <b>Updated</b> time. This is defined by FHIR as "Last Updated for resource". This value is also used for populating the "Last-Modified" header in the
* case of methods that return a single resource (read, vread, etc.)
* <p>
* Values for this key are of type <b>{@link InstantDt}</b>
* </p>
@ -173,9 +183,8 @@ public abstract class ResourceMetadataKeyEnum<T> {
public void put(IResource theResource, InstantDt theObject) {
theResource.getResourceMetadata().put(UPDATED, theObject);
}
};
};
/**
* The value for this key is the version ID of the resource object.
* <p>
@ -196,14 +205,11 @@ public abstract class ResourceMetadataKeyEnum<T> {
theResource.getResourceMetadata().put(VERSION_ID, theObject);
}
};
/**
* If present and populated with a string, provides the "search link" (the link
* element in the bundle entry with <code>rel="search"</code>). Server implementations
* may populate this with a complete URL, in which case the URL will be
* placed as-is in the bundle. They may alternately specify a
* resource relative URL (e.g. "Patient?name=tester") in which case the
* server will convert this to an absolute URL at runtime.
* If present and populated with a string, provides the "search link" (the link element in the bundle entry with <code>rel="search"</code>). Server implementations may populate this with a
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient?name=tester") in which case the server will convert
* this to an absolute URL at runtime.
* <p>
* Values for this key are of type <b>{@link String}</b>
* </p>
@ -221,12 +227,9 @@ public abstract class ResourceMetadataKeyEnum<T> {
};
/**
* If present and populated with a string, provides the "alternate link" (the link
* element in the bundle entry with <code>rel="alternate"</code>). Server implementations
* may populate this with a complete URL, in which case the URL will be
* placed as-is in the bundle. They may alternately specify a
* resource relative URL (e.g. "Patient/1243") in which case the
* server will convert this to an absolute URL at runtime.
* If present and populated with a string, provides the "alternate link" (the link element in the bundle entry with <code>rel="alternate"</code>). Server implementations may populate this with a
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient/1243") in which case the server will convert this to
* an absolute URL at runtime.
* <p>
* Values for this key are of type <b>{@link String}</b>
* </p>
@ -242,14 +245,13 @@ public abstract class ResourceMetadataKeyEnum<T> {
theResource.getResourceMetadata().put(LINK_ALTERNATE, theObject);
}
};
private final String myValue;
public ResourceMetadataKeyEnum(String theValue) {
myValue = theValue;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
@ -267,8 +269,6 @@ public abstract class ResourceMetadataKeyEnum<T> {
return true;
}
public abstract T get(IResource theResource);
@Override
@ -307,39 +307,42 @@ public abstract class ResourceMetadataKeyEnum<T> {
return (IdDt) retValObj;
}
} else if (retValObj instanceof Number) {
return new IdDt(((Number)retValObj).toString());
return new IdDt(((Number) retValObj).toString());
}
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + IdDt.class.getCanonicalName());
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected "
+ IdDt.class.getCanonicalName());
}
private static InstantDt getInstantFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum<?>, Object> theResourceMetadata, ResourceMetadataKeyEnum<InstantDt> theKey) {
Object retValObj = theResourceMetadata.get(theKey);
if (retValObj == null) {
private static InstantDt getInstantFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum<?>, Object> theResourceMetadata, ResourceMetadataKeyEnum<InstantDt> theKey) {
Object retValObj = theResourceMetadata.get(theKey);
if (retValObj == null) {
return null;
} else if (retValObj instanceof Date) {
return new InstantDt((Date) retValObj);
} else if (retValObj instanceof InstantDt) {
if (((InstantDt) retValObj).isEmpty()) {
return null;
} else if (retValObj instanceof Date) {
return new InstantDt((Date) retValObj);
} else if (retValObj instanceof InstantDt) {
if (((InstantDt) retValObj).isEmpty()) {
return null;
} else {
return (InstantDt) retValObj;
}
} else {
return (InstantDt) retValObj;
}
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + InstantDt.class.getCanonicalName());
}
private static String getStringFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum<?>, Object> theResourceMetadata, ResourceMetadataKeyEnum<String> theKey) {
Object retValObj = theResourceMetadata.get(theKey);
if (retValObj == null) {
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected "
+ InstantDt.class.getCanonicalName());
}
private static String getStringFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum<?>, Object> theResourceMetadata, ResourceMetadataKeyEnum<String> theKey) {
Object retValObj = theResourceMetadata.get(theKey);
if (retValObj == null) {
return null;
} else if (retValObj instanceof String) {
if (StringUtils.isBlank(((String) retValObj))) {
return null;
} else if (retValObj instanceof String) {
if (StringUtils.isBlank(((String) retValObj))) {
return null;
} else {
return (String) retValObj;
}
} else {
return (String) retValObj;
}
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + String.class.getCanonicalName());
}
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected "
+ String.class.getCanonicalName());
}
}

View File

@ -9,9 +9,9 @@ package ca.uhn.fhir.model.api.annotation;
* 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.

View File

@ -39,9 +39,9 @@ public abstract class BaseOperationOutcome extends BaseResource implements IReso
public abstract BaseIssue getIssueFirstRep();
public static abstract class BaseIssue extends BaseIdentifiableElement implements IResourceBlock {
public abstract CodeDt getSeverityElement();
public abstract StringDt getDetailsElement();
public abstract BaseCodingDt getType();
@ -51,7 +51,8 @@ public abstract class BaseOperationOutcome extends BaseResource implements IReso
public abstract BaseIssue setDetails(String theString);
public abstract StringDt getLocationFirstRep();
}
}

View File

@ -0,0 +1,75 @@
package ca.uhn.fhir.model.base.resource;
/*
* #%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.List;
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
import ca.uhn.fhir.model.api.BaseResource;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.IResourceBlock;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.StringDt;
public abstract class BaseOperationOutcome extends BaseResource implements IResource {
public abstract BaseIssue addIssue();
public abstract List<? extends BaseIssue> getIssue();
public abstract BaseIssue getIssueFirstRep();
public static abstract class BaseIssue extends BaseIdentifiableElement implements IResourceBlock {
<<<<<<< HEAD
public abstract CodeDt getSeverityElement();
=======
public abstract CodeDt getSeverityElement();
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
public abstract StringDt getDetailsElement();
public abstract BaseCodingDt getType();
<<<<<<< HEAD
public abstract BaseIssue addLocation( String theString);
=======
public abstract BaseIssue addLocation(String theString);
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
public abstract BaseIssue setDetails(String theString);
public abstract StringDt getLocationFirstRep();
<<<<<<< HEAD
}
=======
}
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
}

View File

@ -95,10 +95,10 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
* Constructor which takes two strings representing the lower and upper bounds of the range (inclusive on both ends)
*
* @param theLowerBound
* A qualified date param representing the lower date bound (optionally may include time), e.g.
* An unqualified date param representing the lower date bound (optionally may include time), e.g.
* "2011-02-22" or "2011-02-22T13:12:00"
* @param theUpperBound
* A qualified date param representing the upper date bound (optionally may include time), e.g.
* An unqualified date param representing the upper date bound (optionally may include time), e.g.
* "2011-02-22" or "2011-02-22T13:12:00"
*/
public DateRangeParam(String theLowerBound, String theUpperBound) {
@ -211,7 +211,9 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
@Override
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
for (List<String> paramList : theParameters) {
boolean haveHadUnqualifiedParameter = false;
for (QualifiedParamList paramList : theParameters) {
if (paramList.size() == 0) {
continue;
}
@ -220,9 +222,18 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
}
String param = paramList.get(0);
DateParam parsed = new DateParam();
parsed.setValueAsQueryToken(null, param);
parsed.setValueAsQueryToken(paramList.getQualifier(), param);
addParam(parsed);
if (parsed.getComparator() == null) {
if (haveHadUnqualifiedParameter) {
throw new InvalidRequestException("Multiple date parameters with the same name and no qualifier (>, <, etc.) is not supported");
}
haveHadUnqualifiedParameter=true;
}
}
}
private void addParam(DateParam theParsed) throws InvalidRequestException {
@ -231,10 +242,9 @@ public class DateRangeParam implements IQueryParameterAnd<DateParam> {
throw new InvalidRequestException("Can not have multiple date range parameters for the same param without a qualifier");
}
myLowerBound = theParsed;
myUpperBound = theParsed;
// TODO: in this case, should set lower and upper to exact moments
// using specified precision
myLowerBound = new DateParam(QuantityCompararatorEnum.GREATERTHAN_OR_EQUALS, theParsed.getValueAsString());
myUpperBound = new DateParam(QuantityCompararatorEnum.LESSTHAN_OR_EQUALS, theParsed.getValueAsString());
} else {
switch (theParsed.getComparator()) {

View File

@ -207,10 +207,11 @@ public class ParameterUtil {
case ',':
case '|':
b.append('\\');
// fall through
break;
default:
b.append(next);
break;
}
b.append(next);
}
return b.toString();

View File

@ -1,32 +0,0 @@
package ca.uhn.fhir.rest.server;
/*
* #%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 ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
/**
* @deprecated Use {@link ca.uhn.fhir.rest.server.security.ISecurityManager} instead
*/
public interface ISecurityManager {
public void authenticate(HttpServletRequest request) throws AuthenticationException;
}

View File

@ -92,13 +92,12 @@ public class RestfulServer extends HttpServlet {
private AddProfileTagEnum myAddProfileTag;
private FhirContext myFhirContext;
private String myImplementationDescription;
private List<IServerInterceptor> myInterceptors = new ArrayList<IServerInterceptor>();
private final List<IServerInterceptor> myInterceptors = new ArrayList<IServerInterceptor>();
private ResourceBinding myNullResourceBinding = new ResourceBinding();
private IPagingProvider myPagingProvider;
private Collection<Object> myPlainProviders;
private Map<String, ResourceBinding> myResourceNameToProvider = new HashMap<String, ResourceBinding>();
private Collection<IResourceProvider> myResourceProviders;
private ISecurityManager mySecurityManager;
private IServerAddressStrategy myServerAddressStrategy = new IncomingRequestAddressStrategy();
private BaseMethodBinding<?> myServerConformanceMethod;
private Object myServerConformanceProvider;
@ -123,8 +122,7 @@ public class RestfulServer extends HttpServlet {
/**
* This method is called prior to sending a response to incoming requests. It is used to add custom headers.
* <p>
* Use caution if overriding this method: it is recommended to call <code>super.addHeadersToResponse</code> to avoid
* inadvertantly disabling functionality.
* Use caution if overriding this method: it is recommended to call <code>super.addHeadersToResponse</code> to avoid inadvertantly disabling functionality.
* </p>
*/
public void addHeadersToResponse(HttpServletResponse theHttpResponse) {
@ -236,14 +234,13 @@ public class RestfulServer extends HttpServlet {
Package pack = annotation.annotationType().getPackage();
if (pack.equals(IdParam.class.getPackage())) {
if (!allowableParams.contains(annotation.annotationType())) {
throw new ConfigurationException("Method[" + m.toString() + "] is not allowed to have a parameter annotated with "+ annotation);
throw new ConfigurationException("Method[" + m.toString() + "] is not allowed to have a parameter annotated with " + annotation);
}
}
}
}
}
resourceBinding.addMethod(foundMethodBinding);
ourLog.debug(" * Method: {}#{} is a handler", theProvider.getClass(), m.getName());
}
@ -293,8 +290,8 @@ public class RestfulServer extends HttpServlet {
}
/**
* Gets the {@link FhirContext} associated with this server. For efficient processing, resource providers and plain
* providers should generally use this context if one is needed, as opposed to creating their own.
* Gets the {@link FhirContext} associated with this server. For efficient processing, resource providers and plain providers should generally use this context if one is needed, as opposed to
* creating their own.
*/
public FhirContext getFhirContext() {
return myFhirContext;
@ -336,26 +333,16 @@ public class RestfulServer extends HttpServlet {
}
/**
* Provides the security manager, or <code>null</code> if none
*/
public ISecurityManager getSecurityManager() {
return mySecurityManager;
}
/**
* Get the server address strategy, which is used to determine what base URL to provide clients to refer to this
* server. Defaults to an instance of {@link IncomingRequestAddressStrategy}
* Get the server address strategy, which is used to determine what base URL to provide clients to refer to this server. Defaults to an instance of {@link IncomingRequestAddressStrategy}
*/
public IServerAddressStrategy getServerAddressStrategy() {
return myServerAddressStrategy;
}
/**
* Returns the server conformance provider, which is the provider that is used to generate the server's conformance
* (metadata) statement.
* Returns the server conformance provider, which is the provider that is used to generate the server's conformance (metadata) statement.
* <p>
* By default, the {@link ServerConformanceProvider} is used, but this can be changed, or set to <code>null</code>
* if you do not wish to export a conformance statement.
* By default, the {@link ServerConformanceProvider} is used, but this can be changed, or set to <code>null</code> if you do not wish to export a conformance statement.
* </p>
*/
public Object getServerConformanceProvider() {
@ -363,8 +350,7 @@ public class RestfulServer extends HttpServlet {
}
/**
* Gets the server's name, as exported in conformance profiles exported by the server. This is informational only,
* but can be helpful to set with something appropriate.
* Gets the server's name, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
*
* @see RestfulServer#setServerName(String)
*/
@ -377,8 +363,7 @@ public class RestfulServer extends HttpServlet {
}
/**
* Gets the server's version, as exported in conformance profiles exported by the server. This is informational
* only, but can be helpful to set with something appropriate.
* Gets the server's version, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
*/
public String getServerVersion() {
return myServerVersion;
@ -417,12 +402,14 @@ public class RestfulServer extends HttpServlet {
NarrativeModeEnum narrativeMode = determineNarrativeMode(theRequest);
boolean respondGzip = theRequest.isRespondGzip();
Bundle bundle = createBundleFromBundleProvider(this, theResponse, resultList, responseEncoding, theRequest.getFhirServerBase(), theRequest.getCompleteUrl(), prettyPrint, requestIsBrowser, narrativeMode, start, count, thePagingAction);
Bundle bundle = createBundleFromBundleProvider(this, theResponse, resultList, responseEncoding, theRequest.getFhirServerBase(), theRequest.getCompleteUrl(), prettyPrint, requestIsBrowser,
narrativeMode, start, count, thePagingAction);
for (int i = getInterceptors().size() - 1; i >= 0; i--) {
IServerInterceptor next = getInterceptors().get(i);
boolean continueProcessing = next.outgoingResponse(theRequest, bundle, theRequest.getServletRequest(), theRequest.getServletResponse());
if (!continueProcessing) {
ourLog.debug("Interceptor {} returned false, not continuing processing");
return;
}
}
@ -435,31 +422,29 @@ public class RestfulServer extends HttpServlet {
for (IServerInterceptor next : myInterceptors) {
boolean continueProcessing = next.incomingRequestPreProcessed(theRequest, theResponse);
if (!continueProcessing) {
ourLog.debug("Interceptor {} returned false, not continuing processing");
return;
}
}
String fhirServerBase = null;
boolean requestIsBrowser = requestIsBrowser(theRequest);
RequestDetails requestDetails=null;
try {
if (null != mySecurityManager) {
mySecurityManager.authenticate(theRequest);
}
String resourceName = null;
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
StringBuffer requestUrl = theRequest.getRequestURL();
String servletContextPath = "";
// if (getServletContext().getMajorVersion() >= 3) {
// // getServletContext is only supported in version 3+ of servlet-api
if (getServletContext() != null) {
servletContextPath = StringUtils.defaultString(getServletContext().getContextPath());
}
// }
// if (getServletContext().getMajorVersion() >= 3) {
// // getServletContext is only supported in version 3+ of servlet-api
if (getServletContext() != null) {
servletContextPath = StringUtils.defaultString(getServletContext().getContextPath());
}
// }
if (ourLog.isTraceEnabled()) {
ourLog.trace("Request FullPath: {}", requestFullPath);
ourLog.trace("Servlet Path: {}", servletPath);
@ -609,7 +594,7 @@ public class RestfulServer extends HttpServlet {
throw new InvalidRequestException(b.toString());
}
RequestDetails requestDetails = r;
requestDetails = r;
requestDetails.setResourceOperationType(resourceMethod.getResourceOperationType());
requestDetails.setSystemOperationType(resourceMethod.getSystemOperationType());
requestDetails.setOtherOperationType(resourceMethod.getOtherOperationType());
@ -617,6 +602,7 @@ public class RestfulServer extends HttpServlet {
for (IServerInterceptor next : myInterceptors) {
boolean continueProcessing = next.incomingRequestPostProcessed(requestDetails, theRequest, theResponse);
if (!continueProcessing) {
ourLog.debug("Interceptor {} returned false, not continuing processing");
return;
}
}
@ -624,6 +610,15 @@ public class RestfulServer extends HttpServlet {
resourceMethod.invokeServer(this, r);
} catch (AuthenticationException e) {
for (int i = getInterceptors().size() - 1; i >= 0; i--) {
IServerInterceptor next = getInterceptors().get(i);
if (!next.handleException(requestDetails, e, theRequest, theResponse)) {
ourLog.debug("Interceptor {} returned false, not continuing processing");
return;
}
}
if (requestIsBrowser) {
// if request is coming from a browser, prompt the user to enter login credentials
theResponse.setHeader("WWW-Authenticate", "BASIC realm=\"FHIR\"");
@ -636,14 +631,30 @@ public class RestfulServer extends HttpServlet {
} catch (Throwable e) {
/*
* We have caught an exception while handling an incoming server request.
* Start by notifying the interceptors..
*/
for (int i = getInterceptors().size() - 1; i >= 0; i--) {
IServerInterceptor next = getInterceptors().get(i);
if (!next.handleException(requestDetails, e, theRequest, theResponse)) {
ourLog.debug("Interceptor {} returned false, not continuing processing");
return;
}
}
BaseOperationOutcome oo = null;
int statusCode = 500;
int statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
if (e instanceof BaseServerResponseException) {
oo = ((BaseServerResponseException) e).getOperationOutcome();
statusCode = ((BaseServerResponseException) e).getStatusCode();
}
/*
* Generate an OperationOutcome to return, unless the exception throw by
* the resource provider had one
*/
if (oo == null) {
try {
oo = (BaseOperationOutcome) myFhirContext.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
@ -651,7 +662,7 @@ public class RestfulServer extends HttpServlet {
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
throw new ServletException("Failed to instantiate OperationOutcome resource instance", e1);
}
BaseIssue issue = oo.addIssue();
issue.getSeverityElement().setValue("error");
if (e instanceof InternalErrorException) {
@ -659,11 +670,20 @@ public class RestfulServer extends HttpServlet {
issue.getDetailsElement().setValue(e.toString() + "\n\n" + ExceptionUtils.getStackTrace(e));
} else if (e instanceof BaseServerResponseException) {
ourLog.warn("Failure during REST processing: {}", e.toString());
statusCode = ((BaseServerResponseException) e).getStatusCode();
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) e;
statusCode = baseServerResponseException.getStatusCode();
issue.getDetailsElement().setValue(e.getMessage());
if (baseServerResponseException.getAdditionalMessages() != null) {
for (String next : baseServerResponseException.getAdditionalMessages()) {
BaseIssue issue2 = oo.addIssue();
issue2.getSeverityElement().setValue("error");
issue2.setDetails(next);
}
}
} else {
ourLog.error("Failure during REST processing", e);
ourLog.error("Failure during REST processing: " + e.toString(), e);
issue.getDetailsElement().setValue(e.toString() + "\n\n" + ExceptionUtils.getStackTrace(e));
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
}
} else {
ourLog.error("Unknown error during processing", e);
@ -683,9 +703,8 @@ public class RestfulServer extends HttpServlet {
}
/**
* Initializes the server. Note that this method is final to avoid accidentally introducing bugs in implementations,
* but subclasses may put initialization code in {@link #initialize()}, which is called immediately before beginning
* initialization of the restful server's internal init.
* Initializes the server. Note that this method is final to avoid accidentally introducing bugs in implementations, but subclasses may put initialization code in {@link #initialize()}, which is
* called immediately before beginning initialization of the restful server's internal init.
*/
@Override
public final void init() throws ServletException {
@ -693,11 +712,6 @@ public class RestfulServer extends HttpServlet {
try {
ourLog.info("Initializing HAPI FHIR restful server");
mySecurityManager = getSecurityManager();
if (null == mySecurityManager) {
ourLog.trace("No security manager has been provided");
}
ProvidedResourceScanner providedResourceScanner = new ProvidedResourceScanner(getFhirContext());
providedResourceScanner.scanForProvidedResources(this);
@ -737,14 +751,13 @@ public class RestfulServer extends HttpServlet {
ourLog.error("An error occurred while loading request handlers!", ex);
throw new ServletException("Failed to initialize FHIR Restful server", ex);
}
myStarted = true;
ourLog.info("A FHIR has been lit on this server");
}
/**
* This method may be overridden by subclasses to do perform initialization that needs to be performed prior to the
* server being used.
* This method may be overridden by subclasses to do perform initialization that needs to be performed prior to the server being used.
*/
protected void initialize() throws ServletException {
// nothing by default
@ -765,9 +778,8 @@ public class RestfulServer extends HttpServlet {
}
/**
* Sets the profile tagging behaviour for the server. When set to a value other than {@link AddProfileTagEnum#NEVER}
* (which is the default), the server will automatically add a profile tag based on the class of the resource(s)
* being returned.
* Sets the profile tagging behaviour for the server. When set to a value other than {@link AddProfileTagEnum#NEVER} (which is the default), the server will automatically add a profile tag based
* on the class of the resource(s) being returned.
*
* @param theAddProfileTag
* The behaviour enum (must not be null)
@ -786,7 +798,6 @@ public class RestfulServer extends HttpServlet {
myImplementationDescription = theImplementationDescription;
}
/**
* Sets (or clears) the list of interceptors
*
@ -862,15 +873,7 @@ public class RestfulServer extends HttpServlet {
}
/**
* Sets the security manager, or <code>null</code> if none
*/
public void setSecurityManager(ISecurityManager theSecurityManager) {
mySecurityManager = theSecurityManager;
}
/**
* Provide a server address strategy, which is used to determine what base URL to provide clients to refer to this
* server. Defaults to an instance of {@link IncomingRequestAddressStrategy}
* Provide a server address strategy, which is used to determine what base URL to provide clients to refer to this server. Defaults to an instance of {@link IncomingRequestAddressStrategy}
*/
public void setServerAddressStrategy(IServerAddressStrategy theServerAddressStrategy) {
Validate.notNull(theServerAddressStrategy, "Server address strategy can not be null");
@ -878,17 +881,14 @@ public class RestfulServer extends HttpServlet {
}
/**
* Returns the server conformance provider, which is the provider that is used to generate the server's conformance
* (metadata) statement.
* Returns the server conformance provider, which is the provider that is used to generate the server's conformance (metadata) statement.
* <p>
* By default, the {@link ServerConformanceProvider} is used, but this can be changed, or set to <code>null</code>
* if you do not wish to export a conformance statement.
* By default, the {@link ServerConformanceProvider} is used, but this can be changed, or set to <code>null</code> if you do not wish to export a conformance statement.
* </p>
* Note that this method can only be called before the server is initialized.
*
* @throws IllegalStateException
* Note that this method can only be called prior to {@link #init() initialization} and will throw an
* {@link IllegalStateException} if called after that.
* Note that this method can only be called prior to {@link #init() initialization} and will throw an {@link IllegalStateException} if called after that.
*/
public void setServerConformanceProvider(Object theServerConformanceProvider) {
if (myStarted) {
@ -898,24 +898,22 @@ public class RestfulServer extends HttpServlet {
}
/**
* Sets the server's name, as exported in conformance profiles exported by the server. This is informational only,
* but can be helpful to set with something appropriate.
* Sets the server's name, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
*/
public void setServerName(String theServerName) {
myServerName = theServerName;
}
/**
* Gets the server's version, as exported in conformance profiles exported by the server. This is informational
* only, but can be helpful to set with something appropriate.
* Gets the server's version, as exported in conformance profiles exported by the server. This is informational only, but can be helpful to set with something appropriate.
*/
public void setServerVersion(String theServerVersion) {
myServerVersion = theServerVersion;
}
/**
* If set to <code>true</code> (default is false), the server will use browser friendly content-types (instead of
* standard FHIR ones) when it detects that the request is coming from a browser instead of a FHIR
* If set to <code>true</code> (default is false), the server will use browser friendly content-types (instead of standard FHIR ones) when it detects that the request is coming from a browser
* instead of a FHIR
*/
public void setUseBrowserFriendlyContentTypes(boolean theUseBrowserFriendlyContentTypes) {
myUseBrowserFriendlyContentTypes = theUseBrowserFriendlyContentTypes;
@ -941,8 +939,8 @@ public class RestfulServer extends HttpServlet {
}
}
public static Bundle createBundleFromBundleProvider(RestfulServer theServer, HttpServletResponse theHttpResponse, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint, boolean theRequestIsBrowser,
NarrativeModeEnum theNarrativeMode, int theOffset, Integer theLimit, String theSearchId) {
public static Bundle createBundleFromBundleProvider(RestfulServer theServer, HttpServletResponse theHttpResponse, IBundleProvider theResult, EncodingEnum theResponseEncoding,
String theServerBase, String theCompleteUrl, boolean thePrettyPrint, boolean theRequestIsBrowser, NarrativeModeEnum theNarrativeMode, int theOffset, Integer theLimit, String theSearchId) {
theHttpResponse.setStatus(200);
if (theRequestIsBrowser && theServer.isUseBrowserFriendlyContentTypes()) {
@ -964,7 +962,7 @@ public class RestfulServer extends HttpServlet {
numToReturn = theResult.size();
resourceList = theResult.getResources(0, numToReturn);
validateResourceListNotNull(resourceList);
} else {
IPagingProvider pagingProvider = theServer.getPagingProvider();
if (theLimit == null) {
@ -1047,11 +1045,11 @@ public class RestfulServer extends HttpServlet {
Set<String> containedIds = new HashSet<String>();
for (IResource nextContained : next.getContained().getContainedResources()) {
if (nextContained.getId().isEmpty()==false) {
if (nextContained.getId().isEmpty() == false) {
containedIds.add(nextContained.getId().getValue());
}
}
if (theContext.getNarrativeGenerator() != null) {
String title = theContext.getNarrativeGenerator().generateTitle(next);
ourLog.trace("Narrative generator created title: {}", title);
@ -1074,7 +1072,7 @@ public class RestfulServer extends HttpServlet {
// Don't add contained IDs as top level resources
continue;
}
IdDt id = nextRes.getId().toVersionless();
if (id.hasResourceType() == false) {
String resName = theContext.getResourceDefinition(nextRes).getName();
@ -1190,9 +1188,7 @@ public class RestfulServer extends HttpServlet {
}
/**
* Determine whether a response should be given in JSON or XML format based on the
* incoming HttpServletRequest's <code>"_format"</code> parameter and <code>"Accept:"</code>
* HTTP header.
* Determine whether a response should be given in JSON or XML format based on the incoming HttpServletRequest's <code>"_format"</code> parameter and <code>"Accept:"</code> HTTP header.
*/
public static EncodingEnum determineResponseEncoding(HttpServletRequest theReq) {
String[] format = theReq.getParameterValues(Constants.PARAM_FORMAT);
@ -1285,8 +1281,8 @@ public class RestfulServer extends HttpServlet {
return prettyPrint;
}
public static void streamResponseAsBundle(RestfulServer theServer, HttpServletResponse theHttpResponse, Bundle bundle, EncodingEnum theResponseEncoding, String theServerBase, boolean thePrettyPrint, NarrativeModeEnum theNarrativeMode, boolean theRespondGzip)
throws IOException {
public static void streamResponseAsBundle(RestfulServer theServer, HttpServletResponse theHttpResponse, Bundle bundle, EncodingEnum theResponseEncoding, String theServerBase,
boolean thePrettyPrint, NarrativeModeEnum theNarrativeMode, boolean theRespondGzip) throws IOException {
assert !theServerBase.endsWith("/");
Writer writer = getWriter(theHttpResponse, theRespondGzip);
@ -1304,14 +1300,14 @@ public class RestfulServer extends HttpServlet {
}
}
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint, boolean theRequestIsBrowser, NarrativeModeEnum theNarrativeMode, boolean theRespondGzip,
String theServerBase) throws IOException {
public static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
boolean theRequestIsBrowser, NarrativeModeEnum theNarrativeMode, boolean theRespondGzip, String theServerBase) throws IOException {
int stausCode = 200;
streamResponseAsResource(theServer, theHttpResponse, theResource, theResponseEncoding, thePrettyPrint, theRequestIsBrowser, theNarrativeMode, stausCode, theRespondGzip, theServerBase);
}
private static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint, boolean theRequestIsBrowser, NarrativeModeEnum theNarrativeMode, int stausCode,
boolean theRespondGzip, String theServerBase) throws IOException {
private static void streamResponseAsResource(RestfulServer theServer, HttpServletResponse theHttpResponse, IResource theResource, EncodingEnum theResponseEncoding, boolean thePrettyPrint,
boolean theRequestIsBrowser, NarrativeModeEnum theNarrativeMode, int stausCode, boolean theRespondGzip, String theServerBase) throws IOException {
theHttpResponse.setStatus(stausCode);
if (theResource.getId() != null && theResource.getId().hasIdPart() && isNotBlank(theServerBase)) {

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
package ca.uhn.fhir.rest.server.exceptions;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
@ -27,9 +29,8 @@ import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
*/
/**
* Base class for RESTful client and server exceptions. RESTful client methods will only throw exceptions which are
* subclasses of this exception type, and RESTful server methods should also only call subclasses of this exception
* type.
* Base class for RESTful client and server exceptions. RESTful client methods will only throw exceptions which are subclasses of this exception type, and RESTful server methods should also only call
* subclasses of this exception type.
*/
public abstract class BaseServerResponseException extends RuntimeException {
@ -49,11 +50,12 @@ public abstract class BaseServerResponseException extends RuntimeException {
registerExceptionType(NotImplementedOperationException.STATUS_CODE, NotImplementedOperationException.class);
}
private List<String> myAdditionalMessages = null;
private BaseOperationOutcome myBaseOperationOutcome;
private String myResponseBody;
private String myResponseMimeType;
private int myStatusCode;
/**
* Constructor
*
@ -67,7 +69,24 @@ public abstract class BaseServerResponseException extends RuntimeException {
myStatusCode = theStatusCode;
myBaseOperationOutcome = null;
}
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theMessage
* The message
*/
public BaseServerResponseException(int theStatusCode, String... theMessages) {
super(theMessages != null && theMessages.length > 0 ? theMessages[0] : null);
myStatusCode = theStatusCode;
myBaseOperationOutcome = null;
if (theMessages != null && theMessages.length > 1) {
myAdditionalMessages = Arrays.asList(Arrays.copyOfRange(theMessages, 1, theMessages.length, String[].class));
}
}
/**
* Constructor
*
@ -151,6 +170,10 @@ public abstract class BaseServerResponseException extends RuntimeException {
myBaseOperationOutcome = theBaseOperationOutcome;
}
public List<String> getAdditionalMessages() {
return myAdditionalMessages;
}
/**
* Returns the {@link BaseOperationOutcome} resource if any which was supplied in the response, or <code>null</code>
*/
@ -159,8 +182,7 @@ public abstract class BaseServerResponseException extends RuntimeException {
}
/**
* In a RESTful client, this method will be populated with the body of the HTTP respone if one was provided by the
* server, or <code>null</code> otherwise.
* In a RESTful client, this method will be populated with the body of the HTTP respone if one was provided by the server, or <code>null</code> otherwise.
* <p>
* In a restful server, this method is currently ignored.
* </p>
@ -170,8 +192,7 @@ public abstract class BaseServerResponseException extends RuntimeException {
}
/**
* In a RESTful client, this method will be populated with the HTTP status code that was returned with the HTTP
* response.
* In a RESTful client, this method will be populated with the HTTP status code that was returned with the HTTP response.
* <p>
* In a restful server, this method is currently ignored.
* </p>
@ -193,6 +214,8 @@ public abstract class BaseServerResponseException extends RuntimeException {
* client implementations you should not call this method.
*
* @param theBaseOperationOutcome The BaseOperationOutcome resource
* Sets the BaseOperationOutcome 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.
*/
public void setOperationOutcome(BaseOperationOutcome theBaseOperationOutcome) {
myBaseOperationOutcome = theBaseOperationOutcome;

View File

@ -0,0 +1,301 @@
package ca.uhn.fhir.rest.server.exceptions;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
/*
* #%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%
*/
/**
* Base class for RESTful client and server exceptions. RESTful client methods will only throw exceptions which are subclasses of this exception type, and RESTful server methods should also only call
* subclasses of this exception type.
*/
public abstract class BaseServerResponseException extends RuntimeException {
private static final Map<Integer, Class<? extends BaseServerResponseException>> ourStatusCodeToExceptionType = new HashMap<Integer, Class<? extends BaseServerResponseException>>();
private static final long serialVersionUID = 1L;
static {
registerExceptionType(AuthenticationException.STATUS_CODE, AuthenticationException.class);
registerExceptionType(InternalErrorException.STATUS_CODE, InternalErrorException.class);
registerExceptionType(InvalidRequestException.STATUS_CODE, InvalidRequestException.class);
registerExceptionType(MethodNotAllowedException.STATUS_CODE, MethodNotAllowedException.class);
registerExceptionType(ResourceNotFoundException.STATUS_CODE, ResourceNotFoundException.class);
registerExceptionType(ResourceVersionNotSpecifiedException.STATUS_CODE, ResourceVersionNotSpecifiedException.class);
registerExceptionType(ResourceVersionConflictException.STATUS_CODE, ResourceVersionConflictException.class);
registerExceptionType(UnprocessableEntityException.STATUS_CODE, UnprocessableEntityException.class);
registerExceptionType(ResourceGoneException.STATUS_CODE, ResourceGoneException.class);
registerExceptionType(NotImplementedOperationException.STATUS_CODE, NotImplementedOperationException.class);
}
<<<<<<< HEAD
=======
private List<String> myAdditionalMessages = null;
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
private BaseOperationOutcome myBaseOperationOutcome;
private String myResponseBody;
private String myResponseMimeType;
private int myStatusCode;
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theMessage
* The message
*/
public BaseServerResponseException(int theStatusCode, String theMessage) {
super(theMessage);
myStatusCode = theStatusCode;
myBaseOperationOutcome = null;
<<<<<<< HEAD
=======
}
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theMessage
* The message
*/
public BaseServerResponseException(int theStatusCode, String... theMessages) {
super(theMessages != null && theMessages.length > 0 ? theMessages[0] : null);
myStatusCode = theStatusCode;
myBaseOperationOutcome = null;
if (theMessages != null && theMessages.length > 1) {
myAdditionalMessages = Arrays.asList(Arrays.copyOfRange(theMessages, 1, theMessages.length, String[].class));
}
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
}
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theMessage
* The message
* @param theBaseOperationOutcome
<<<<<<< HEAD
* An BaseOperationOutcome resource to return to the calling client (in a server) or the BaseOperationOutcome
* that was returned from the server (in a client)
=======
* An BaseOperationOutcome resource to return to the calling client (in a server) or the BaseOperationOutcome that was returned from the server (in a client)
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
*/
public BaseServerResponseException(int theStatusCode, String theMessage, BaseOperationOutcome theBaseOperationOutcome) {
super(theMessage);
myStatusCode = theStatusCode;
myBaseOperationOutcome = theBaseOperationOutcome;
}
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theMessage
* The message
* @param theCause
* The cause
*/
public BaseServerResponseException(int theStatusCode, String theMessage, Throwable theCause) {
super(theMessage, theCause);
myStatusCode = theStatusCode;
myBaseOperationOutcome = null;
}
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theMessage
* The message
* @param theCause
* The underlying cause exception
* @param theBaseOperationOutcome
<<<<<<< HEAD
* An BaseOperationOutcome resource to return to the calling client (in a server) or the BaseOperationOutcome
* that was returned from the server (in a client)
=======
* An BaseOperationOutcome resource to return to the calling client (in a server) or the BaseOperationOutcome that was returned from the server (in a client)
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
*/
public BaseServerResponseException(int theStatusCode, String theMessage, Throwable theCause, BaseOperationOutcome theBaseOperationOutcome) {
super(theMessage, theCause);
myStatusCode = theStatusCode;
myBaseOperationOutcome = theBaseOperationOutcome;
}
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theCause
* The underlying cause exception
*/
public BaseServerResponseException(int theStatusCode, Throwable theCause) {
super(theCause.toString(), theCause);
myStatusCode = theStatusCode;
myBaseOperationOutcome = null;
}
/**
* Constructor
*
* @param theStatusCode
* The HTTP status code corresponding to this problem
* @param theCause
* The underlying cause exception
* @param theBaseOperationOutcome
<<<<<<< HEAD
* An BaseOperationOutcome resource to return to the calling client (in a server) or the BaseOperationOutcome
* that was returned from the server (in a client)
=======
* An BaseOperationOutcome resource to return to the calling client (in a server) or the BaseOperationOutcome that was returned from the server (in a client)
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
*/
public BaseServerResponseException(int theStatusCode, Throwable theCause, BaseOperationOutcome theBaseOperationOutcome) {
super(theCause.toString(), theCause);
myStatusCode = theStatusCode;
myBaseOperationOutcome = theBaseOperationOutcome;
<<<<<<< HEAD
=======
}
public List<String> getAdditionalMessages() {
return myAdditionalMessages;
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
}
/**
* Returns the {@link BaseOperationOutcome} resource if any which was supplied in the response, or <code>null</code>
*/
public BaseOperationOutcome getOperationOutcome() {
return myBaseOperationOutcome;
}
/**
* In a RESTful client, this method will be populated with the body of the HTTP respone if one was provided by the server, or <code>null</code> otherwise.
* <p>
* In a restful server, this method is currently ignored.
* </p>
*/
public String getResponseBody() {
return myResponseBody;
}
/**
* In a RESTful client, this method will be populated with the HTTP status code that was returned with the HTTP response.
* <p>
* In a restful server, this method is currently ignored.
* </p>
*/
public String getResponseMimeType() {
return myResponseMimeType;
}
/**
* Returns the HTTP status code corresponding to this problem
*/
public int getStatusCode() {
return myStatusCode;
}
/**
<<<<<<< HEAD
* Sets the BaseOperationOutcome 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 theBaseOperationOutcome The BaseOperationOutcome resource
=======
* Sets the BaseOperationOutcome 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 theBaseOperationOutcome
* The BaseOperationOutcome resource
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
*/
public void setOperationOutcome(BaseOperationOutcome theBaseOperationOutcome) {
myBaseOperationOutcome = theBaseOperationOutcome;
}
/**
* This method is currently only called internally by HAPI, it should not be called by user code.
*/
public void setResponseBody(String theResponseBody) {
myResponseBody = theResponseBody;
}
/**
* This method is currently only called internally by HAPI, it should not be called by user code.
*/
public void setResponseMimeType(String 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) {
if (ourStatusCodeToExceptionType.containsKey(theStatusCode)) {
try {
return ourStatusCodeToExceptionType.get(theStatusCode).getConstructor(new Class[] { String.class }).newInstance(theMessage);
} catch (InstantiationException e) {
throw new InternalErrorException(e);
} catch (IllegalAccessException e) {
throw new InternalErrorException(e);
} catch (IllegalArgumentException e) {
throw new InternalErrorException(e);
} catch (InvocationTargetException e) {
throw new InternalErrorException(e);
} catch (NoSuchMethodException e) {
throw new InternalErrorException(e);
} catch (SecurityException e) {
throw new InternalErrorException(e);
}
} else {
return new UnclassifiedServerFailureException(theStatusCode, theMessage);
}
}
static void registerExceptionType(int theStatusCode, Class<? extends BaseServerResponseException> theType) {
if (ourStatusCodeToExceptionType.containsKey(theStatusCode)) {
throw new Error("Can not register " + theType + " to status code " + theStatusCode + " because " + ourStatusCodeToExceptionType.get(theStatusCode) + " already registers that code");
}
ourStatusCodeToExceptionType.put(theStatusCode, theType);
}
}

View File

@ -77,7 +77,7 @@ public class UnprocessableEntityException extends BaseServerResponseException {
* Constructor which accepts an array of Strings describing the issue. This strings will be translated into an {@link BaseOperationOutcome} resource which will be supplied in the response.
*/
public UnprocessableEntityException(String... theMessage) {
super(STATUS_CODE, theMessage[0]); // TODO: this used to generate an OperationOutcome - why?
super(STATUS_CODE, theMessage);
}
}

View File

@ -78,22 +78,10 @@ public class UnprocessableEntityException extends BaseServerResponseException {
*/
public UnprocessableEntityException(String... theMessage) {
<<<<<<< HEAD
super(STATUS_CODE, DEFAULT_MESSAGE, toOperationOutcome(theMessage));
}
private static OperationOutcome toOperationOutcome(String... theMessage) {
OperationOutcome OperationOutcome = new OperationOutcome();
if (theMessage != null) {
for (String next : theMessage) {
OperationOutcome.addIssue().setDetails(next);
}
}
return OperationOutcome;
=======
super(STATUS_CODE, theMessage[0]); // TODO: this used to generate an OperationOutcome - why?
>>>>>>> versions
=======
super(STATUS_CODE, theMessage);
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
}
}

View File

@ -37,6 +37,11 @@ import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
/**
* Provides methods to intercept requests and responses. Note that implementations of this interface may wish to use {@link InterceptorAdapter} in order to not need to implement every method.
* <p>
* <b>See:</b> See the
* <a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_server_interceptor.html">server interceptor documentation</a>
* for more information on how to use this class.
* </p>
*/
public interface IServerInterceptor {
@ -64,7 +69,8 @@ public interface IServerInterceptor {
* </p>
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theRequest
* The incoming request
* @param theResponse
@ -82,7 +88,8 @@ public interface IServerInterceptor {
* This method is called after the server implementation method has been called, but before any attempt to stream the response back to the client
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
@ -124,7 +131,8 @@ public interface IServerInterceptor {
* This method is called after the server implementation method has been called, but before any attempt to stream the response back to the client
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
@ -145,7 +153,8 @@ public interface IServerInterceptor {
* This method is called after the server implementation method has been called, but before any attempt to stream the response back to the client
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
@ -171,7 +180,9 @@ public interface IServerInterceptor {
* </p>
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including
* Contains either <code>null</code>, or a bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}. This parameter may be
* null if the request processing did not successfully parse the incoming request, but will generally not be null.
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest

View File

@ -0,0 +1,202 @@
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.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.exceptions.AuthenticationException;
/**
* Provides methods to intercept requests and responses. Note that implementations of this interface may wish to use {@link InterceptorAdapter} in order to not need to implement every method.
*/
public interface IServerInterceptor {
/**
* This method is called before any other processing takes place for each incoming request. It may be used to provide alternate handling for some requests, or to screen requests before they are
* handled, etc.
* <p>
* Note that any exceptions thrown by this method will not be trapped by HAPI (they will be passed up to the server)
* </p>
*
* @param theRequest
* The incoming request
* @param theResponse
* The response. Note that interceptors may choose to provide a response (i.e. by calling {@link HttpServletResponse#getWriter()}) but in that case it is important to return
* <code>false</code>
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do. If your interceptor is providing a response rather than letting HAPI handle the
* response normally, you must return <code>false</code>. In this case, no further processing will occur and no further interceptors will be called.
*/
public boolean incomingRequestPreProcessed(HttpServletRequest theRequest, HttpServletResponse theResponse);
/**
* This method is called just before the actual implementing server method is invoked.
* <p>
* Note about exceptions:
* </p>
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theRequest
* The incoming request
* @param theResponse
* The response. Note that interceptors may choose to provide a response (i.e. by calling {@link HttpServletResponse#getWriter()}) but in that case it is important to return
* <code>false</code>
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do. If your interceptor is providing a response rather than letting HAPI handle the
* response normally, you must return <code>false</code>. In this case, no further processing will occur and no further interceptors will be called.
* @throws AuthenticationException
* This exception may be thrown to indicate that the interceptor has detected an unauthorized access attempt. If thrown, processing will stop and an HTTP 401 will be returned to the
* client.
*/
public boolean incomingRequestPostProcessed(RequestDetails theRequestDetails, HttpServletRequest theRequest, HttpServletResponse theResponse) throws AuthenticationException;
/**
* This method is called after the server implementation method has been called, but before any attempt to stream the response back to the client
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
* The incoming request
* @param theResponse
* The response. Note that interceptors may choose to provide a response (i.e. by calling {@link HttpServletResponse#getWriter()}) but in that case it is important to return
* <code>false</code>
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do. If your interceptor is providing a response rather than letting HAPI handle the
* response normally, you must return <code>false</code>. In this case, no further processing will occur and no further interceptors will be called.
* @throws AuthenticationException
* This exception may be thrown to indicate that the interceptor has detected an unauthorized access attempt. If thrown, processing will stop and an HTTP 401 will be returned to the
* client.
*/
public boolean outgoingResponse(RequestDetails theRequestDetails, TagList theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
throws AuthenticationException;
/**
* This method is called after the server implementation method has been called, but before any attempt to stream the response back to the client
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
* The incoming request
* @param theResponse
* The response. Note that interceptors may choose to provide a response (i.e. by calling {@link HttpServletResponse#getWriter()}) but in that case it is important to return
* <code>false</code>
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do. If your interceptor is providing a response rather than letting HAPI handle the
* response normally, you must return <code>false</code>. In this case, no further processing will occur and no further interceptors will be called.
* @throws AuthenticationException
* This exception may be thrown to indicate that the interceptor has detected an unauthorized access attempt. If thrown, processing will stop and an HTTP 401 will be returned to the
* client.
*/
public boolean outgoingResponse(RequestDetails theRequestDetails, Bundle theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
throws AuthenticationException;
/**
* This method is called after the server implementation method has been called, but before any attempt to stream the response back to the client
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
* The incoming request
* @param theResponse
* The response. Note that interceptors may choose to provide a response (i.e. by calling {@link HttpServletResponse#getWriter()}) but in that case it is important to return
* <code>false</code>
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do. If your interceptor is providing a response rather than letting HAPI handle the
* response normally, you must return <code>false</code>. In this case, no further processing will occur and no further interceptors will be called.
* @throws AuthenticationException
* This exception may be thrown to indicate that the interceptor has detected an unauthorized access attempt. If thrown, processing will stop and an HTTP 401 will be returned to the
* client.
*/
public boolean outgoingResponse(RequestDetails theRequestDetails, IResource theResponseObject, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse)
throws AuthenticationException;
/**
* This method is called after the server implementation method has been called, but before any attempt to stream the response back to the client
*
* @param theRequestDetails
* A bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}.
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
* The incoming request
* @param theResponse
* The response. Note that interceptors may choose to provide a response (i.e. by calling {@link HttpServletResponse#getWriter()}) but in that case it is important to return
* <code>false</code>
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do. If your interceptor is providing a response rather than letting HAPI handle the
* response normally, you must return <code>false</code>. In this case, no further processing will occur and no further interceptors will be called.
* @throws AuthenticationException
* This exception may be thrown to indicate that the interceptor has detected an unauthorized access attempt. If thrown, processing will stop and an HTTP 401 will be returned to the
* client.
*/
public boolean outgoingResponse(RequestDetails theRequestDetails, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws AuthenticationException;
/**
* This method is called upon any exception being thrown within the server's request processing code. This includes any exceptions thrown within resource provider methods (e.g. {@link Search} and
* {@link Read} methods) as well as any runtime exceptions thrown by the server itself. This also includes any {@link AuthenticationException}s thrown.
* <p>
* Implementations of this method may choose to ignore/log/count/etc exceptions, and return <code>true</code>. In this case, processing will continue, and the server will automatically generate an
* {@link BaseOperationOutcome OperationOutcome}. Implementations may also choose to provide their own response to the client. In this case, they should return <code>false</code>, to indicate that
* they have handled the request and processing should stop.
* </p>
*
* @param theRequestDetails
<<<<<<< HEAD
* A bean containing details about the request that is about to be processed, including
=======
* Contains either <code>null</code>, or a bean containing details about the request that is about to be processed, including details such as the resource type and logical ID (if any) and other
* FHIR-specific aspects of the request which have been pulled out of the {@link HttpServletRequest servlet request}. This parameter may be
* null if the request processing did not successfully parse the incoming request, but will generally not be null.
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
* @param theResponseObject
* The actual object which is being streamed to the client as a response
* @param theRequest
* The incoming request
* @param theResponse
* The response. Note that interceptors may choose to provide a response (i.e. by calling {@link HttpServletResponse#getWriter()}) but in that case it is important to return
* <code>false</code>
* @return Return <code>true</code> if processing should continue normally. This is generally the right thing to do. If your interceptor is providing a response rather than letting HAPI handle the
* response normally, you must return <code>false</code>. In this case, no further processing will occur and no further interceptors will be called.
* @throws ServletException
* If this exception is thrown, it will be re-thrown up to the container for handling.
* @throws IOException
* If this exception is thrown, it will be re-thrown up to the container for handling.
*/
public boolean handleException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theServletRequest, HttpServletResponse theServletResponse) throws ServletException,
IOException;
}

View File

@ -357,6 +357,8 @@ public class XmlUtil {
case '"':
case '&':
hasEscapable = true;
default:
break;
}
}

View File

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

View File

@ -6,23 +6,20 @@
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<dependent-module archiveName="hapi-fhir-jpaserver-base-0.8-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-jpaserver-base/hapi-fhir-jpaserver-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="hapi-fhir-base-0.8-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="hapi-fhir-structures-dstu-0.8-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-structures-dstu/hapi-fhir-structures-dstu">
<dependency-type>uses</dependency-type>
</dependent-module>
<<<<<<< HEAD
<dependent-module archiveName="hapi-fhir-jpaserver-base-0.6.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-jpaserver-base/hapi-fhir-jpaserver-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="hapi-fhir-base-0.6.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.6/hapi-fhir-testpage-overlay-0.6.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
=======
<dependent-module archiveName="hapi-fhir-jpaserver-base-0.7-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-jpaserver-base/hapi-fhir-jpaserver-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="hapi-fhir-base-0.7-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.7-SNAPSHOT/hapi-fhir-testpage-overlay-0.7-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
>>>>>>> cdd4b137fb40dd72f895c2bcb644d6e668e1015b
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.8-SNAPSHOT/hapi-fhir-testpage-overlay-0.8-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
<dependency-type>consumes</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">

View File

@ -12,7 +12,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="src/test/resources"/>
<classpathentry including="**/*.java" kind="src" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>

View File

@ -1,4 +1,5 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8

View File

@ -1 +1,4 @@
/target/
/.settings/
.classpath
.project

View File

@ -0,0 +1,7 @@
/target/
<<<<<<< HEAD
/.settings/
.classpath
.project
=======
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2

View File

@ -1,30 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry including="**/*.java" kind="src" path="src/test/resources"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/tinder"/>
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.nondependency" value=""/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -2,3 +2,6 @@
/target
*.log
*.log*
/.settings/
.classpath
.project

View File

@ -1,5 +0,0 @@
eclipse.preferences.version=1
encoding//src/main/java=UTF-8
encoding//src/test/java=UTF-8
encoding//src/test/resources=UTF-8
encoding/<project>=UTF-8

View File

@ -1,12 +0,0 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -1,4 +0,0 @@
activeProfiles=
eclipse.preferences.version=1
resolveWorkspaceProjects=true
version=1

View File

@ -1,3 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
<wb-module deploy-name="hapi-fhir-structures-dstu"/>
<wb-module deploy-name="hapi-fhir-structures-dstu">
<wb-resource deploy-path="/" source-path="/src/main/java"/>
<wb-resource deploy-path="/" source-path="/target/generated-resources/tinder"/>
<wb-resource deploy-path="/" source-path="/target/generated-sources/tinder"/>
</wb-module>
</project-modules>

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<installed facet="java" version="1.6"/>
<installed facet="jst.utility" version="1.0"/>
<installed facet="java" version="1.6"/>
</faceted-project>

View File

@ -11,7 +11,7 @@ import ca.uhn.fhir.model.primitive.StringDt;
* Created by Bill de Beaubien on 10/31/2014.
*/
@ResourceDef(name="Observation", id="customobservation")
class CustomObservation extends Observation {
public class CustomObservation extends Observation {
@Child(name = "valueUnits", order = 3)
@Extension(url = "http://hapi.test.com/profile/customobservation#valueUnits", definedLocally = true, isModifier = false)
@Description(shortDefinition = "Units on an observation whose type is of valueString")

View File

@ -0,0 +1,34 @@
package ca.uhn.fhir.context;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.model.api.annotation.Extension;
import ca.uhn.fhir.model.api.annotation.ResourceDef;
import ca.uhn.fhir.model.dstu.resource.Observation;
import ca.uhn.fhir.model.primitive.StringDt;
/**
* Created by Bill de Beaubien on 10/31/2014.
*/
@ResourceDef(name="Observation", id="customobservation")
<<<<<<< HEAD
public class CustomObservation extends Observation {
=======
class CustomObservation extends Observation {
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
@Child(name = "valueUnits", order = 3)
@Extension(url = "http://hapi.test.com/profile/customobservation#valueUnits", definedLocally = true, isModifier = false)
@Description(shortDefinition = "Units on an observation whose type is of valueString")
private StringDt myValueUnits;
public StringDt getValueUnits() {
if (myValueUnits == null) {
myValueUnits = new StringDt();
}
return myValueUnits;
}
public void setValueUnits(StringDt theValueUnits) {
myValueUnits = theValueUnits;
}
}

View File

@ -1,5 +1,7 @@
package ca.uhn.fhir.context;
import static org.junit.Assert.*;
import org.junit.Test;
import ca.uhn.fhir.model.dstu.resource.Patient;
@ -15,4 +17,10 @@ public class FhirContextTest {
ctx.getResourceDefinition(Patient.class);
}
@Test
public void testFindBinary() {
RuntimeResourceDefinition def = new FhirContext().getResourceDefinition("Binary");
assertEquals("Binary", def.getName());
}
}

View File

@ -87,6 +87,13 @@ public class XmlParserTest {
System.setProperty("file.encoding", "ISO-8859-1");
}
@Test
public void testProfileWithBoundCode() throws IOException {
String content = IOUtils.toString(XmlParserTest.class.getResourceAsStream("/DMIXAuditException.xml"));
ourCtx.newXmlParser().parseResource(Profile.class, content);
}
@Test
public void testEncodeNonContained() {
// Create an organization

View File

@ -8,7 +8,6 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.uhn.fhir.rest.method.QualifiedParamList;
@ -16,13 +15,40 @@ import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
public class DateRangeParamTest {
private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException {
DateRangeParam p = new DateRangeParam();
List<QualifiedParamList> tokens = new ArrayList<QualifiedParamList>();
tokens.add(QualifiedParamList.singleton(null, theLower));
if (theUpper != null) {
tokens.add(QualifiedParamList.singleton(null, theUpper));
}
p.setValuesAsQueryTokens(tokens);
return p;
}
public static Date parse(String theString) throws ParseException {
return ourFmt.parse(theString);
}
public static Date parseM1(String theString) throws ParseException {
return new Date(ourFmt.parse(theString).getTime() - 1L);
}
private static SimpleDateFormat ourFmt;
static {
ourFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
}
private DateRangeParam create(String theString) {
return new DateRangeParam(new DateParam(theString));
}
@Test
public void testDay() throws Exception {
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getLowerBoundAsInstant());
assertEquals(parseM1("2011-01-02 00:00:00.0000"), create(">=2011-01-01", "<2011-01-02").getUpperBoundAsInstant());
assertEquals(parse("2011-01-02 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getLowerBoundAsInstant());
assertEquals(parseM1("2011-01-03 00:00:00.0000"), create(">2011-01-01", "<=2011-01-02").getUpperBoundAsInstant());
}
@ -31,7 +57,7 @@ public class DateRangeParamTest {
public void testFromQualifiedDateParam() throws Exception {
assertEquals(parse("2011-01-01 00:00:00.0000"), create("2011-01-01").getLowerBoundAsInstant());
assertEquals(parseM1("2011-01-02 00:00:00.0000"), create("2011-01-01").getUpperBoundAsInstant());
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01").getLowerBoundAsInstant());
assertEquals(null, create(">=2011-01-01").getUpperBoundAsInstant());
@ -43,16 +69,22 @@ public class DateRangeParamTest {
public void testMonth() throws Exception {
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01", "<2011-02").getLowerBoundAsInstant());
assertEquals(parseM1("2011-02-01 00:00:00.0000"), create(">=2011-01", "<2011-02").getUpperBoundAsInstant());
assertEquals(parse("2011-02-01 00:00:00.0000"), create(">2011-01", "<=2011-02").getLowerBoundAsInstant());
assertEquals(parseM1("2011-03-01 00:00:00.0000"), create(">2011-01", "<=2011-02").getUpperBoundAsInstant());
}
@Test
public void testOnlyOneParam() throws Exception {
assertEquals(parse("2011-01-01 00:00:00.0000"), create("2011-01-01").getLowerBoundAsInstant());
assertEquals(parseM1("2011-01-02 00:00:00.0000"), create("2011-01-01").getUpperBoundAsInstant());
}
@Test
public void testSecond() throws Exception {
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011-01-01T00:00:00", "<2011-01-01T01:00:00").getLowerBoundAsInstant());
assertEquals(parseM1("2011-01-01 02:00:00.0000"), create(">=2011-01-01T00:00:00", "<2011-01-01T02:00:00").getUpperBoundAsInstant());
assertEquals(parse("2011-01-01 00:00:01.0000"), create(">2011-01-01T00:00:00", "<=2011-01-01T02:00:00").getLowerBoundAsInstant());
assertEquals(parseM1("2011-01-01 02:00:01.0000"), create(">2011-01-01T00:00:00", "<=2011-01-01T02:00:00").getUpperBoundAsInstant());
}
@ -61,40 +93,9 @@ public class DateRangeParamTest {
public void testYear() throws Exception {
assertEquals(parse("2011-01-01 00:00:00.0000"), create(">=2011", "<2012").getLowerBoundAsInstant());
assertEquals(parseM1("2012-01-01 00:00:00.0000"), create(">=2011", "<2012").getUpperBoundAsInstant());
assertEquals(parse("2012-01-01 00:00:00.0000"), create(">2011", "<=2012").getLowerBoundAsInstant());
assertEquals(parseM1("2014-01-01 00:00:00.0000"), create(">2011", "<=2013").getUpperBoundAsInstant());
}
private DateRangeParam create(String theString) {
return new DateRangeParam(new QualifiedDateParam(theString));
}
private Date parse(String theString) throws ParseException {
return ourFmt.parse(theString);
}
private Date parseM1(String theString) throws ParseException {
return new Date(ourFmt.parse(theString).getTime() - 1L);
}
private Date parseP1(String theString) throws ParseException {
return new Date(ourFmt.parse(theString).getTime() + 1L);
}
@BeforeClass
public static void beforeClass() {
ourFmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSS");
}
private static DateRangeParam create(String theLower, String theUpper) throws InvalidRequestException {
DateRangeParam p = new DateRangeParam();
List<QualifiedParamList> tokens=new ArrayList<QualifiedParamList>();
tokens.add(QualifiedParamList.singleton(null,theLower));
tokens.add(QualifiedParamList.singleton(null,theUpper));
p.setValuesAsQueryTokens(tokens);
return p;
}
}

View File

@ -0,0 +1,131 @@
package ca.uhn.fhir.rest.server;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.DateRangeParam;
import ca.uhn.fhir.rest.param.DateRangeParamTest;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class DateRangeParamSearchTest {
private static CloseableHttpClient ourClient;
private static int ourPort;
private static Server ourServer;
@Test
public void testSearchForOneUnqualifiedDate() throws Exception {
String baseUrl = "http://localhost:" + ourPort + "/Patient?" + Patient.SP_BIRTHDATE + "=";
HttpGet httpGet = new HttpGet(baseUrl + "2012-01-01");
HttpResponse status = ourClient.execute(httpGet);
IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals("2012-01-01", ourLastDateRange.getLowerBound().getValueAsString());
assertEquals("2012-01-01", ourLastDateRange.getUpperBound().getValueAsString());
assertEquals(DateRangeParamTest.parse("2012-01-01 00:00:00.0000"), ourLastDateRange.getLowerBoundAsInstant());
assertEquals(DateRangeParamTest.parseM1("2012-01-02 00:00:00.0000"), ourLastDateRange.getUpperBoundAsInstant());
}
@Test
public void testSearchForMultipleUnqualifiedDate() throws Exception {
String baseUrl = "http://localhost:" + ourPort + "/Patient?" + Patient.SP_BIRTHDATE + "=";
HttpGet httpGet = new HttpGet(baseUrl + "2012-01-01&" + Patient.SP_BIRTHDATE + "=2012-02-03");
HttpResponse status = ourClient.execute(httpGet);
IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(400, status.getStatusLine().getStatusCode());
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
}
@Before
public void before() {
ourLastDateRange = null;
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
ServletHandler proxyHandler = new ServletHandler();
RestfulServer servlet = new RestfulServer();
servlet.getFhirContext().setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
servlet.setResourceProviders(patientProvider);
ServletHolder servletHolder = new ServletHolder(servlet);
proxyHandler.addServletWithMapping(servletHolder, "/*");
ourServer.setHandler(proxyHandler);
ourServer.start();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
ourClient = builder.build();
}
private static DateRangeParam ourLastDateRange;
/**
* Created by dsotnikov on 2/25/2014.
*/
public static class DummyPatientResourceProvider implements IResourceProvider {
@Search()
public List<Patient> search(@RequiredParam(name=Patient.SP_BIRTHDATE) DateRangeParam theDateRange) {
ourLastDateRange = theDateRange;
ArrayList<Patient> retVal = new ArrayList<Patient>();
Patient patient = new Patient();
patient.setId("1");
patient.addIdentifier("system", "hello");
retVal.add(patient);
return retVal;
}
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
}
}

View File

@ -33,6 +33,7 @@ import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.PortUtil;
/**
@ -54,6 +55,21 @@ public class ExceptionTest {
ourExceptionType=null;
}
@Test
public void testThrowUnprocessableEntityWithMultipleMessages() throws Exception {
{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?throwUnprocessableEntityWithMultipleMessages=aaa");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(422, status.getStatusLine().getStatusCode());
OperationOutcome oo = (OperationOutcome) servlet.getFhirContext().newXmlParser().parseResource(responseContent);
assertThat(oo.getIssueFirstRep().getDetails().getValue(), StringContains.containsString("message1"));
assertEquals(3, oo.getIssue().size());
}
}
@Test
public void testInternalError() throws Exception {
{
@ -162,10 +178,15 @@ public class ExceptionTest {
@Search
public List<Patient> findPatient(@RequiredParam(name = "throwInternalError") StringParam theParam) {
public List<Patient> throwInternalError(@RequiredParam(name = "throwInternalError") StringParam theParam) {
throw new InternalErrorException("Exception Text");
}
@Search
public List<Patient> throwUnprocessableEntityWithMultipleMessages(@RequiredParam(name = "throwUnprocessableEntityWithMultipleMessages") StringParam theParam) {
throw new UnprocessableEntityException("message1", "message2", "message3");
}
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;

View File

@ -1378,11 +1378,6 @@ public class ResfulServerMethodTest {
return myResourceProviders;
}
@Override
public ISecurityManager getSecurityManager() {
return null;
}
}
}

View File

@ -0,0 +1,165 @@
package ca.uhn.fhir.rest.server.interceptor;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hamcrest.core.StringContains;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.slf4j.Logger;
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.RequiredParam;
import ca.uhn.fhir.rest.annotation.Search;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.util.PortUtil;
public class ExceptionHandlingInterceptorTest {
private static CloseableHttpClient ourClient;
private static int ourPort;
private static Server ourServer;
private static RestfulServer servlet;
private IServerInterceptor myInterceptor;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionHandlingInterceptorTest.class);
@Test
public void testThrowUnprocessableEntityException() throws Exception {
when(myInterceptor.incomingRequestPreProcessed(any(HttpServletRequest.class), any(HttpServletResponse.class))).thenReturn(true);
when(myInterceptor.incomingRequestPostProcessed(any(RequestDetails.class), any(HttpServletRequest.class), any(HttpServletResponse.class))).thenReturn(true);
when(myInterceptor.handleException(any(RequestDetails.class), any(Throwable.class), any(HttpServletRequest.class), any(HttpServletResponse.class))).thenReturn(true);
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=throwUnprocessableEntityException");
HttpResponse status = ourClient.execute(httpGet);
ourLog.info(IOUtils.toString(status.getEntity().getContent()));
assertEquals(422, status.getStatusLine().getStatusCode());
IOUtils.closeQuietly(status.getEntity().getContent());
ArgumentCaptor<Throwable> captor = ArgumentCaptor.forClass(Throwable.class);
verify(myInterceptor, times(1)).handleException(any(RequestDetails.class), captor.capture(), any(HttpServletRequest.class), any(HttpServletResponse.class));
assertEquals(UnprocessableEntityException.class, captor.getValue().getClass());
}
@Test
public void testThrowUnprocessableEntityExceptionAndOverrideResponse() throws Exception {
when(myInterceptor.incomingRequestPreProcessed(any(HttpServletRequest.class), any(HttpServletResponse.class))).thenReturn(true);
when(myInterceptor.incomingRequestPostProcessed(any(RequestDetails.class), any(HttpServletRequest.class), any(HttpServletResponse.class))).thenReturn(true);
when(myInterceptor.handleException(any(RequestDetails.class), any(Throwable.class), any(HttpServletRequest.class), any(HttpServletResponse.class))).thenAnswer(new Answer<Boolean>() {
@Override
public Boolean answer(InvocationOnMock theInvocation) throws Throwable {
HttpServletResponse resp = (HttpServletResponse) theInvocation.getArguments()[3];
resp.setStatus(405);
resp.setContentType("text/plain");
resp.getWriter().write("HELP IM A BUG");
resp.getWriter().close();
return false;
}
});
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?_query=throwUnprocessableEntityException");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(405, status.getStatusLine().getStatusCode());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals("HELP IM A BUG", responseContent);
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
}
@Before
public void before() {
myInterceptor = mock(IServerInterceptor.class);
servlet.setInterceptors(Collections.singletonList(myInterceptor));
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
ServletHandler proxyHandler = new ServletHandler();
servlet = new RestfulServer();
servlet.setResourceProviders(patientProvider);
ServletHolder servletHolder = new ServletHolder(servlet);
proxyHandler.addServletWithMapping(servletHolder, "/*");
ourServer.setHandler(proxyHandler);
ourServer.start();
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
HttpClientBuilder builder = HttpClientBuilder.create();
builder.setConnectionManager(connectionManager);
ourClient = builder.build();
}
/**
* Created by dsotnikov on 2/25/2014.
*/
public static class DummyPatientResourceProvider implements IResourceProvider {
/**
* Retrieve the resource by its identifier
*
* @param theId
* The resource identity
* @return The resource
*/
@Search(queryName = "throwUnprocessableEntityException")
public List<Patient> throwUnprocessableEntityException() {
throw new UnprocessableEntityException("Unprocessable!");
}
@Override
public Class<Patient> getResourceType() {
return Patient.class;
}
}
}

View File

@ -0,0 +1,780 @@
<?xml version="1.0" encoding="utf-8"?>
<Profile xmlns="http://hl7.org/fhir">
<version value="1.0" />
<name value="Audit Exception Profile" />
<description value="DMIXFP-10 v1.0 Initial version" />
<status value="draft" />
<fhirVersion value="0.0.81" />
<mapping>
<identity value="rim" />
<uri value="http://hl7.org/v3" />
<name value="RIM" />
</mapping>
<mapping>
<identity value="dicom" />
<uri value="http://nema.org/dicom" />
<name value="DICOM" />
</mapping>
<structure>
<type value="SecurityEvent" />
<name value="MySecurityEvent" />
<publish value="true" />
<element>
<path value="SecurityEvent" />
<definition>
<short value="Event record kept for security purposes" />
<formal value="A record of an event made for purposes of maintaining a security log. Typical uses include detection of intrusion attempts and monitoring for inappropriate usage." />
<comments value="Based on ATNA (RFC 3881)." />
<min value="1" />
<max value="1" />
<type>
<code value="Resource" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="ControlAct[moodCode=EVN]" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="Message" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event" />
<definition>
<short value="What was done" />
<formal value="Identifies the name, action type, time, and disposition of the audited event." />
<min value="1" />
<max value="1" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="N/A (no nesting in v3)" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="EventIdentification" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event.type" />
<definition>
<short value="Type/identifier of event" />
<formal value="Identifier for a family of the event." />
<comments value="e.g., a menu item, program, rule, policy, function code, application name or URL. It identifies the performed function." />
<min value="1" />
<max value="1" />
<type>
<code value="CodeableConcept" />
</type>
<isModifier value="false" />
<binding>
<name value="SecurityEventType" />
<isExtensible value="true" />
<conformance value="preferred" />
<referenceResource>
<reference value="http://hl7.org/fhir/vs/security-event-type" />
</referenceResource>
</binding>
<mapping>
<identity value="rim" />
<map value=".code (type, subtype and action are pre-coordinated or sent as translations)" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="@EventId" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event.type.coding" />
<definition>
<short value="Code defined by a terminology system" />
<formal value="A reference to a code defined by a terminology system." />
<comments value="Codes may be defined very casually in enumerations, or code lists, up to very formal definitions such as SNOMED CT - see the V3 Core Principles for more information. Ordering of codings is undefined and SHALL not be used to infer meaning." />
<min value="0" />
<max value="*" />
<type>
<code value="Coding" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="union(., ./translation)" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.1-8, C*E.10-22" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event.type.coding.system" />
<definition>
<short value="Identity of the terminology system" />
<formal value="The identification of the code system that defines the meaning of the symbol in the code." />
<comments value="The URI may be an OID (urn:oid:...) or a UUID (urn:uuid:...). OIDs and UUIDs SHALL be references to the HL7 OID registry. Otherwise, the URI should come from HL7's list of FHIR defined special URIs or it should de-reference to some definition that establish the system clearly and unambiguously." />
<min value="1" />
<max value="1" />
<type>
<code value="uri" />
</type>
<valueUri value="http://dmix.gov/fhir/securityprofile" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./codeSystem" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.3" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event.type.coding.code" />
<definition>
<short value="Symbol in syntax defined by the system" />
<formal value="A symbol in syntax defined by the system. The symbol may be a predefined code or an expression in a syntax defined by the coding system (e.g. post-coordination)." />
<min value="1" />
<max value="1" />
<type>
<code value="code" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./code" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.1" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event.subtype" />
<definition>
<short value="More specific type/id for the event" />
<formal value="Identifier for the category of event." />
<min value="0" />
<max value="*" />
<type>
<code value="CodeableConcept" />
</type>
<isModifier value="false" />
<binding>
<name value="SecurityEventSubType" />
<isExtensible value="true" />
<conformance value="preferred" />
<referenceResource>
<reference value="http://hl7.org/fhir/vs/security-event-sub-type" />
</referenceResource>
</binding>
<mapping>
<identity value="rim" />
<map value=".code (type, subtype and action are pre-coordinated or sent as translations)" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="@EventTypeCode" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event.subtype.coding" />
<definition>
<short value="Code defined by a terminology system" />
<formal value="A reference to a code defined by a terminology system." />
<comments value="Codes may be defined very casually in enumerations, or code lists, up to very formal definitions such as SNOMED CT - see the V3 Core Principles for more information. Ordering of codings is undefined and SHALL not be used to infer meaning." />
<min value="0" />
<max value="*" />
<type>
<code value="Coding" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="union(., ./translation)" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.1-8, C*E.10-22" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.event.subtype.coding.system" />
<definition>
<short value="Identity of the terminology system" />
<formal value="The identification of the code system that defines the meaning of the symbol in the code." />
<comments value="The URI may be an OID (urn:oid:...) or a UUID (urn:uuid:...). OIDs and UUIDs SHALL be references to the HL7 OID registry. Otherwise, the URI should come from HL7's list of FHIR defined special URIs or it should de-reference to some definition that establish the system clearly and unambiguously." />
<min value="0" />
<max value="1" />
<type>
<code value="uri" />
</type>
<valueUri value="http://dmix.gov/fhir/securityprofile" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./codeSystem" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.3" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.participant" />
<definition>
<short value="A person, a hardware device or software process" />
<formal value="A person, a hardware device or software process." />
<comments value="There may be more than one user per event, for example, in cases of actions initiated by one user for other users, or in events that involve more than one user, hardware device, or system process. However, only one user may be the initiator/requestor for the event." />
<min value="1" />
<max value="*" />
<constraint>
<key value="3" />
<name value="Participant Identification" />
<severity value="error" />
<human value="Either a userId or a reference, but not both" />
<xpath value="exists(f:userId) != exists(f:reference)" />
</constraint>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".participation" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="ActiveParticipant" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.participant.role" />
<definition>
<short value="User roles (e.g. local RBAC codes)" />
<formal value="Specification of the role(s) the user plays when performing the event. Usually the codes used in this element are local codes defined by the role-based access control security system used in the local context." />
<min value="0" />
<max value="*" />
<type>
<code value="CodeableConcept" />
</type>
<isModifier value="false" />
<binding>
<name value="DICOMRoleId" />
<isExtensible value="true" />
<conformance value="preferred" />
<referenceResource>
<reference value="http://hl7.org/fhir/vs/dicm-402-roleid" />
</referenceResource>
</binding>
<mapping>
<identity value="rim" />
<map value=".typeCode and/or .functionCode" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="RoleIdCode" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.participant.role.coding" />
<definition>
<short value="Code defined by a terminology system" />
<formal value="A reference to a code defined by a terminology system." />
<comments value="Codes may be defined very casually in enumerations, or code lists, up to very formal definitions such as SNOMED CT - see the V3 Core Principles for more information. Ordering of codings is undefined and SHALL not be used to infer meaning." />
<min value="0" />
<max value="*" />
<type>
<code value="Coding" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="union(., ./translation)" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.1-8, C*E.10-22" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.participant.role.coding.system" />
<definition>
<short value="Identity of the terminology system" />
<formal value="The identification of the code system that defines the meaning of the symbol in the code." />
<comments value="The URI may be an OID (urn:oid:...) or a UUID (urn:uuid:...). OIDs and UUIDs SHALL be references to the HL7 OID registry. Otherwise, the URI should come from HL7's list of FHIR defined special URIs or it should de-reference to some definition that establish the system clearly and unambiguously." />
<min value="0" />
<max value="1" />
<type>
<code value="uri" />
</type>
<valueUri value="http://dmix.gov/fhir/securityprofile" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./codeSystem" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.3" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.source" />
<definition>
<short value="Application systems and processes" />
<formal value="Application systems and processes." />
<comments value="Since multi-tier, distributed, or composite applications make source identification ambiguous, this collection of fields may repeat for each application or process actively involved in the event. For example, multiple value-sets can identify participating web servers, application processes, and database server threads in an n-tier distributed application. Passive event participants, e.g., low-level network transports, need not be identified." />
<min value="1" />
<max value="1" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".participation[typeCode=INF].role[classCode=ASSIGN].player[classCode=DEV, determinerCode=INSTANCE]" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="AuditSourceIdentification" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.source.site" />
<definition>
<short value="Logical source location within the enterprise" />
<formal value="Logical source location within the healthcare enterprise network." />
<comments value="a hospital or other provider location within a multi-entity provider group." />
<min value="1" />
<max value="1" />
<type>
<code value="string" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".scopedRole[classCode=LOCE].player.desc" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="@AuditEnterpriseSiteId" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object" />
<definition>
<short value="Specific instances of data or objects that have been accessed" />
<formal value="Specific instances of data or objects that have been accessed." />
<comments value="required unless the values for Event Identification, Active Participant Identification, and Audit Source Identification are sufficient to document the entire auditable event. Because events may have more than one participant object, this group can be a repeating set of values." />
<min value="0" />
<max value="*" />
<constraint>
<key value="2" />
<name value="Object Identification" />
<severity value="error" />
<human value="Either an identifier or a reference, but not both" />
<xpath value="exists(f:identifier) != exists(f:reference)" />
</constraint>
<constraint>
<key value="1" />
<name value="Object Name" />
<severity value="error" />
<human value="Either a name or a query (or both)" />
<xpath value="not(exists(f:name)) or not(exists(f:query))" />
</constraint>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".outboundRelationship[typeCode=SUBJ].target or .participation[typeCode=SBJ].role" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="ParticipantObjectIdentification" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.identifier" />
<definition>
<short value="Specific instance of object (e.g. versioned)" />
<formal value="Identifies a specific instance of the participant object. The reference should always be version specific." />
<comments value="Identifier details depends on object type." />
<min value="0" />
<max value="1" />
<type>
<code value="Identifier" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".id.extension" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="@ParticipantObjectID" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.identifier.use" />
<definition>
<short value="usual | official | temp | secondary (If known)" />
<formal value="The purpose of this identifier." />
<comments value="This is labeled as &quot;Is Modifier&quot; because applications should not mistake a temporary id for a permanent one. Applications can assume that an identifier is permanent unless it explicitly says that it is temporary." />
<min value="0" />
<max value="1" />
<type>
<code value="code" />
</type>
<valueCode value="official" />
<isModifier value="true" />
<binding>
<name value="IdentifierUse" />
<isExtensible value="false" />
<conformance value="required" />
<referenceResource>
<reference value="http://hl7.org/fhir/vs/identifier-use" />
</referenceResource>
</binding>
<mapping>
<identity value="rim" />
<map value="N/A - this is sometimes implied by context" />
</mapping>
<mapping>
<identity value="v2" />
<map value="CX.5" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.identifier.label" />
<definition>
<short value="Description of identifier" />
<formal value="A text string for the identifier that can be displayed to a human so they can recognize the identifier." />
<min value="0" />
<max value="1" />
<type>
<code value="string" />
</type>
<valueString value="VDS Invoked" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="N/A - this is sometimes implied by context" />
</mapping>
<mapping>
<identity value="v2" />
<map value="N/A" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.identifier.system" />
<definition>
<short value="The namespace for the identifier" />
<formal value="Establishes the namespace in which set of possible id values is unique." />
<min value="0" />
<max value="1" />
<type>
<code value="uri" />
</type>
<valueUri value="http://dmix.gov/fhir/securityprofile" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="II.root" />
</mapping>
<mapping>
<identity value="v2" />
<map value="CX.4 / EI-2-4" />
</mapping>
<mapping>
<identity value="servd" />
<map value="./IdentifierType" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.type" />
<definition>
<short value="Object type being audited" />
<formal value="Object type being audited." />
<comments value="This value is distinct from the user's role or any user relationship to the participant object." />
<min value="1" />
<max value="1" />
<type>
<code value="code" />
</type>
<isModifier value="false" />
<binding>
<name value="SecurityEventObjectType" />
<isExtensible value="false" />
<conformance value="required" />
<referenceResource>
<reference value="http://hl7.org/fhir/vs/object-type" />
</referenceResource>
</binding>
<mapping>
<identity value="rim" />
<map value="[self::Act].code or role.player.code" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="@ParticipantObjectTypeCode" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.sensitivity" />
<definition>
<short value="Policy-defined sensitivity for the object" />
<formal value="Denotes policy-defined sensitivity for the Participant Object ID such as VIP, HIV status, mental health status or similar topics." />
<comments value="Values from ATNA are institution- and implementation-defined text strings (in sensitivity.text). HL7 defines confidentiality codes for records, documents etc. that can also be used here." />
<min value="0" />
<max value="1" />
<type>
<code value="CodeableConcept" />
</type>
<isModifier value="false" />
<binding>
<name value="SecurityEventObjectSensitivity" />
<isExtensible value="true" />
<conformance value="example" />
<referenceResource>
<reference value="http://hl7.org/fhir/vs/security-event-sensitivity" />
</referenceResource>
</binding>
<mapping>
<identity value="rim" />
<map value=".confidentialityCode" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="@ParticipantObjectSensitivity" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.sensitivity.coding" />
<definition>
<short value="Code defined by a terminology system" />
<formal value="A reference to a code defined by a terminology system." />
<comments value="Codes may be defined very casually in enumerations, or code lists, up to very formal definitions such as SNOMED CT - see the V3 Core Principles for more information. Ordering of codings is undefined and SHALL not be used to infer meaning." />
<min value="0" />
<max value="*" />
<type>
<code value="Coding" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="union(., ./translation)" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.1-8, C*E.10-22" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.sensitivity.coding.system" />
<definition>
<short value="Identity of the terminology system" />
<formal value="The identification of the code system that defines the meaning of the symbol in the code." />
<comments value="The URI may be an OID (urn:oid:...) or a UUID (urn:uuid:...). OIDs and UUIDs SHALL be references to the HL7 OID registry. Otherwise, the URI should come from HL7's list of FHIR defined special URIs or it should de-reference to some definition that establish the system clearly and unambiguously." />
<min value="0" />
<max value="1" />
<type>
<code value="uri" />
</type>
<valueUri value="http://hl7.org/fhir/v3/Confidentiality" />
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value="./codeSystem" />
</mapping>
<mapping>
<identity value="v2" />
<map value="C*E.3" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.object.name" />
<definition>
<short value="Instance-specific descriptor for Object" />
<formal value="An instance-specific descriptor of the Participant Object ID audited, such as a person's name." />
<comments value="This field may be used in a query/report to identify audit events for a specific person, e.g., where multiple synonymous Participant Object IDs (patient number, medical record number, encounter number, etc.) have been used." />
<min value="1" />
<max value="1" />
<type>
<code value="string" />
</type>
<isModifier value="false" />
<mapping>
<identity value="rim" />
<map value=".title" />
</mapping>
<mapping>
<identity value="dicom" />
<map value="ParticipantObjectName" />
</mapping>
</definition>
</element>
<element>
<path value="SecurityEvent.extension" />
<slicing>
<discriminator value="url" />
<ordered value="true" />
<rules value="openAtEnd" />
</slicing>
</element>
<element>
<path value="SecurityEvent.extension" />
<name value="aeExtension" />
<definition>
<min value="1" />
<max value="1" />
<type>
<code value="Extension" />
<profile value="#aeExtension" />
</type>
</definition>
</element>
</structure>
<extensionDefn>
<code value="aeExtension" />
<display value="aeExtension" />
<definition>
<min value="1" />
<max value="1" />
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.patientID" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="Unique identifier for patient" />
<min value="1" />
<max value="1" />
<type>
<code value="string" />
</type>
<maxLength value="10" />
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.buildRelease" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<min value="0" />
<max value="1" />
<type>
<code value="string" />
</type>
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.eventType" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="Audit|Exception" />
<min value="1" />
<max value="1" />
<type>
<code value="string" />
</type>
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.eventUnique" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="Unique identifier for this audit record" />
<min value="1" />
<max value="1" />
<type>
<code value="uuid" />
</type>
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.eventGroupUnique" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="Unique identifier for DMS RLUS/FHIR transaction for a consumer" />
<min value="1" />
<max value="1" />
<type>
<code value="uuid" />
</type>
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.eventMessageData" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="Message describing auditable transaction" />
<min value="1" />
<max value="1" />
<type>
<code value="string" />
</type>
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.debugSignal" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="1 means WMB uses its debug code. 0 means no debug. Other values TBD" />
<min value="0" />
<max value="1" />
<type>
<code value="integer" />
</type>
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.actionCode" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="NV means no schema validation. Other values TBD" />
<min value="0" />
<max value="1" />
<type>
<code value="string" />
</type>
</definition>
</extensionDefn>
<extensionDefn>
<code value="aeExtension.specialContent" />
<contextType value="extension" />
<context value="#aeExtension" />
<definition>
<short value="Additional informative text can be included here" />
<min value="0" />
<max value="1" />
<type>
<code value="string" />
</type>
</definition>
</extensionDefn>
</Profile>

View File

@ -1,180 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src/test/java" output="target/test-classes" including="**/*.java"/>
<classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>
<classpathentry kind="output" path="target/classes"/>
<classpathentry kind="var" path="M2_REPO/javax/activation/activation/1.1/activation-1.1.jar" sourcepath="M2_REPO/javax/activation/activation/1.1/activation-1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/el/javax.el-api/3.0.0/javax.el-api-3.0.0.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0.jar" sourcepath="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0.jar" sourcepath="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar" sourcepath="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/javax/transaction/jta/1.1/jta-1.1.jar" sourcepath="M2_REPO/javax/transaction/jta/1.1/jta-1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar" sourcepath="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar" sourcepath="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
<classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0.jar" sourcepath="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/commons-codec/commons-codec/1.9/commons-codec-1.9-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar" sourcepath="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4.jar" sourcepath="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4.jar" sourcepath="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1.jar" sourcepath="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar" sourcepath="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/cssparser/cssparser/0.9.14/cssparser-0.9.14.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/derby/derby/10.10.2.0/derby-10.10.2.0.jar"/>
<classpathentry kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar" sourcepath="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/com/google/guava/guava/17.0/guava-17.0.jar" sourcepath="M2_REPO/com/google/guava/guava/17.0/guava-17.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-base/0.6-SNAPSHOT/hapi-fhir-base-0.6-SNAPSHOT.jar"/>
<classpathentry kind="src" path="/hapi-fhir-jpaserver-base"/>
<classpathentry kind="src" path="/hapi-fhir-jpaserver-test"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.2.Final/hibernate-commons-annotations-4.0.2.Final.jar" sourcepath="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.2.Final/hibernate-commons-annotations-4.0.2.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-core/4.2.12.Final/hibernate-core-4.2.12.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-core/4.2.12.Final/hibernate-core-4.2.12.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-ehcache/4.2.12.Final/hibernate-ehcache-4.2.12.Final.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-entitymanager/4.2.12.Final/hibernate-entitymanager-4.2.12.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-entitymanager/4.2.12.Final/hibernate-entitymanager-4.2.12.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.0-api/1.0.1.Final/hibernate-jpa-2.0-api-1.0.1.Final.jar" sourcepath="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.0-api/1.0.1.Final/hibernate-jpa-2.0-api-1.0.1.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/htmlunit/htmlunit/2.16-SNAPSHOT/htmlunit-2.16-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/htmlunit/htmlunit-core-js/2.16-SNAPSHOT/htmlunit-core-js-2.16-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpmime/4.3.4/httpmime-4.3.4.jar"/>
<classpathentry kind="var" path="M2_REPO/org/javassist/javassist/3.16.1-GA/javassist-3.16.1-GA.jar" sourcepath="M2_REPO/org/javassist/javassist/3.16.1-GA/javassist-3.16.1-GA-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/glassfish/javax.el/3.0.0/javax.el-3.0.0.jar" sourcepath="M2_REPO/org/glassfish/javax.el/3.0.0/javax.el-3.0.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4.jar" sourcepath="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/javolution/javolution/5.2.3/javolution-5.2.3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging/3.1.0.GA/jboss-logging-3.1.0.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging/3.1.0.GA/jboss-logging-3.1.0.GA-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.1_spec/1.0.1.Final/jboss-transaction-api_1.1_spec-1.0.1.Final.jar" sourcepath="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.1_spec/1.0.1.Final/jboss-transaction-api_1.1_spec-1.0.1.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/slf4j/jcl-over-slf4j/1.7.7/jcl-over-slf4j-1.7.7.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-webapp/9.1.1.v20140108/jetty-webapp-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-webapp/9.1.1.v20140108/jetty-webapp-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-websocket/8.1.15.v20140411/jetty-websocket-8.1.15.v20140411.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-xml/9.1.1.v20140108/jetty-xml-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-xml/9.1.1.v20140108/jetty-xml-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jscience/jscience/4.3.1/jscience-4.3.1.jar" sourcepath="M2_REPO/org/jscience/jscience/4.3.1/jscience-4.3.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.11/junit-4.11-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/nekohtml/nekohtml/1.9.21/nekohtml-1.9.21.jar"/>
<classpathentry kind="var" path="M2_REPO/ognl/ognl/3.0.6/ognl-3.0.6.jar" sourcepath="M2_REPO/ognl/ognl/3.0.6/ognl-3.0.6-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/w3c/css/sac/1.3/sac-1.3.jar"/>
<classpathentry kind="var" path="M2_REPO/xalan/serializer/2.7.1/serializer-2.7.1.jar"/>
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-web/4.0.1.RELEASE/spring-web-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-web/4.0.1.RELEASE/spring-web-4.0.1.RELEASE-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-webmvc/4.0.1.RELEASE/spring-webmvc-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-webmvc/4.0.1.RELEASE/spring-webmvc-4.0.1.RELEASE-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1.jar" sourcepath="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/thymeleaf/thymeleaf/2.1.3.RELEASE/thymeleaf-2.1.3.RELEASE.jar" sourcepath="M2_REPO/org/thymeleaf/thymeleaf/2.1.3.RELEASE/thymeleaf-2.1.3.RELEASE-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/thymeleaf/thymeleaf-spring4/2.1.3.RELEASE/thymeleaf-spring4-2.1.3.RELEASE.jar"/>
<classpathentry kind="var" path="M2_REPO/org/unbescape/unbescape/1.0/unbescape-1.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0.jar" sourcepath="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-sources.jar">
<attributes>
<attribute value="jar:file:/Users/james/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-javadoc.jar!/" name="javadoc_location"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/xalan/xalan/2.7.1/xalan-2.7.1.jar"/>
<classpathentry kind="var" path="M2_REPO/xerces/xercesImpl/2.11.0/xercesImpl-2.11.0.jar"/>
<classpathentry kind="var" path="M2_REPO/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
</classpath>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**/*.java" including="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**/*.java" including="**/*.java" kind="src" path="src/main/resources"/>
<classpathentry kind="var" path="M2_REPO/javax/activation/activation/1.1/activation-1.1.jar" sourcepath="M2_REPO/javax/activation/activation/1.1/activation-1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/el/javax.el-api/3.0.0/javax.el-api-3.0.0.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0.jar" sourcepath="M2_REPO/javax/json/javax.json-api/1.0/javax.json-api-1.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0.jar" sourcepath="M2_REPO/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/javax/mail/javax.mail-api/1.5.0/javax.mail-api-1.5.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar" sourcepath="M2_REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/javax/transaction/jta/1.1/jta-1.1.jar" sourcepath="M2_REPO/javax/transaction/jta/1.1/jta-1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2.jar" sourcepath="M2_REPO/javax/xml/stream/stax-api/1.0-2/stax-api-1.0-2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar" sourcepath="M2_REPO/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/antlr/antlr/2.7.7/antlr-2.7.7.jar"/>
<classpathentry kind="var" path="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0.jar" sourcepath="M2_REPO/aopalliance/aopalliance/1.0/aopalliance-1.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0.jar" sourcepath="M2_REPO/com/fasterxml/classmate/1.0.0/classmate-1.0.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9.jar" sourcepath="M2_REPO/commons-codec/commons-codec/1.9/commons-codec-1.9-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-codec/commons-codec/1.9/commons-codec-1.9-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar" sourcepath="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4.jar" sourcepath="M2_REPO/commons-dbcp/commons-dbcp/1.4/commons-dbcp-1.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4.jar" sourcepath="M2_REPO/commons-io/commons-io/2.4/commons-io-2.4-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-io/commons-io/2.4/commons-io-2.4-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1.jar" sourcepath="M2_REPO/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/apache/commons/commons-lang3/3.2.1/commons-lang3-3.2.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar" sourcepath="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4.jar" sourcepath="M2_REPO/commons-pool/commons-pool/1.5.4/commons-pool-1.5.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/cssparser/cssparser/0.9.14/cssparser-0.9.14.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/derby/derby/10.10.2.0/derby-10.10.2.0.jar"/>
<classpathentry kind="var" path="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1.jar" sourcepath="M2_REPO/dom4j/dom4j/1.6.1/dom4j-1.6.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/com/google/guava/guava/17.0/guava-17.0.jar" sourcepath="M2_REPO/com/google/guava/guava/17.0/guava-17.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-all/1.3/hamcrest-all-1.3-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar" sourcepath="M2_REPO/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-base/0.6-SNAPSHOT/hapi-fhir-base-0.6-SNAPSHOT.jar"/>
<classpathentry kind="src" path="/hapi-fhir-jpaserver-base"/>
<classpathentry kind="src" path="/hapi-fhir-jpaserver-test"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.2.Final/hibernate-commons-annotations-4.0.2.Final.jar" sourcepath="M2_REPO/org/hibernate/common/hibernate-commons-annotations/4.0.2.Final/hibernate-commons-annotations-4.0.2.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-core/4.2.12.Final/hibernate-core-4.2.12.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-core/4.2.12.Final/hibernate-core-4.2.12.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-ehcache/4.2.12.Final/hibernate-ehcache-4.2.12.Final.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-entitymanager/4.2.12.Final/hibernate-entitymanager-4.2.12.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-entitymanager/4.2.12.Final/hibernate-entitymanager-4.2.12.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.0-api/1.0.1.Final/hibernate-jpa-2.0-api-1.0.1.Final.jar" sourcepath="M2_REPO/org/hibernate/javax/persistence/hibernate-jpa-2.0-api/1.0.1.Final/hibernate-jpa-2.0-api-1.0.1.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final.jar" sourcepath="M2_REPO/org/hibernate/hibernate-validator/5.1.0.Final/hibernate-validator-5.1.0.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/htmlunit/htmlunit/2.16-SNAPSHOT/htmlunit-2.16-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/htmlunit/htmlunit-core-js/2.16-SNAPSHOT/htmlunit-core-js-2.16-SNAPSHOT.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpclient/4.3.3/httpclient-4.3.3-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2.jar" sourcepath="M2_REPO/org/apache/httpcomponents/httpcore/4.3.2/httpcore-4.3.2-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/apache/httpcomponents/httpmime/4.3.4/httpmime-4.3.4.jar"/>
<classpathentry kind="var" path="M2_REPO/org/javassist/javassist/3.16.1-GA/javassist-3.16.1-GA.jar" sourcepath="M2_REPO/org/javassist/javassist/3.16.1-GA/javassist-3.16.1-GA-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/glassfish/javax.el/3.0.0/javax.el-3.0.0.jar" sourcepath="M2_REPO/org/glassfish/javax.el/3.0.0/javax.el-3.0.0-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4.jar" sourcepath="M2_REPO/org/glassfish/javax.json/1.0.4/javax.json-1.0.4-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/javolution/javolution/5.2.3/javolution-5.2.3.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/logging/jboss-logging/3.1.0.GA/jboss-logging-3.1.0.GA.jar" sourcepath="M2_REPO/org/jboss/logging/jboss-logging/3.1.0.GA/jboss-logging-3.1.0.GA-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.1_spec/1.0.1.Final/jboss-transaction-api_1.1_spec-1.0.1.Final.jar" sourcepath="M2_REPO/org/jboss/spec/javax/transaction/jboss-transaction-api_1.1_spec/1.0.1.Final/jboss-transaction-api_1.1_spec-1.0.1.Final-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/slf4j/jcl-over-slf4j/1.7.7/jcl-over-slf4j-1.7.7.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-continuation/9.1.1.v20140108/jetty-continuation-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-http/9.1.1.v20140108/jetty-http-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-io/9.1.1.v20140108/jetty-io-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-security/9.1.1.v20140108/jetty-security-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-server/9.1.1.v20140108/jetty-server-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlet/9.1.1.v20140108/jetty-servlet-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-servlets/9.1.1.v20140108/jetty-servlets-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-util/9.1.1.v20140108/jetty-util-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-webapp/9.1.1.v20140108/jetty-webapp-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-webapp/9.1.1.v20140108/jetty-webapp-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-websocket/8.1.15.v20140411/jetty-websocket-8.1.15.v20140411.jar"/>
<classpathentry kind="var" path="M2_REPO/org/eclipse/jetty/jetty-xml/9.1.1.v20140108/jetty-xml-9.1.1.v20140108.jar" sourcepath="M2_REPO/org/eclipse/jetty/jetty-xml/9.1.1.v20140108/jetty-xml-9.1.1.v20140108-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/jscience/jscience/4.3.1/jscience-4.3.1.jar" sourcepath="M2_REPO/org/jscience/jscience/4.3.1/jscience-4.3.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/junit/junit/4.11/junit-4.11.jar" sourcepath="M2_REPO/junit/junit/4.11/junit-4.11-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/junit/junit/4.11/junit-4.11-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-classic/1.1.1/logback-classic-1.1.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1.jar" sourcepath="M2_REPO/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/ch/qos/logback/logback-core/1.1.1/logback-core-1.1.1-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/net/sourceforge/nekohtml/nekohtml/1.9.21/nekohtml-1.9.21.jar"/>
<classpathentry kind="var" path="M2_REPO/ognl/ognl/3.0.6/ognl-3.0.6.jar" sourcepath="M2_REPO/ognl/ognl/3.0.6/ognl-3.0.6-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/w3c/css/sac/1.3/sac-1.3.jar"/>
<classpathentry kind="var" path="M2_REPO/xalan/serializer/2.7.1/serializer-2.7.1.jar"/>
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.7.7/slf4j-api-1.7.7.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-aop/4.0.1.RELEASE/spring-aop-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-beans/4.0.1.RELEASE/spring-beans-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context/4.0.1.RELEASE/spring-context-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-context-support/4.0.1.RELEASE/spring-context-support-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-core/4.0.1.RELEASE/spring-core-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-expression/4.0.1.RELEASE/spring-expression-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-jdbc/4.0.1.RELEASE/spring-jdbc-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-orm/4.0.1.RELEASE/spring-orm-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/springframework/spring-tx/4.0.1.RELEASE/spring-tx-4.0.1.RELEASE-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-web/4.0.1.RELEASE/spring-web-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-web/4.0.1.RELEASE/spring-web-4.0.1.RELEASE-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/springframework/spring-webmvc/4.0.1.RELEASE/spring-webmvc-4.0.1.RELEASE.jar" sourcepath="M2_REPO/org/springframework/spring-webmvc/4.0.1.RELEASE/spring-webmvc-4.0.1.RELEASE-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1.jar" sourcepath="M2_REPO/org/codehaus/woodstox/stax2-api/3.1.1/stax2-api-3.1.1-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/thymeleaf/thymeleaf/2.1.3.RELEASE/thymeleaf-2.1.3.RELEASE.jar" sourcepath="M2_REPO/org/thymeleaf/thymeleaf/2.1.3.RELEASE/thymeleaf-2.1.3.RELEASE-sources.jar"/>
<classpathentry kind="var" path="M2_REPO/org/thymeleaf/thymeleaf-spring4/2.1.3.RELEASE/thymeleaf-spring4-2.1.3.RELEASE.jar"/>
<classpathentry kind="var" path="M2_REPO/org/unbescape/unbescape/1.0/unbescape-1.0.jar"/>
<classpathentry kind="var" path="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0.jar" sourcepath="M2_REPO/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-sources.jar">
<attributes>
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/org/codehaus/woodstox/woodstox-core-asl/4.2.0/woodstox-core-asl-4.2.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/xalan/xalan/2.7.1/xalan-2.7.1.jar"/>
<classpathentry kind="var" path="M2_REPO/xerces/xercesImpl/2.11.0/xercesImpl-2.11.0.jar"/>
<classpathentry kind="var" path="M2_REPO/xml-apis/xml-apis/1.4.01/xml-apis-1.4.01.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
<attribute name="org.eclipse.jst.component.dependency" value="/WEB-INF/lib"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View File

@ -1,16 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hapi-fhir-testpage-overlay</name>
<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
<projects>
<project>hapi-fhir-jpaserver-base</project>
<project>hapi-fhir-jpaserver-test</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
<name>hapi-fhir-testpage-overlay</name>
<comment>NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse.</comment>
<projects>
<project>hapi-fhir-jpaserver-base</project>
<project>hapi-fhir-jpaserver-test</project>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.wst.jsdt.core.javascriptValidator</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.validation.validationbuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
<nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.wst.jsdt.core.jsNature</nature>
</natures>
</projectDescription>

View File

@ -1,5 +1,8 @@
#Sun Aug 10 11:41:00 EDT 2014
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.source=1.6
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -23,7 +23,6 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="temp"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6">
<attributes>
<attribute name="maven.pomderived" value="true"/>

View File

@ -221,7 +221,7 @@ public class TinderStructuresMojo extends AbstractMojo {
String dtOutputDir = "target/generated-sources/tinder/ca/uhn/fhir/model/dev/composite";
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet("dev", ".");
rp.setBaseResourceNames(Arrays.asList("referralrequest", "patient","practitioner","encounter",
rp.setBaseResourceNames(Arrays.asList("conformance", "referralrequest", "patient","practitioner","encounter",
"organization","location","relatedperson","appointment","slot","order","availability","device", "valueset"));
rp.parse();
rp.bindValueSets(vsp);

View File

@ -0,0 +1,272 @@
package ca.uhn.fhir.tinder;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import ca.uhn.fhir.tinder.parser.DatatypeGeneratorUsingSpreadsheet;
import ca.uhn.fhir.tinder.parser.ProfileParser;
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet;
@Mojo(name = "generate-structures", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
public class TinderStructuresMojo extends AbstractMojo {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderStructuresMojo.class);
@Parameter(required = false)
private List<String> baseResourceNames;
@Parameter(required = false, defaultValue = "false")
private boolean buildDatatypes;
@Component
private MavenProject myProject;
@Parameter(alias = "package", required = true)
private String packageName;
@Parameter(alias = "version", required = true, defaultValue="dstu")
private String version = "dstu";
@Parameter(required = false)
private List<ProfileFileDefinition> resourceProfileFiles;
@Parameter(required = false)
private List<ValueSetFileDefinition> resourceValueSetFiles;
@Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
private String targetDirectory;
@Parameter(required = true, defaultValue = "${project.build.directory}/generated-resources/tinder")
private String targetResourceDirectory;
@Parameter(required = true, defaultValue = "${project.build.directory}/..")
private String baseDir;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (StringUtils.isBlank(packageName)) {
throw new MojoFailureException("Package not specified");
}
if (packageName.contains("..") || packageName.endsWith(".")) {
throw new MojoFailureException("Invalid package specified");
}
ourLog.info("Beginning HAPI-FHIR Tinder Code Generation...");
ourLog.info(" * Output Package: " + packageName);
File resDirectoryBase = new File(new File(targetResourceDirectory), packageName.replace('.', File.separatorChar));
resDirectoryBase.mkdirs();
ourLog.info(" * Output Resource Directory: " + resDirectoryBase.getAbsolutePath());
File directoryBase = new File(new File(targetDirectory), packageName.replace('.', File.separatorChar));
directoryBase.mkdirs();
ourLog.info(" * Output Source Directory: " + directoryBase.getAbsolutePath());
ValueSetGenerator vsp = new ValueSetGenerator(version);
vsp.setResourceValueSetFiles(resourceValueSetFiles);
try {
vsp.parse();
} catch (Exception e) {
throw new MojoFailureException("Failed to load valuesets", e);
}
ourLog.info("Loading Datatypes...");
Map<String, String> datatypeLocalImports = new HashMap<String, String>();
DatatypeGeneratorUsingSpreadsheet dtp = new DatatypeGeneratorUsingSpreadsheet(version, baseDir);
if (buildDatatypes) {
try {
dtp.parse();
dtp.markResourcesForImports();
} catch (Exception e) {
throw new MojoFailureException("Failed to load datatypes", e);
}
dtp.bindValueSets(vsp);
datatypeLocalImports = dtp.getLocalImports();
}
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet(version, baseDir);
if (baseResourceNames != null && baseResourceNames.size() > 0) {
ourLog.info("Loading Resources...");
try {
rp.setBaseResourceNames(baseResourceNames);
rp.parse();
rp.markResourcesForImports();
} catch (Exception e) {
throw new MojoFailureException("Failed to load resources", e);
}
rp.bindValueSets(vsp);
rp.getLocalImports().putAll(datatypeLocalImports);
datatypeLocalImports.putAll(rp.getLocalImports());
ourLog.info("Writing Resources...");
File resSubDirectoryBase = new File(directoryBase, "resource");
rp.combineContentMaps(dtp);
rp.writeAll(resSubDirectoryBase, resDirectoryBase, packageName);
}
ProfileParser pp = new ProfileParser(version, baseDir);
if (resourceProfileFiles != null) {
ourLog.info("Loading profiles...");
for (ProfileFileDefinition next : resourceProfileFiles) {
ourLog.info("Parsing file: {}", next.profileFile);
pp.parseSingleProfile(new File(next.profileFile), next.profileSourceUrl);
}
pp.bindValueSets(vsp);
pp.markResourcesForImports();
pp.getLocalImports().putAll(datatypeLocalImports);
datatypeLocalImports.putAll(pp.getLocalImports());
pp.combineContentMaps(rp);
pp.combineContentMaps(dtp);
pp.writeAll(new File(directoryBase, "resource"), resDirectoryBase, packageName);
}
if (dtp != null) {
ourLog.info("Writing Composite Datatypes...");
dtp.combineContentMaps(pp);
dtp.combineContentMaps(rp);
dtp.writeAll(new File(directoryBase, "composite"), resDirectoryBase, packageName);
}
ourLog.info("Writing ValueSet Enums...");
vsp.writeMarkedValueSets(new File(directoryBase, "valueset"), packageName);
myProject.addCompileSourceRoot(targetDirectory);
}
public List<String> getBaseResourceNames() {
return baseResourceNames;
}
public String getPackageName() {
return packageName;
}
public List<ProfileFileDefinition> getResourceProfileFiles() {
return resourceProfileFiles;
}
public List<ValueSetFileDefinition> getResourceValueSetFiles() {
return resourceValueSetFiles;
}
public String getTargetDirectory() {
return targetDirectory;
}
public boolean isBuildDatatypes() {
return buildDatatypes;
}
public void setBaseResourceNames(List<String> theBaseResourceNames) {
baseResourceNames = theBaseResourceNames;
}
public void setBuildDatatypes(boolean theBuildDatatypes) {
buildDatatypes = theBuildDatatypes;
}
public void setPackageName(String thePackageName) {
packageName = thePackageName;
}
public void setResourceProfileFiles(List<ProfileFileDefinition> theResourceProfileFiles) {
resourceProfileFiles = theResourceProfileFiles;
}
public void setResourceValueSetFiles(List<ValueSetFileDefinition> theResourceValueSetFiles) {
resourceValueSetFiles = theResourceValueSetFiles;
}
public void setTargetDirectory(String theTargetDirectory) {
targetDirectory = theTargetDirectory;
}
public static void main(String[] args) throws Exception {
// ProfileParser pp = new ProfileParser();
// pp.parseSingleProfile(new File("../hapi-tinder-test/src/test/resources/profile/patient.xml"), "http://foo");
ValueSetGenerator vsp = new ValueSetGenerator("dev");
// vsp.setResourceValueSetFiles(theResourceValueSetFiles);Directory("src/main/resources/vs/");
vsp.parse();
DatatypeGeneratorUsingSpreadsheet dtp = new DatatypeGeneratorUsingSpreadsheet("dev", ".");
dtp.parse();
dtp.markResourcesForImports();
dtp.bindValueSets(vsp);
Map<String, String> datatypeLocalImports = dtp.getLocalImports();
String dtOutputDir = "target/generated-sources/tinder/ca/uhn/fhir/model/dev/composite";
ResourceGeneratorUsingSpreadsheet rp = new ResourceGeneratorUsingSpreadsheet("dev", ".");
<<<<<<< HEAD
rp.setBaseResourceNames(Arrays.asList("referralrequest", "patient","practitioner","encounter",
=======
rp.setBaseResourceNames(Arrays.asList("conformance", "referralrequest", "patient","practitioner","encounter",
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
"organization","location","relatedperson","appointment","slot","order","availability","device", "valueset"));
rp.parse();
rp.bindValueSets(vsp);
rp.markResourcesForImports();
// rp.bindValueSets(vsp);
String rpOutputDir = "target/generated-sources/tinder/ca/uhn/fhir/model/dev/resource";
String rpSOutputDir = "target/generated-resources/tinder/ca/uhn/fhir/model/dev";
dtp.combineContentMaps(rp);
rp.combineContentMaps(dtp);
rp.getLocalImports().putAll(datatypeLocalImports);
datatypeLocalImports.putAll(rp.getLocalImports());
dtp.writeAll(new File(dtOutputDir), null, "ca.uhn.fhir.model.dev");
rp.writeAll(new File(rpOutputDir), new File(rpSOutputDir), "ca.uhn.fhir.model.dev");
String vsOutputDir = "target/generated-sources/tinder/ca/uhn/fhir/model/dev/valueset";
vsp.writeMarkedValueSets(new File(vsOutputDir), "ca.uhn.fhir.model.dev");
}
public static class ProfileFileDefinition {
@Parameter(required = true)
private String profileFile;
@Parameter(required = true)
private String profileSourceUrl;
}
public static class ValueSetFileDefinition {
@Parameter(required = true)
private String valueSetFile;
public String getValueSetFile() {
return valueSetFile;
}
public void setValueSetFile(String theValueSetFile) {
valueSetFile = theValueSetFile;
}
}
}

View File

@ -93,4 +93,4 @@ public class ${className}
return "${className.replaceAll("Resource", "")}";
}
}
}

View File

@ -0,0 +1,95 @@
#parse ( "/vm/templates.vm" )
package ${packageBase}.resource;
import java.math.BigDecimal;
import java.net.URI;
import java.util.*;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.rest.gclient.*;
#foreach ( $import in $imports )
import ${import};
#end
##import ${packageBase}.composite.*;
##import ${packageBase}.valueset.*;
/**
* HAPI/FHIR <b>${elementName}</b> Resource
* (${shortName})
*
* <p>
* <b>Definition:</b>
* ${definition}
* </p>
*
* <p>
* <b>Requirements:</b>
* ${requirements}
* </p>
*
#if (${profile} != "")
* <p>
* <b>Profile Definition:</b>
* <a href="${profile}">${profile}</a>
* </p>
*
#end
*/
@ResourceDef(name="${elementName}", profile="${profile}", id="${id}")
public class ${className}
<<<<<<< HEAD
extends #{if}( ${className}=="OperationOutcome" || ${className}=="Conformance" ) ca.uhn.fhir.model.base.resource.Base${className} #{else} BaseResource #{end}
=======
extends #{if}( ${className}=="OperationOutcome" || ${className}=="Conformance" || ${className}=="SecurityEvent" ) ca.uhn.fhir.model.base.resource.Base${className} #{else} BaseResource #{end}
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
implements IResource {
#foreach ( $param in $searchParams )
/**
* Search parameter constant for <b>${param.name}</b>
* <p>
* Description: <b>${param.description}</b><br/>
* Type: <b>${param.type}</b><br/>
* Path: <b>${param.path}</b><br/>
* </p>
*/
@SearchParamDefinition(name="${param.name}", path="${param.path}", description="${param.description}", type="${param.type}" #{if}($param.compositeOf.empty == false) , compositeOf={ #{foreach}($compositeOf in $param.compositeOf) "${compositeOf}"#{if}($foreach.hasNext), #{end}#{end} } #{end} )
public static final String $param.constantName = "${param.name}";
/**
* <b>Fluent Client</b> search parameter constant for <b>${param.name}</b>
* <p>
* Description: <b>${param.description}</b><br/>
* Type: <b>${param.type}</b><br/>
* Path: <b>${param.path}</b><br/>
* </p>
*/
#if( ${param.typeCapitalized} == 'Composite' )
public static final CompositeClientParam<${param.compositeTypes[0]}ClientParam, ${param.compositeTypes[1]}ClientParam> ${param.fluentConstantName} = new CompositeClientParam<${param.compositeTypes[0]}ClientParam, ${param.compositeTypes[1]}ClientParam>(${param.constantName});
#else
public static final ${param.typeCapitalized}ClientParam ${param.fluentConstantName} = new ${param.typeCapitalized}ClientParam(${param.constantName});
#end
#if( ${param.typeCapitalized} == 'Reference' )
#foreach ( $include in $param.paths )
/**
* Constant for fluent queries to be used to add include statements. Specifies
* the path value of "<b>${include.path}</b>".
*/
public static final Include INCLUDE_${include.includeName} = new Include("${include.path}");
#end
#end
#end
#childExtensionFields( $childExtensionTypes )
#childVars( $children )
#childAccessors( $children )
#childResourceBlocks($resourceBlockChildren)
#childExtensionTypes( $childExtensionTypes )
}

View File

@ -92,4 +92,4 @@ public class ${className}
return "${className.replaceAll("Resource", "")}";
}
}
}

View File

@ -0,0 +1,94 @@
#parse ( "/vm/templates_dstu.vm" )
package ${packageBase}.resource;
import java.util.*;
import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.*;
import ca.uhn.fhir.rest.gclient.*;
#foreach ( $import in $imports )
import ${import};
#end
##import ${packageBase}.composite.*;
##import ${packageBase}.valueset.*;
/**
* HAPI/FHIR <b>${elementName}</b> Resource
* (${shortName})
*
* <p>
* <b>Definition:</b>
* ${definition}
* </p>
*
* <p>
* <b>Requirements:</b>
* ${requirements}
* </p>
*
#if (${profile} != "")
* <p>
* <b>Profile Definition:</b>
* <a href="${profile}">${profile}</a>
* </p>
*
#end
*/
@ResourceDef(name="${elementName}", profile="${profile}", id="${id}")
public class ${className}
<<<<<<< HEAD
extends #{if}( ${className}=="OperationOutcome" || ${className}=="Conformance" ) ca.uhn.fhir.model.base.resource.Base${className} #{else} BaseResource #{end}
=======
extends #{if}( ${className}=="OperationOutcome" || ${className}=="Conformance" || ${className}=="SecurityEvent" ) ca.uhn.fhir.model.base.resource.Base${className} #{else} BaseResource #{end}
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
implements IResource {
#foreach ( $param in $searchParams )
/**
* Search parameter constant for <b>${param.name}</b>
* <p>
* Description: <b>${param.description}</b><br/>
* Type: <b>${param.type}</b><br/>
* Path: <b>${param.path}</b><br/>
* </p>
*/
@SearchParamDefinition(name="${param.name}", path="${param.path}", description="${param.description}", type="${param.type}" #{if}($param.compositeOf.empty == false) , compositeOf={ #{foreach}($compositeOf in $param.compositeOf) "${compositeOf}"#{if}($foreach.hasNext), #{end}#{end} } #{end} )
public static final String $param.constantName = "${param.name}";
/**
* <b>Fluent Client</b> search parameter constant for <b>${param.name}</b>
* <p>
* Description: <b>${param.description}</b><br/>
* Type: <b>${param.type}</b><br/>
* Path: <b>${param.path}</b><br/>
* </p>
*/
#if( ${param.typeCapitalized} == 'Composite' )
public static final CompositeClientParam<${param.compositeTypes[0]}ClientParam, ${param.compositeTypes[1]}ClientParam> ${param.fluentConstantName} = new CompositeClientParam<${param.compositeTypes[0]}ClientParam, ${param.compositeTypes[1]}ClientParam>(${param.constantName});
#else
public static final ${param.typeCapitalized}ClientParam ${param.fluentConstantName} = new ${param.typeCapitalized}ClientParam(${param.constantName});
#end
#if( ${param.typeCapitalized} == 'Reference' )
#foreach ( $include in $param.paths )
/**
* Constant for fluent queries to be used to add include statements. Specifies
* the path value of "<b>${include.path}</b>".
*/
public static final Include INCLUDE_${include.includeName} = new Include("${include.path}");
#end
#end
#end
#childExtensionFields( $childExtensionTypes )
#childVars( $children )
#childAccessors( $children )
#childResourceBlocks($resourceBlockChildren)
#childExtensionTypes( $childExtensionTypes )
}

1
list_releases.sh Normal file
View File

@ -0,0 +1 @@
curl https://api.github.com/repos/jamesagnew/hapi-fhir/releases

82
pom.xml
View File

@ -28,6 +28,13 @@
<url>https://github.com/jamesagnew/hapi-fhir/issues/</url>
</issueManagement>
<distributionManagement>
<site>
<id>git.server</id>
<url>scm:git:git@github.com:jamesagnew/hapi-fhir.git</url>
</site>
</distributionManagement>
<scm>
<connection>scm:git:git@github.com:jamesagnew/hapi-fhir.git</connection>
<url>scm:git:git@github.com:jamesagnew/hapi-fhir.git</url>
@ -245,6 +252,58 @@
</dependency>
</dependencies>
</plugin>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
ca.uhn.hapi.fhir
</groupId>
<artifactId>
hapi-tinder-plugin
</artifactId>
<versionRange>
[0.8-SNAPSHOT,)
</versionRange>
<goals>
<goal>
generate-jparest-server
</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
org.apache.maven.plugins
</groupId>
<artifactId>
maven-antrun-plugin
</artifactId>
<versionRange>
[1.7,)
</versionRange>
<goals>
<goal>run</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
@ -502,12 +561,33 @@
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<classFilesDirectory>./hapi-fhir-base/target/classes</classFilesDirectory>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>findbugs</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-linkcheck-plugin</artifactId>
<version>1.1</version> </plugin> -->
</plugins>
</reporting>
<profiles>
<profile>
<id>ROOT</id>
<modules>
</modules>
</profile>
<profile>
<id>SIGN_ARTIFACTS</id>
<activation>
@ -551,7 +631,7 @@
<modules>
<module>hapi-deployable-pom</module>
<module>hapi-fhir-base</module>
<module>hapi-fhir-oauth2</module>
<!--<module>hapi-fhir-oauth2</module>-->
<module>hapi-fhir-base/testmindeps</module>
<module>hapi-tinder-plugin</module>
<module>hapi-tinder-test</module>

633
pom.xml.orig Normal file
View File

@ -0,0 +1,633 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.sonatype.oss</groupId>
<artifactId>oss-parent</artifactId>
<version>9</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<packaging>pom</packaging>
<version>0.8-SNAPSHOT</version>
<name>HAPI-FHIR</name>
<url>http://hl7api.sourceforge.net/hapi-fhir/</url>
<organization>
<name>University Health Network</name>
<url>http://www.uhn.ca</url>
</organization>
<inceptionYear>2014</inceptionYear>
<issueManagement>
<system>GitHub</system>
<url>https://github.com/jamesagnew/hapi-fhir/issues/</url>
</issueManagement>
<distributionManagement>
<site>
<id>git.server</id>
<url>scm:git:git@github.com:jamesagnew/hapi-fhir.git</url>
</site>
</distributionManagement>
<scm>
<connection>scm:git:git@github.com:jamesagnew/hapi-fhir.git</connection>
<url>scm:git:git@github.com:jamesagnew/hapi-fhir.git</url>
<developerConnection>scm:git:git@github.com:jamesagnew/hapi-fhir.git</developerConnection>
</scm>
<description>
</description>
<dependencies>
</dependencies>
<prerequisites>
<maven>3.0.1</maven>
</prerequisites>
<developers>
<developer>
<id>jamesagnew</id>
<name>James Agnew</name>
<organization>University Health Network</organization>
</developer>
<developer>
<name>Dmitri Sotnikov</name>
<organization>University Health Network</organization>
</developer>
<developer>
<name>Lisa Wong</name>
<organization>University Health Network</organization>
</developer>
<developer>
<name>Josh Mandel</name>
<organization>Boston Children's Hospital</organization>
</developer>
<developer>
<name>Laura MacDougall Sookraj</name>
<organization>University Health Network</organization>
</developer>
<developer>
<name>Neal Acharya</name>
<organization>University Health Network</organization>
</developer>
<developer>
<name>David Hay</name>
<organization>Orion Health</organization>
</developer>
<developer>
<id>suranga</id>
<name>Suranga Nath Kasthurirathne</name>
<organization>OpenMRS / Regenstrief Center for Biomedical Informatics</organization>
</developer>
<developer>
<id>dougmartin</id>
<name>Doug Martin</name>
<organization>Regenstrief Center for Biomedical Informatics</organization>
</developer>
<developer>
<id>akley</id>
<name>Alexander Kley</name>
</developer>
<developer>
<id>preston</id>
<name>Preston Lee</name>
<organization>Arizona State University</organization>
</developer>
<developer>
<id>jathman</id>
<name>Joe Athman</name>
</developer>
<developer>
<id>petromykhailysyn</id>
<name>Petro Mykhailyshyn</name>
</developer>
</developers>
<licenses>
<license>
<name>Apache Software License 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
</license>
</licenses>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- For site-deploy -->
<siteMainDirectory>${user.home}/sites/hapi-fhir</siteMainDirectory>
<scmPubCheckoutDirectory>${user.home}/sites/scm/hapi-fhir</scmPubCheckoutDirectory>
<!-- Plugin Versions -->
<commons_lang_version>3.3.2</commons_lang_version>
<derby_version>10.11.1.1</derby_version>
<guava_version>18.0</guava_version>
<hamcrest_version>1.3</hamcrest_version>
<hibernate_version>4.2.12.Final</hibernate_version>
<hibernate_validator_version>5.1.0.Final</hibernate_validator_version>
<jetty_version>9.2.2.v20140723</jetty_version>
<jscience_version>4.3.1</jscience_version>
<junit_version>4.11</junit_version>
<logback_version>1.1.2</logback_version>
<maven_assembly_plugin_version>2.4.1</maven_assembly_plugin_version>
<maven_javadoc_plugin_version>2.9.1</maven_javadoc_plugin_version>
<maven_license_plugin_version>1.7</maven_license_plugin_version>
<maven_surefire_plugin_version>2.17</maven_surefire_plugin_version>
<maven_site_plugin_version>3.4</maven_site_plugin_version>
<maven_source_plugin_version>2.3</maven_source_plugin_version>
<mitreid-connect-version>1.1.8</mitreid-connect-version>
<mockito_version>1.9.5</mockito_version>
<phloc_schematron_version>2.7.1</phloc_schematron_version>
<phloc_commons_version>4.3.3</phloc_commons_version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<servlet_api_version>3.1.0</servlet_api_version>
<slf4j_version>1.7.7</slf4j_version>
<spring_version>4.1.0.RELEASE</spring_version>
<spring_security_version>3.2.4.RELEASE</spring_security_version>
<thymeleaf-version>2.1.3.RELEASE</thymeleaf-version>
<ebay_cors_filter_version>1.0.1</ebay_cors_filter_version>
<woodstox_version>4.4.0</woodstox_version>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven_surefire_plugin_version}</version>
<configuration>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<runOrder>random</runOrder>
<!--<argLine>-Dfile.encoding=ISO-8859-1</argLine> -->
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>${maven_site_plugin_version}</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ssh</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.doxia</groupId>
<artifactId>doxia-module-markdown</artifactId>
<version>1.6</version>
</dependency>
</dependencies>
<configuration>
<skip>true</skip>
<skipDeploy>true</skipDeploy>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven_javadoc_plugin_version}</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>${maven_source_plugin_version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>license-maven-plugin</artifactId>
<version>${maven_license_plugin_version}</version>
<configuration>
<verbose>true</verbose>
<addSvnKeyWords>false</addSvnKeyWords>
</configuration>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>${maven_site_plugin_version}</version>
<configuration>
<skip>false</skip>
<skipDeploy>true</skipDeploy>
</configuration>
<dependencies>
<dependency>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-scm</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-api</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<inherited>false</inherited>
<executions>
<execution>
<id>copySubProjects</id>
<phase>site</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<copy todir="target/site/apidocs">
<fileset dir="hapi-fhir-base/target/site/apidocs"/>
</copy>
<copy todir="target/site/apidocs-dstu">
<fileset dir="hapi-fhir-structures-dstu/target/site/apidocs"/>
</copy>
<copy todir="target/site/apidocs-dev">
<fileset dir="hapi-fhir-structures-dev/target/site/apidocs"/>
</copy>
</target>
</configuration>
</execution>
<execution>
<id>addSyntaxHighlighter</id>
<phase>site</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<echo>Adding Syntax Highlighter</echo>
<replace dir="target/site" summary="true">
<include name="*.html"></include>
<replacetoken><![CDATA[</body>]]></replacetoken>
<replacevalue><![CDATA[
<script type="text/javascript">
var elements = document.getElementsByClassName("source");
for (var i=0; i < elements.length; i++) {
var pres = elements[i].getElementsByTagName("pre");
for (var j = 0; j < pres.length; j++) {
var pre = pres[j];
if (pre.innerHTML.match(/\/\*/)) {
pre.className = 'brush: java';
} else if (pre.innerHTML.match(/^\/\//)) {
pre.className = 'brush: java';
} else if (pre.innerHTML.match(/^\{/)) {
pre.className = 'brush: jscript';
} else if (pre.innerHTML.match(/^\#/)) {
pre.className = 'brush: bash';
} else if (pre.innerHTML.match(/\&lt\;\//)) {
pre.className = 'brush: xml';
} else {
pre.className = 'brush: java';
}
}
}
SyntaxHighlighter.all();
</script>
</body>
]]></replacevalue>
</replace>
</target>
</configuration>
</execution>
<execution>
<id>addAnalytics</id>
<phase>post-site</phase>
<configuration>
<target>
<echo>Adding Google analytics in target/site for &lt;body&gt;</echo>
<replace dir="target/site" summary="true">
<include name="**/*.html"></include>
<replacefilter token="#build#" value="${label}" />
<replacefilter token="#version#" value="${project.version}" />
<replacetoken><![CDATA[</body>]]></replacetoken>
<replacevalue><![CDATA[
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-1395874-5', 'auto');
ga('require', 'displayfeatures');
ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview');
</script>
</body >
]]></replacevalue>
</replace>
<echo>Adding Google analytics in target/site for &lt;BODY&gt;</echo>
<replace dir="target/site" summary="true">
<include name="**/*.html"></include>
<replacetoken><![CDATA[</BODY>]]></replacetoken>
<replacevalue><![CDATA[
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-1395874-5', 'auto');
ga('require', 'displayfeatures');
ga('require', 'linkid', 'linkid.js');
ga('send', 'pageview');
</script>
</BODY >
]]></replacevalue>
</replace>
<echo>Adding social plugins for HAPI</echo>
<replace dir="target/site/" summary="true">
<include name="**/*.html"></include>
<replacetoken><![CDATA[SOCIALPLUGINSHEREFHIR]]></replacetoken>
<replacevalue><![CDATA[
<table cellpadding="0" cellspacing="0" border="0"><tr>
<td><div class="g-plusone" data-annotation="inline" data-width="300" data-href="http://hl7api.sourceforge.net/"></div></td>
<td><div class="fb-like" data-href="http://hl7api.sourceforge.net/" data-send="false" data-layout="button_count" data-width="450" data-show-faces="true"></div></td>
</tr></table>
<<<<<<< HEAD
</p><p>
<!-- Place this tag after the last +1 button tag. -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
]]></replacevalue>
</replace>
=======
</p><p>
<!-- Place this tag after the last +1 button tag. -->
<script type="text/javascript">
(function() {
var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true;
po.src = 'https://apis.google.com/js/plusone.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s);
})();
</script>
<div id="fb-root"></div>
<script>(function(d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
js = d.createElement(s); js.id = id;
js.src = "//connect.facebook.net/en_US/all.js#xfbml=1";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>
]]></replacevalue>
</replace>
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<version>1.12</version>
<inherited>true</inherited>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature</groupId>
<artifactId>java16</artifactId>
<version>1.01</version>
</signature>
</configuration>
</plugin>
<plugin>
<artifactId>maven-site-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>stage-for-scm-publish</id>
<phase>post-site</phase>
<goals>
<goal>stage</goal>
</goals>
<configuration>
<stagingDirectory>${siteMainDirectory}</stagingDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-scm-publish-plugin</artifactId>
<version>1.1</version>
<inherited>false</inherited>
<configuration>
<checkoutDirectory>${scmPubCheckoutDirectory}</checkoutDirectory>
<content>\${siteMainDirectory}</content>
<tryUpdate>true</tryUpdate>
<scmBranch>gh-pages</scmBranch>
<pubScmUrl>scm:git:git@github.com:jamesagnew/hapi-fhir.git</pubScmUrl>
</configuration>
<executions>
<execution>
<id>scm-publish</id>
<phase>site-deploy</phase>
<goals>
<goal>publish-scm</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-changes-plugin</artifactId>
<version>2.11</version>
<inherited>false</inherited>
<reportSets>
<reportSet>
<reports>
<report>changes-report</report>
</reports>
</reportSet>
</reportSets>
<configuration>
<feedType>atom_1.0</feedType>
<issueLinkTemplatePerSystem>
<default>https://github.com/jamesagnew/hapi-fhir/issues/%ISSUE%</default>
</issueLinkTemplatePerSystem>
<escapeHTML>false</escapeHTML>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>${maven_surefire_plugin_version}</version>
<configuration>
<aggregate>true</aggregate>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
<version>2.7</version>
<inherited>false</inherited>
<reportSets>
<reportSet>
<reports>
<report>project-team</report>
<report>issue-tracking</report>
<report>license</report>
<report>scm</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<<<<<<< HEAD
=======
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.0</version>
<configuration>
<classFilesDirectory>./hapi-fhir-base/target/classes</classFilesDirectory>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>findbugs</report>
</reports>
</reportSet>
</reportSets>
</plugin>
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-linkcheck-plugin</artifactId>
<version>1.1</version> </plugin> -->
</plugins>
</reporting>
<profiles>
<profile>
<id>ROOT</id>
<modules>
</modules>
</profile>
<profile>
<id>SIGN_ARTIFACTS</id>
<activation>
<property>
<name>gpg.passphrase</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>1.5</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>SITE</id>
<modules>
<module>hapi-fhir-base</module>
<module>hapi-fhir-structures-dstu</module>
<module>hapi-fhir-structures-dev</module>
<<<<<<< HEAD
=======
<module>examples</module>
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
</modules>
</profile>
<profile>
<id>ALLMODULES</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<modules>
<module>hapi-deployable-pom</module>
<module>hapi-fhir-base</module>
<module>hapi-fhir-oauth2</module>
<<<<<<< HEAD
<module>hapi-fhir-base/examples</module>
=======
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2
<module>hapi-fhir-base/testmindeps</module>
<module>hapi-tinder-plugin</module>
<module>hapi-tinder-test</module>
<module>hapi-fhir-structures-dstu</module>
<module>hapi-fhir-structures-dev</module>
<module>hapi-fhir-jpaserver-base</module>
<module>hapi-fhir-jpaserver-test</module>
<module>restful-server-example</module>
<module>restful-server-example-test</module>
<module>hapi-fhir-testpage-overlay</module>
<module>hapi-fhir-jpaserver-uhnfhirtest</module>
</modules>
</profile>
</profiles>
</project>

View File

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

View File

@ -3,20 +3,13 @@
<wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
<wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
<wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
<<<<<<< HEAD
<dependent-module archiveName="hapi-fhir-base-0.7.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.7/hapi-fhir-testpage-overlay-0.7.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
=======
<dependent-module archiveName="hapi-fhir-base-0.8-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-base/hapi-fhir-base">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module archiveName="hapi-fhir-structures-dstu-0.8-SNAPSHOT.jar" deploy-path="/WEB-INF/lib" handle="module:/resource/hapi-fhir-structures-dstu/hapi-fhir-structures-dstu">
<dependency-type>uses</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/var/M2_REPO/ca/uhn/hapi/fhir/hapi-fhir-testpage-overlay/0.8-SNAPSHOT/hapi-fhir-testpage-overlay-0.8-SNAPSHOT.war?unpackFolder=target/m2e-wtp/overlays&amp;includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
>>>>>>> versions
<dependent-module deploy-path="/" handle="module:/overlay/prj/hapi-fhir-testpage-overlay?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">
<dependency-type>consumes</dependency-type>
</dependent-module>
<dependent-module deploy-path="/" handle="module:/overlay/slf/?includes=**/**&amp;excludes=META-INF/MANIFEST.MF">

View File

@ -7,11 +7,34 @@
</properties>
<body>
<release version="0.8" date="TBD">
<action type="add" issue="38">
<action>
<![CDATA[<b>API CHANGE:</b>]]> The "FHIR structures" for DSTU1 (the classes which model the
resources and composite datatypes) have been moved out of the core JAR into their
own JAR, in order to allow support for DEV resources, and DSTU2 resources when thast
version is finalized. See
<![CDATA[<a href="./doc_upgrading.html">upgrading</a>]]>
for more information.
</action>
<action type="fix">
<![CDATA[
<b>Deprocated API Removal</b>: The following classes (which were deprocated previously)
have now been removed:
<ul>
<li><b>ISecurityManager</b>: If you are using this class, the same functionality
is available through the more general purpose
<a href="http://jamesagnew.github.io/hapi-fhir/doc_rest_server_interceptor.html">server interceptor</a>
capabilities.
<li><b>CodingListParam</b>: This class was made redundant by the
<a href="http://jamesagnew.github.io/hapi-fhir/apidocs/ca/uhn/fhir/rest/param/TokenOrListParam.html">TokenOrListParam</a>
class, which can be used in its place.
</ul>
]]>
</action>
<action type="add" issue="38" dev="wdebeau1">
Profile generation on the server was not working due to IdDt being
incorrectly used. Thanks to Bill de Beaubien for the pull request!
</action>
<action type="add" issue="42">
<action type="add" issue="42" dev="wdebeau1">
Profiles did not generate correctly if a resource definition class had a
defined extension which was of a composite type. Thanks to Bill de Beaubien for the pull request!
</action>
@ -19,7 +42,7 @@
Remove unnessecary IOException from narrative generator API. Thanks to
Petro Mykhailysyn for the pull request!
</action>
<action type="add" issue="48">
<action type="add" issue="48" dev="wdebeau1">
Introduced a new
<![CDATA[<code>@ProvidesResources</code>]]> annotation which can be added to
resource provider and servers to allow them to declare additional resource
@ -27,6 +50,33 @@
serve up multiple classes for the same resource type (e.g. a server that sometimes
returns a default Patient, but sometimes uses a custom subclass).
Thanks to Bill de Beaubien for the pull request!
</action>
<action type="add">
Add a new method <![CDATA[handleException]]> to the server interceptor
framework which allows interceptors to be notified of any exceptions and
runtime errors within server methods. Interceptors may optionally also
override the default error handling behaviour of the RestfulServer.
</action>
<action dev="wdebeau1" type="add">
Add constants to BaseResource for the "_id" search parameter which all resources
should support.
</action>
<action type="fix">
DateRangeParam parameters on the server now return correct
<![CDATA[<code>getLowerBoundAsInstant()</code>]]>
and
<![CDATA[<code>getUpperBoundAsInstant()</code>]]>
values if a single unqualified value is passed in. For example, if
a query containing
<![CDATA[<code>&birthdate=2012-10-01</code>]]>
is received, previously these two methods would both return the same
value, but with this fix
<![CDATA[<code>getUpperBoundAsInstant()</code>]]>
now returns the instant at 23:59:59.9999.
</action>
<action type="fix">
Resource fields with a type of "*" (or Any) sometimes failed to parse if a
value type of "code" was used. Thanks to Bill de Beaubien for reporting!
</action>
</release>
<release version="0.7" date="2014-Oct-23">

View File

@ -0,0 +1,476 @@
<?xml version="1.0"?>
<document xmlns="http://maven.apache.org/changes/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/changes/1.0.0 ./changes.xsd">
<properties>
<author>James Agnew</author>
<title>HAPI FHIR Changelog</title>
</properties>
<body>
<release version="0.8" date="TBD">
<<<<<<< HEAD:src/changes/changes.xml
<action type="add" issue="38">
Profile generation on the server was not working due to IdDt being
incorrectly used. Thanks to Bill de Beaubien for the pull request!
</action>
<action type="add" issue="42">
=======
<action>
<![CDATA[<b>API CHANGE:</b>]]> The "FHIR structures" for DSTU1 (the classes which model the
resources and composite datatypes) have been moved out of the core JAR into their
own JAR, in order to allow support for DEV resources, and DSTU2 resources when thast
version is finalized. See
<![CDATA[<a href="./doc_upgrading.html">upgrading</a>]]>
for more information.
</action>
<action type="add" issue="38" dev="wdebeau1">
Profile generation on the server was not working due to IdDt being
incorrectly used. Thanks to Bill de Beaubien for the pull request!
</action>
<action type="add" issue="42" dev="wdebeau1">
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2:src/changes/changes.xml
Profiles did not generate correctly if a resource definition class had a
defined extension which was of a composite type. Thanks to Bill de Beaubien for the pull request!
</action>
<action type="add" issue="44" dev="petromykhailysyn">
Remove unnessecary IOException from narrative generator API. Thanks to
Petro Mykhailysyn for the pull request!
</action>
<<<<<<< HEAD:src/changes/changes.xml
=======
<action type="add" issue="48" dev="wdebeau1">
Introduced a new
<![CDATA[<code>@ProvidesResources</code>]]> annotation which can be added to
resource provider and servers to allow them to declare additional resource
classes they are able to serve. This is useful if you have a server which can
serve up multiple classes for the same resource type (e.g. a server that sometimes
returns a default Patient, but sometimes uses a custom subclass).
Thanks to Bill de Beaubien for the pull request!
</action>
<action>
Add a new method <![CDATA[handleException]]> to the server interceptor
framework which allows interceptors to be notified of any exceptions and
runtime errors within server methods. Interceptors may optionally also
override the default error handling behaviour of the RestfulServer.
</action>
<action dev="wdebeau1">
Add constants to BaseResource for the "_id" search parameter which all resources
should support.
</action>
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2:src/changes/changes.xml
</release>
<release version="0.7" date="2014-Oct-23">
<action type="add" issue="30">
<![CDATA[<b>API CHANGE:</b>]]> The TagList class previously implemented ArrayList semantics,
but this has been replaced with LinkedHashMap semantics. This means that the list of
tags will no longer accept duplicate tags, but that tag order will still be
preserved. Thanks to Bill de Beaubien for reporting!
</action>
<action type="fix" issue="33">
Server was incorrectly including contained resources being returned as both contained resources, and as
top-level resources in the returned bundle for search operations.
Thanks to Bill de Beaubien for reporting! This also fixes Issue #20, thanks to
lephty for reporting!
</action>
<action type="add" dev="suranga">
Documentation fixes
</action>
<action type="add" dev="dougmartin">
Add a collection of new methods on the generic client which support the
<![CDATA[
<b><a href="./apidocs/ca/uhn/fhir/rest/client/IGenericClient.html#read(java.lang.Class,%20ca.uhn.fhir.model.primitive.UriDt)">read</a></b>,
<b><a href="./apidocs/ca/uhn/fhir/rest/client/IGenericClient.html#vread(java.lang.Class,%20ca.uhn.fhir.model.primitive.UriDt)">read</a></b>,
and <b><a href="./apidocs/ca/uhn/fhir/rest/client/IGenericClient.html#search(java.lang.Class,%20ca.uhn.fhir.model.primitive.UriDt)">search</a></b>
]]>
operations using an absolute URL. This allows developers to perform these operations using
URLs they obtained from other sources (or external resource references within resources). In
addition, the existing read/vread operations will now access absolute URL references if
they are passed in. Thanks to Doug Martin of the Regenstrief Center for Biomedical Informatics
for contributing this implementation!
</action>
<action type="fix">
Server implementation was not correctly figuring out its own FHIR Base URL when deployed
on Amazon Web Service server. Thanks to Jeffrey Ting and Bill De Beaubien of
Systems Made Simple for their help in figuring out this issue!
</action>
<action type="fix">
XML Parser failed to encode fields with both a resource reference child and
a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of
Systems Made Simple for their help in figuring out this issue!
</action>
<action type="fix">
HAPI now runs successfully on Servlet 2.5 containers (such as Tomcat 6). Thanks to
Bernard Gitaadji for reporting and diagnosing the issue!
</action>
<action type="fix">
Summary (in the bundle entry) is now encoded by the XML and JSON parsers if supplied. Thanks to David Hay of
Orion Health for reporting this!
</action>
<action type="fix" issue="24">
Conformance profiles which are automatically generated by the server were missing a few mandatory elements,
which meant that the profile did not correctly validate. Thanks to Bill de Beaubien of Systems Made Simple
for reporting this!
</action>
<action type="fix">
XHTML (in narratives) containing escapable characters (e.g. &lt; or &quot;) will now always have those characters
escaped properly in encoded messages.
</action>
<action type="fix">
Resources containing entities which are not valid in basic XML (e.g. &amp;sect;) will have those
entities converted to their equivalent unicode characters when resources are encoded, since FHIR does
not allow extended entities in resource instances.
</action>
<action type="add">
Add a new client interceptor which adds HTTP Authorization Bearer Tokens (for use with OAUTH2 servers)
to client requests.
</action>
<action type="fix">
Add phloc-commons dependency explicitly, which resolves an issue building HAPI from source on
some platforms. Thanks to Odysseas Pentakalos for the patch!
</action>
<action type="add">
HAPI now logs a single line indicating the StAX implementation being used upon the
first time an XML parser is created.
</action>
<action type="fix">
Update methods on the server did not return a "content-location" header, but
only a "location" header. Both are required according to the FHIR specification.
Thanks to Bill de Beaubien of Systems Made Simple for reporting this!
</action>
<action type="fix" issue="26" dev="akley">
Parser failed to correctly read contained Binary resources. Thanks to Alexander Kley for
the patch!
</action>
<action type="fix" issue="29" dev="akley">
Calling encode multiple times on a resource with contained resources caused the contained
resources to be re-added (and the actual message to grow) with each encode pass. Thanks to
Alexander Kley for the test case!
</action>
<action type="fix">
JSON-encoded contained resources with the incorrect "_id" element (which should be "id", but some
incorrect examples exist on the FHIR specification) now parse correctly. In other words, HAPI
previously only accepted the correct "id" element, but now it also accepts the incorrect
"_id" element just to be more lenient.
</action>
<action type="fix">
Several unit tests failed on Windows (or any platform with non UTF-8 default encoding). This may
have also caused resource validation to fail occasionally on these platforms as well.
Thanks to Bill de Beaubien for reporting!
</action>
<action type="fix">
toString() method on TokenParam was incorrectly showing the system as the value.
Thanks to Bill de Beaubien for reporting!
</action>
<action type="update">
Documentation on contained resources contained a typo and did not actually produce contained resources. Thanks
to David Hay of Orion Health for reporting!
</action>
<action type="add" issue="31" dev="preston">
Add a
<![CDATA[<a href="https://www.vagrantup.com/">Vagrant</a>]]>
based environment (basically a fully built, self contained development environment) for
trying out the HAPI server modules. Thanks to Preston Lee for the pull request, and for
offering to maintain this!
</action>
<action type="add" issue="32" dev="jathman">
Change validation API so that it uses a return type instead of exceptions to communicate
validation failures. Thanks to Joe Athman for the pull request!
</action>
<action type="add" issue="35" dev="petromykhailysyn">
Add a client interceptor which adds an HTTP cookie to each client request. Thanks to
Petro Mykhailysyn for the pull request!
</action>
</release>
<release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!">
<!--
<action type="add">
Allow generic client ... OAUTH
</action>
-->
<action type="add">
Add server interceptor framework, and new interceptor for logging incoming
requests.
</action>
<action type="add">
Add server validation framework for validating resources against the FHIR schemas and schematrons
</action>
<action type="fix">
Tester UI created double _format and _pretty param entries in searches. Thanks to Gered King of University
Health Network for reporting!
</action>
<action type="fix" issue="4">
Create method was incorrectly returning an HTTP 204 on sucessful completion, but
should be returning an HTTP 200 per the FHIR specification. Thanks to wanghaisheng
for reporting!
</action>
<action type="fix">
FHIR Tester UI now correctly sends UTF-8 charset in responses so that message payloads containing
non US-ASCII characters will correctly display in the browser
</action>
<action type="fix">
JSON parser was incorrectly encoding extensions on composite elements outside the element itself
(as is done correctly for non-composite elements) instead of inside of them. Thanks to David Hay of
Orion for reporting this!
</action>
<action type="add">
Contained/included resource instances received by a client are now automatically
added to any ResourceReferenceDt instancea in other resources which reference them.
</action>
<action type="add">
Add documentation on how to use eBay CORS Filter to support Cross Origin Resource
Sharing (CORS) to server. CORS support that was built in to the server itself has
been removed, as it did not work correctly (and was reinventing a wheel that others
have done a great job inventing). Thanks to Peter Bernhardt of Relay Health for all the assistance
in testing this!
</action>
<action type="fix">
IResource interface did not expose the getLanguage/setLanguage methods from BaseResource,
so the resource language was difficult to access.
</action>
<action type="fix">
JSON Parser now gives a more friendly error message if it tries to parse JSON with invalid use
of single quotes
</action>
<action type="add">
Transaction server method is now allowed to return an OperationOutcome in addition to the
incoming resources. The public test server now does this in order to return status information
about the transaction processing.
</action>
<action type="add">
Update method in the server can now flag (via a field on the MethodOutcome object being returned)
that the result was actually a creation, and Create method can indicate that it was actually an
update. This has no effect other than to switch between the HTTP 200 and HTTP 201 status codes on the
response, but this may be useful in some circumstances.
</action>
<action type="fix">
Annotation client search methods with a specific resource type (e.g. List&lt;Patient&gt; search())
won't return any resources that aren't of the correct type that are received in a response
bundle (generally these are referenced resources, so they are populated in the reference fields instead).
Thanks to Tahura Chaudhry of University Health Network for the unit test!
</action>
<action type="add">
Added narrative generator template for OperationOutcome resource
</action>
<action type="fix">
Date/time types did not correctly parse values in the format "yyyymmdd" (although the FHIR-defined format
is "yyyy-mm-dd" anyhow, and this is correctly handled). Thanks to Jeffrey Ting of Systems Made Simple
for reporting!
</action>
<action type="fix">
Server search method for an unnamed query gets called if the client requests a named query
with the same parameter list. Thanks to Neal Acharya of University Health Network for reporting!
</action>
<action type="fix">
Category header (for tags) is correctly read in client for "read" operation
</action>
<action type="add">
Transaction method in server can now have parameter type Bundle instead of
List&lt;IResource&gt;
</action>
<action type="add">
HAPI parsers now use field access to get/set values instead of method accessors and mutators.
This should give a small performance boost.
</action>
<action type="fix">
JSON parser encodes resource references incorrectly, using the name "resource" instead
of the name "reference" for the actual reference. Thanks to
Ricky Nguyen for reporting and tracking down the issue!
</action>
<action type="fix">
Rename NotImpementedException to NotImplementedException (to correct typo)
</action>
<action type="fix">
Server setUseBrowserFriendlyContentType setting also respected for errors (e.g. OperationOutcome with 4xx/5xx status)
</action>
<action type="fix">
Fix performance issue in date/time datatypes where pattern matchers were not static
</action>
<action type="fix">
Server now gives a more helpful error message if a @Read method has a search parameter (which is invalid, but
previously lead to a very unhelpful error message). Thanks to Tahura Chaudhry of UHN for reporting!
</action>
<action type="fix">
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>
<action type="fix" issue="14">
If a server defines a method with parameter "_id", incoming search requests for that method may
get delegated to the wrong method. Thanks to Neal Acharya for reporting!
</action>
<action type="add">
SecurityEvent.Object structural element has been renamed to
SecurityEvent.ObjectElement to avoid conflicting names with the
java Object class. Thanks to Laurie Macdougall-Sookraj of UHN for
reporting!
</action>
<action type="fix">
Text/narrative blocks that were created with a non-empty
namespace prefix (e.g. &lt;xhtml:div xmlns:xhtml="..."&gt;...&lt;/xhtml:div&gt;)
failed to encode correctly (prefix was missing in encoded resource)
</action>
<action type="fix">
Resource references previously encoded their children (display and reference)
in the wrong order so references with both would fail schema validation.
</action>
<action type="add">
SecurityEvent resource's enums now use friendly enum names instead of the unfriendly
numeric code values. Thanks to Laurie MacDougall-Sookraj of UHN for the
suggestion!
</action>
</release>
<release version="0.5" date="2014-Jul-30">
<action type="add">
HAPI has a number of RESTful method parameter types that have similar but not identical
purposes and confusing names. A cleanup has been undertaken to clean this up.
This means that a number of existing classes
have been deprocated in favour of new naming schemes.
<![CDATA[<br/><br/>]]>
All annotation-based clients and all server search method parameters are now named
(type)Param, for example: StringParam, TokenParam, etc.
<![CDATA[<br/><br/>]]>
All generic/fluent client method parameters are now named
(type)ClientParam, for example: StringClientParam, TokenClientParam, etc.
<![CDATA[<br/><br/>]]>
All renamed classes have been retained and deprocated, so this change should not cause any issues
for existing applications but those applications should be refactored to use the
new parameters when possible.
</action>
<action type="add">
Allow server methods to return wildcard generic types (e.g. List&lt;? extends IResource&gt;)
</action>
<action type="add">
Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as
"&amp;identifier=system|codepart1\|codepart2"
</action>
<action type="add">
Add support for OPTIONS verb (which returns the server conformance statement)
</action>
<action type="add">
Add support for CORS headers in server
</action>
<action type="add">
Bump SLF4j dependency to latest version (1.7.7)
</action>
<action type="add">
Add interceptor framework for clients (annotation based and generic), and add interceptors
for configurable logging, capturing requests and responses, and HTTP basic auth.
</action>
<action type="fix">
Transaction client invocations with XML encoding were using the wrong content type ("application/xml+fhir" instead
of the correct "application/atom+xml"). Thanks to David Hay of Orion Health for surfacing this one!
</action>
<action type="add">
Bundle entries now support a link type of "search". Thanks to David Hay for the suggestion!
</action>
<action type="add" issue="1">
If a client receives a non 2xx response (e.g. HTTP 500) and the response body is a text/plain message or
an OperationOutcome resource, include the message in the exception message so that it will be
more conveniently displayed in logs and other places. Thanks to Neal Acharya for the suggestion!
</action>
<action type="add" issue="2">
Read invocations in the client now process the "Content-Location" header and use it to
populate the ID of the returned resource. Thanks to Neal Acharya for the suggestion!
</action>
<action type="fix" issue="3">
Fix issue where vread invocations on server incorrectly get routed to instance history method if one is
defined. Thanks to Neal Acharya from UHN for surfacing this one!
</action>
<action type="add">
Binary reads on a server not include the Content-Disposition header, to prevent HTML in binary
blobs from being used for nefarious purposes. See
<![CDATA[<a href="http://gforge.hl7.org/gf/project/fhir/tracker/?action=TrackerItemEdit&tracker_id=677&tracker_item_id=3298">FHIR Tracker Bug 3298</a>]]>
for more information.
</action>
<action type="add">
Support has been added for using an HTTP proxy for outgoing requests.
</action>
<action type="fix">
Fix: Primitive extensions declared against custom resource types
are encoded even if they have no value. Thanks to David Hay of Orion for
reporting this!
</action>
<action type="fix">
Fix: RESTful server deployed to a location where the URL to access it contained a
space (e.g. a WAR file with a space in the name) failed to work correctly.
Thanks to David Hay of Orion for reporting this!
</action>
</release>
<release version="0.4" date="2014-Jul-13">
<action type="add">
<![CDATA[<b>BREAKING CHANGE:</b>]]>: IdDt has been modified so that it
contains a partial or complete resource identity. Previously it contained
only the simple alphanumeric id of the resource (the part at the end of the "read" URL for
that resource) but it can now contain a complete URL or even a partial URL (e.g. "Patient/123")
and can optionally contain a version (e.g. "Patient/123/_history/456"). New methods have
been added to this datatype which provide just the numeric portion. See the JavaDoc
for more information.
</action>
<action type="add">
<![CDATA[<b>API CHANGE:</b>]]>: Most elements in the HAPI FHIR model contain
a getId() and setId() method. This method is confusing because it is only actually used
for IDREF elements (which are rare) but its name makes it easy to confuse with more
important identifiers. For this reason, these methods have been deprocated and replaced with
get/setElementSpecificId() methods. The old methods will be removed at some point. Resource
types are unchanged and retain their get/setId methods.
</action>
<action type="add">
Allow use of QuantityDt as a service parameter to support the "quantity" type. Previously
QuantityDt did not implement IQueryParameterType so it was not valid, and there was no way to
support quantity search parameters on the server (e.g. Observation.value-quantity)
</action>
<action type="add">
Introduce StringParameter type which can be used as a RESTful operation search parameter
type. StringParameter allows ":exact" matches to be specified in clients, and handled in servers.
</action>
<action type="add">
Parsers (XML/JSON) now support deleted entries in bundles
</action>
<action type="add">
Transaction method now supported in servers
</action>
<action type="add">
Support for Binary resources added (in servers, clients, parsers, etc.)
</action>
<action type="fix">
Support for Query resources fixed (in parser)
</action>
<action type="fix">
Nested contained resources (e.g. encoding a resource with a contained resource that itself contains a resource)
now parse and encode correctly, meaning that all contained resources are placed in the "contained" element
of the root resource, and the parser looks in the root resource for all container levels when stitching
contained resources back together.
</action>
<action type="fix">
Server methods with @Include parameter would sometimes fail when no _include was actually
specified in query strings.
</action>
<action type="fix">
Client requests for IdentifierDt types (such as Patient.identifier) did not create the correct
query string if the system is null.
</action>
<action type="add">
Add support for paging responses from RESTful servers.
</action>
<action type="fix">
Don't fail on narrative blocks in JSON resources with only an XML declaration but no content (these are
produced by the Health Intersections server)
</action>
<action type="fix">
Server now automatically compresses responses if the client indicates support
</action>
<action type="fix">
Server failed to support optional parameters when type is String and :exact qualifier is used
</action>
<action type="fix">
Read method in client correctly populated resource ID in returned object
</action>
<action type="add">
Support added for deleted-entry by/name, by/email, and comment from Tombstones spec
</action>
</release>
<release version="0.3" date="2014-May-12" description="This release corrects lots of bugs and introduces the fluent client mode">
</release>
</body>
</document>

View File

@ -0,0 +1 @@
<mxGraphModel dx="940" dy="431" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" fold="1" page="1" pageScale="1" pageWidth="826" pageHeight="1169" style="default-style2" math="0"><root><mxCell id="0"/><mxCell id="1" parent="0"/><mxCell id="2" value="RESTful&#xa;Server" style="shape=umlLifeline;perimeter=lifelinePerimeter;size=46;strokeColor=#0000FF;strokeWidth=2;fillColor=#99FFFF" parent="1" vertex="1"><mxGeometry x="150" y="20" width="100" height="280" as="geometry"/></mxCell><mxCell id="3" value="Interceptor" style="shape=umlLifeline;perimeter=lifelinePerimeter;size=46;strokeColor=#0000FF;strokeWidth=2;fillColor=#99FFFF" parent="1" vertex="1"><mxGeometry x="280" y="20" width="100" height="280" as="geometry"/></mxCell><mxCell id="4" value="Resource/Plain&#xa;Provider&#xa;Method" style="shape=umlLifeline;perimeter=lifelinePerimeter;size=46;strokeColor=#0000FF;strokeWidth=2;fillColor=#99FFFF" parent="1" vertex="1"><mxGeometry x="400" y="20" width="100" height="280" as="geometry"/></mxCell><mxCell id="7" value="" style="ellipse;shape=startState;fillColor=#000000;strokeColor=#ff0000;" parent="1" vertex="1"><mxGeometry x="70" y="80" width="30" height="30" as="geometry"/></mxCell><mxCell id="8" value="Incoming Request" style="edgeStyle=elbowEdgeStyle;elbow=horizontal;verticalAlign=bottom;endArrow=open;endSize=8;strokeColor=#ff0000;entryX=0.5;entryY=0.3;entryPerimeter=0" parent="1" source="7" edge="1"><mxGeometry x="70" y="80" as="geometry"><mxPoint x="200" y="95" as="targetPoint"/></mxGeometry></mxCell><mxCell id="21" value="Request is handled" style="rounded=1;whiteSpace=wrap" parent="1" vertex="1"><mxGeometry x="390" y="150" width="120" height="30" as="geometry"/></mxCell><mxCell id="22" value="" style="edgeStyle=none;align=left;entryX=0.5;entryY=0.632;entryPerimeter=0;exitX=0.5;exitY=0.632;exitPerimeter=0" parent="1" edge="1"><mxGeometry width="100" height="100" relative="1" as="geometry"><mxPoint x="200" y="140.15999999999997" as="sourcePoint"/><mxPoint x="450" y="140.15999999999997" as="targetPoint"/></mxGeometry></mxCell><mxCell id="24" value="" parent="1" vertex="1"><mxGeometry x="320" y="233" width="20" height="27" as="geometry"/></mxCell><mxCell id="25" value="handleException" style="edgeStyle=elbowEdgeStyle;elbow=vertical;verticalAlign=bottom;endArrow=block;exitX=0.5;exitY=0.478;exitPerimeter=0;align=left" parent="1" target="24" edge="1"><mxGeometry x="221.75" y="233.25" as="geometry"><mxPoint x="200" y="233.39999999999998" as="sourcePoint"/></mxGeometry></mxCell><mxCell id="26" value="return true;" style="edgeStyle=elbowEdgeStyle;elbow=vertical;verticalAlign=bottom;dashed=1;endArrow=open;endSize=8;" parent="1" source="24" edge="1"><mxGeometry x="221.75" y="233.25" as="geometry"><mxPoint x="200" y="260" as="targetPoint"/></mxGeometry></mxCell><mxCell id="27" value="" style="ellipse;shape=endState;fillColor=#000000;strokeColor=#ff0000;align=left" parent="1" vertex="1"><mxGeometry x="70" y="270" width="30" height="30" as="geometry"/></mxCell><mxCell id="28" value="Response" style="edgeStyle=orthogonalEdgeStyle;endArrow=block;dashed=0;dashPattern=1 4;align=left;entryX=1;entryY=0.5;exitX=0.5;exitY=0.954;exitPerimeter=0;endFill=1;strokeWidth=1;strokeColor=#FF0000" parent="1" target="27" edge="1"><mxGeometry x="0.500299820107935" y="-13" width="100" height="100" relative="1" as="geometry"><mxPoint x="200" y="285.05999999999995" as="sourcePoint"/><mxPoint x="650" y="213" as="targetPoint"/><mxPoint x="-8" y="-12" as="offset"/></mxGeometry></mxCell><mxCell id="29" value="" style="ellipse;shape=cloud;whiteSpace=wrap;html=1;" vertex="1" parent="1"><mxGeometry x="175" y="100" width="50" height="30" as="geometry"/></mxCell><mxCell id="30" value="throw exception" style="edgeStyle=elbowEdgeStyle;elbow=vertical;verticalAlign=bottom;dashed=1;endArrow=open;endSize=8;" edge="1" parent="1"><mxGeometry x="351.75" y="173.25" as="geometry"><mxPoint x="200" y="200" as="targetPoint"/><mxPoint x="450" y="200" as="sourcePoint"/></mxGeometry></mxCell></root></mxGraphModel>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
In this directory:
* XCF files are opened in The GIMP
* XML files are opened in draw.io

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.6 KiB

124
src/site/site.xml.orig Normal file
View File

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<project xmlns="http://maven.apache.org/DECORATION/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/DECORATION/1.1.0 http://maven.apache.org/xsd/decoration-1.1.0.xsd" name="HAPI">
<bannerLeft>
<name>HAPI</name>
<src>images/hapi_fhir_banner.png</src>
<href>http://jamesagnew.github.io/hapi-fhir/</href>
</bannerLeft>
<bannerRight>
<name>FHIR</name>
<src>images/hapi_fhir_banner_right.png</src>
<href>http://jamesagnew.github.io/hapi-fhir/</href>
</bannerRight>
<poweredBy>
<logo name="Hosted on GitHub" href="https://github.com/jamesagnew/hapi-fhir" img="./images/github-logo-mini.png"/>
<logo name="Built with Maven 3" href="http://maven.apache.org" img="./images/maven-logo-mini.png" />
</poweredBy>
<version position="left" />
<body>
<head>
<!-- Syntax Highlighter -->
<script type="text/javascript" src="syntaxhighlighter/shCore.js"></script>
<script type="text/javascript" src="syntaxhighlighter/shBrushJScript.js"></script>
<script type="text/javascript" src="syntaxhighlighter/shBrushJava.js"></script>
<script type="text/javascript" src="syntaxhighlighter/shBrushBash.js"></script>
<script type="text/javascript" src="syntaxhighlighter/shBrushXml.js"></script>
<link href="syntaxhighlighter/shCore.css" rel="stylesheet" type="text/css" />
<link href="syntaxhighlighter/shThemeDefault.css" rel="stylesheet" type="text/css" />
<!--
HAPI stylesheet comes after because it overwrites the Syntax Highlighter
font size
-->
<link rel="shortcut icon" href="https://github.com/jamesagnew/hapi-fhir/images/favicon.png" />
<link rel="stylesheet" type="text/css" href="hapi.css" />
</head>
<links>
<item name="GitHub Page" href="https://github.com/jamesagnew/hapi-fhir/" />
<item name="hl7.org" href="http://hl7.org/" />
<item name="University Health Network" href="http://www.uhn.ca/" />
</links>
<menu name="Welcome">
<item name="Welcome" href="index.html" />
<item name="Download" href="./download.html" />
<item name="Upgrade Guide" href="./doc_upgrading.html" />
<item name="Changelog" href="./changes-report.html" />
</menu>
<menu name="Test Server">
<item name="Public Test Server" href="http://fhirtest.uhn.ca"/>
<item name="Vagrant (Private) Test Server" href="doc_vagrant.html"/>
</menu>
<menu name="Documentation">
<item name="Introduction" href="./doc_intro.html" />
<item name="The Data Model" href="./doc_fhirobjects.html">
<item name="Profiles &amp; Extensions" href="./doc_extensions.html" />
<item name="Resource References" href="./doc_resource_references.html" />
<item name="Tags" href="./doc_tags.html" />
<item name="Validation" href="./doc_validation.html" />
</item>
<item name="RESTful Client" href="./doc_rest_client.html" >
<item name="Interceptors (client)" href="./doc_rest_client_interceptor.html"/>
</item>
<item name="RESTful Server" href="./doc_rest_server.html" >
<item name="RESTful Operations" href="./doc_rest_operations.html" />
<item name="Narrative Generator" href="./doc_narrative.html" />
<item name="CORS Support" href="./doc_cors.html" />
<item name="Interceptors (server)" href="./doc_rest_server_interceptor.html" />
<item name="Web Testing UI" href="./doc_server_tester.html" />
</item>
<item name="Logging" href="./doc_logging.html" />
<item name="Tinder Plugin" href="./doc_tinder.html" />
</menu>
<menu name="Community">
<item name="Google Group" href="https://groups.google.com/d/forum/hapi-fhir" />
<item name="Issue Tracker" href="https://github.com/jamesagnew/hapi-fhir/issues" />
</menu>
<menu name="JavaDocs">
<<<<<<< HEAD:src/site/site.xml
<item name="API (Core)" href="./apidocs/index.html" />
<item name="API (DSTU Model)" href="./apidocs-dstu/index.html" />
<item name="API (DEV Model)" href="./apidocs-dev/index.html" />
=======
<item name="Core API" href="./apidocs/index.html" />
<item name="Model API (DSTU1)" href="./apidocs-dstu/index.html" />
<item name="Model API (DEV)" href="./apidocs-dev/index.html" />
>>>>>>> d22a35788f57e9f7ce64bc8afc2ee7eaf29d94f2:src/site/site.xml
<item name="Source Code" href=".https://github.com/jamesagnew/hapi-fhir" />
</menu>
<menu name="Reports">
<item name="Developers" href="team-list.html" />
<item name="Unit Test Report" href="surefire-report.html" />
<item name="FindBugs" href="findbugs.html" />
<item name="License" href="license.html" />
<item name="Source Code" href="https://github.com/jamesagnew/hapi-fhir" />
</menu>
</body>
<skin>
<groupId>org.apache.maven.skins</groupId>
<artifactId>maven-fluido-skin</artifactId>
<version>1.3.1</version>
</skin>
<custom>
<fluidoSkin>
<googleSearch />
<!-- <sourceLineNumbersEnabled>true</sourceLineNumbersEnabled> -->
</fluidoSkin>
</custom>
</project>

View File

@ -120,7 +120,7 @@
</p>
<macro name="snippet">
<param name="file" value="src/test/resources/narrative/Practitioner.html" />
<param name="file" value="hapi-fhir-structures-dstu/src/test/resources/narrative/Practitioner.html" />
</macro>
<p>

View File

@ -69,6 +69,32 @@
of the operation being invoked (resource, bundle, etc.)
</li>
</ul>
<br clear="all"/>
<subsection name="Exception Handling">
<img src="svg/restful-server-interceptors-exception.svg" alt="Interceptors" align="right"/>
<p>
In the event of an exception being thrown within the server, the interceptor
method
<code><a href="./apidocs/ca/uhn/fhir/rest/server/interceptor/IServerInterceptor.html#handleException(ca.uhn.fhir.rest.method.RequestDetails,%20java.lang.Throwable,%20javax.servlet.http.HttpServletRequest,%20javax.servlet.http.HttpServletResponse)">handleException</a></code>
will be called. This applies both to HAPI-FHIR defined exceptions thrown within resource provider methods
you have created as well as unexpected exceptions such as NullPointerException thrown
at any point in the handling chain.
</p>
<p>
In general, you will want to return <code>true</code> from the <code>handleException</code>
method, which means that processing continues normally (RestfulServer will return an
HTTP 4xx or 5xx response automatically depending on the specific exception which was thrown).
</p>
<p>
However, you may override the server's built-in exception handling by returning
<code>false</code>. In this case, you must provide your own response by
interacting with the <code>HttpServletResponse</code> object which is
passed in.
</p>
</subsection>
<br clear="all"/>
<subsection name="Registering Interceptors">
@ -129,6 +155,29 @@
</section>
<section name="Creating Interceptors">
<p>
Creating your own interceptors is easy. HAPI-FHIR provides a class called
<code>InterceptorAdapter</code> which you can extend and then override any
methods you wish. The following example shows a simple request counter.
</p>
<macro name="snippet">
<param name="id" value="interceptor" />
<param name="file" value="examples/src/main/java/example/RequestCounterInterceptor.java" />
</macro>
<p>
The following example shows an exception handling interceptor which
overrides the built-in exception handling by providing a custom response.
</p>
<macro name="snippet">
<param name="id" value="interceptor" />
<param name="file" value="examples/src/main/java/example/RequestExceptionInterceptor.java" />
</macro>
</section>
</body>
</document>

View File

@ -86,7 +86,7 @@
and copy in the following contents:
</p>
<macro name="snippet">
<param name="file" value="../restful-server-example/src/main/webapp/WEB-INF/hapi-fhir-tester-config.xml" />
<param name="file" value="restful-server-example/src/main/webapp/WEB-INF/hapi-fhir-tester-config.xml" />
</macro>
<p>

View File

@ -13,6 +13,22 @@
<macro name="toc">
</macro>
<subsection name="Tinder Plugin">
<p>
If you are using the "Tinder" Maven plugin to generate structure code,
you will need to add a structure dependency to the plugin configuration
itself in your project pom.xml. See the
<a href="./doc_tinder.html">Tinder Page</a> for an example of
how to do this.
</p>
</subsection>
</section>
<section name="Upgrading to HAPI FHIR 0.5">
<p>
<b>This section is still incomplete: </b> Note that HAPI 0.8 has not
yet been released. This section provides details about how to use the
@ -28,21 +44,21 @@
</p>
<ul>
<li>
The <code>hapi-fhir-base-[version].jar</code> file containing the core library.
<i>Required:</i> The <code>hapi-fhir-base-[version].jar</code> file containing the core library.
</li>
<li>
The <code>hapi-fhir-structures-dstu-[version].jar</code> file containing the FHIR model classes
<i>Required:</i> The <code>hapi-fhir-structures-dstu-[version].jar</code> file containing the FHIR model classes
for DSTU1 (all contents of this JAR were previously found in hapi-fhir-base).
</li>
<li>
<i>Optionally: </i>You may also choose to include the
<i>Optional:</i> You may also choose to include the
<code>hapi-fhir-structures-dev-[version].jar</code>. This JAR contains structures for the
latest DEV version of FHIR. You may create a client/server which supports either DSTU1 or DEV
resources, or both depending on your needs. Note that using DEV resources may introduce
incompatibilities with other frameworks however.<br/><br/>
<b>You must also include hapi-fhir-structures-dstu-[version].jar</b> if you include
the dev structures JAR at this time. Hopefully at some point soon this requirement
will be relaxed.
incompatibilities with other frameworks however. If you are including this JAR,
<b>you must also include hapi-fhir-structures-dstu-[version].jar</b>.
Hopefully by the time 0.8 is final this requirement will be relaxed, but for now it
is mandatory.
</li>
</ul>