Merge branch 'master' of https://github.com/jamesagnew/hapi-fhir
This commit is contained in:
commit
4b730cc418
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>0.6</version>
|
||||
<version>0.7-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
|||
<dependency>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir-base</artifactId>
|
||||
<version>0.6</version>
|
||||
<version>0.7-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
|
|
|
@ -3,6 +3,7 @@ package example;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
@ -20,19 +21,25 @@ public class ExampleRestfulServlet extends RestfulServer {
|
|||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* The initialize method is automatically called when the servlet is starting up, so it can
|
||||
* be used to configure the servlet to define resource providers, or set up
|
||||
* configuration, interceptors, etc.
|
||||
*/
|
||||
public ExampleRestfulServlet() {
|
||||
/*
|
||||
* The servlet defines any number of resource providers, and
|
||||
* configures itself to use them by calling
|
||||
* setResourceProviders()
|
||||
*/
|
||||
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
|
||||
resourceProviders.add(new RestfulPatientResourceProvider());
|
||||
resourceProviders.add(new RestfulObservationResourceProvider());
|
||||
setResourceProviders(resourceProviders);
|
||||
}
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
/*
|
||||
* The servlet defines any number of resource providers, and
|
||||
* configures itself to use them by calling
|
||||
* setResourceProviders()
|
||||
*/
|
||||
List<IResourceProvider> resourceProviders = new ArrayList<IResourceProvider>();
|
||||
resourceProviders.add(new RestfulPatientResourceProvider());
|
||||
resourceProviders.add(new RestfulObservationResourceProvider());
|
||||
setResourceProviders(resourceProviders);
|
||||
}
|
||||
|
||||
}
|
||||
//END SNIPPET: servlet
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import ca.uhn.fhir.model.dstu.composite.CodingDt;
|
|||
import ca.uhn.fhir.model.dstu.composite.HumanNameDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.PeriodDt;
|
||||
import ca.uhn.fhir.model.dstu.composite.QuantityDt;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
|
||||
|
@ -16,88 +17,103 @@ import ca.uhn.fhir.model.primitive.StringDt;
|
|||
|
||||
public class FhirDataModel {
|
||||
|
||||
public static void datatypes() {
|
||||
// START SNIPPET: datatypes
|
||||
Observation obs = new Observation();
|
||||
public static void datatypes() {
|
||||
// START SNIPPET: datatypes
|
||||
Observation obs = new Observation();
|
||||
|
||||
// These are all equivalent
|
||||
obs.setIssued(new InstantDt(new Date()));
|
||||
obs.setIssued(new Date(), TemporalPrecisionEnum.MILLI);
|
||||
obs.setIssuedWithMillisPrecision(new Date());
|
||||
// These are all equivalent
|
||||
obs.setIssued(new InstantDt(new Date()));
|
||||
obs.setIssued(new Date(), TemporalPrecisionEnum.MILLI);
|
||||
obs.setIssuedWithMillisPrecision(new Date());
|
||||
|
||||
// The InstantDt also lets you work with the instant as a Java Date
|
||||
// object or as a FHIR String.
|
||||
Date date = obs.getIssued().getValue(); // A date object
|
||||
String dateString = obs.getIssued().getValueAsString(); // "2014-03-08T12:59:58.068-05:00"
|
||||
// END SNIPPET: datatypes
|
||||
// The InstantDt also lets you work with the instant as a Java Date
|
||||
// object or as a FHIR String.
|
||||
Date date = obs.getIssued().getValue(); // A date object
|
||||
String dateString = obs.getIssued().getValueAsString(); // "2014-03-08T12:59:58.068-05:00"
|
||||
// END SNIPPET: datatypes
|
||||
|
||||
System.out.println(date);
|
||||
System.out.println(dateString);
|
||||
System.out.println(date);
|
||||
System.out.println(dateString);
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void nonNull() {
|
||||
// START SNIPPET: nonNull
|
||||
Observation observation = new Observation();
|
||||
}
|
||||
|
||||
// None of these calls will return null, but instead create their respective
|
||||
// child elements.
|
||||
IdentifierDt identifierDt = observation.getIdentifier();
|
||||
PeriodDt periodDt = observation.getIdentifier().getPeriod();
|
||||
DateTimeDt activeDt = observation.getIdentifier().getPeriod().getStart();
|
||||
@SuppressWarnings("unused")
|
||||
public void nonNull() {
|
||||
// START SNIPPET: nonNull
|
||||
Observation observation = new Observation();
|
||||
|
||||
// DateTimeDt is a FHIR primitive however, so the following will return null
|
||||
// unless a value has been placed there.
|
||||
Date active = observation.getIdentifier().getPeriod().getStart().getValue();
|
||||
// END SNIPPET: nonNull
|
||||
// None of these calls will return null, but instead create their
|
||||
// respective
|
||||
// child elements.
|
||||
IdentifierDt identifierDt = observation.getIdentifier();
|
||||
PeriodDt periodDt = observation.getIdentifier().getPeriod();
|
||||
DateTimeDt activeDt = observation.getIdentifier().getPeriod().getStart();
|
||||
|
||||
// DateTimeDt is a FHIR primitive however, so the following will return
|
||||
// null
|
||||
// unless a value has been placed there.
|
||||
Date active = observation.getIdentifier().getPeriod().getStart().getValue();
|
||||
// END SNIPPET: nonNull
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
public static void codes() {
|
||||
// START SNIPPET: codes
|
||||
Patient patient = new Patient();
|
||||
}
|
||||
|
||||
// Coded types can naturally be set using plain Strings
|
||||
CodingDt genderCoding = patient.getGender().addCoding();
|
||||
genderCoding.setSystem("http://hl7.org/fhir/v3/AdministrativeGender");
|
||||
genderCoding.setCode("M");
|
||||
public static void codes() {
|
||||
// START SNIPPET: codes
|
||||
Patient patient = new Patient();
|
||||
|
||||
// This is equivalent to the three statements above
|
||||
patient.setGender(AdministrativeGenderCodesEnum.M);
|
||||
// END SNIPPET: codes
|
||||
// Coded types can naturally be set using plain Strings
|
||||
CodingDt genderCoding = patient.getGender().addCoding();
|
||||
genderCoding.setSystem("http://hl7.org/fhir/v3/AdministrativeGender");
|
||||
genderCoding.setCode("M");
|
||||
|
||||
// This is equivalent to the three statements above
|
||||
patient.setGender(AdministrativeGenderCodesEnum.M);
|
||||
// END SNIPPET: codes
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
datatypes();
|
||||
|
||||
// START SNIPPET: observation
|
||||
Observation observation = new Observation();
|
||||
|
||||
// Create a quantity datatype
|
||||
QuantityDt q = new QuantityDt();
|
||||
q.setValue(185);
|
||||
q.setSystem("http://unitsofmeasure.org");
|
||||
q.setCode("lbs");
|
||||
|
||||
// Put the datatype in the observation
|
||||
observation.setValue(q);
|
||||
|
||||
// Set the reference range
|
||||
observation.getReferenceRangeFirstRep().setLow(100);
|
||||
observation.getReferenceRangeFirstRep().setHigh(200);
|
||||
|
||||
// END SNIPPET: observation
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void namesHard() {
|
||||
// START SNIPPET: namesHard
|
||||
Patient patient = new Patient();
|
||||
HumanNameDt name = patient.addName();
|
||||
StringDt family = name.addFamily();
|
||||
family.setValue("Smith");
|
||||
StringDt firstName = name.addGiven();
|
||||
firstName.setValue("Rob");
|
||||
StringDt secondName = name.addGiven();
|
||||
secondName.setValue("Bruce");
|
||||
// END SNIPPET: namesHard
|
||||
}
|
||||
|
||||
public void namesEasy() {
|
||||
// START SNIPPET: namesEasy
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("Smith").addGiven("Rob").addGiven("Bruce");
|
||||
// END SNIPPET: namesEasy
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
datatypes();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void namesHard() {
|
||||
// START SNIPPET: namesHard
|
||||
Patient patient = new Patient();
|
||||
HumanNameDt name = patient.addName();
|
||||
StringDt family = name.addFamily();
|
||||
family.setValue("Smith");
|
||||
StringDt firstName = name.addGiven();
|
||||
firstName.setValue("Rob");
|
||||
StringDt secondName = name.addGiven();
|
||||
secondName.setValue("Bruce");
|
||||
//END SNIPPET: namesHard
|
||||
}
|
||||
|
||||
public void namesEasy() {
|
||||
// START SNIPPET: namesEasy
|
||||
Patient patient = new Patient();
|
||||
patient.addName().addFamily("Smith").addGiven("Rob").addGiven("Bruce");
|
||||
//END SNIPPET: namesEasy
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package example;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.annotation.WebServlet;
|
||||
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.interceptor.LoggingInterceptor;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class ServletExamples {
|
||||
|
||||
// START SNIPPET: loggingInterceptor
|
||||
@WebServlet(urlPatterns = { "/fhir/*" }, displayName = "FHIR Server")
|
||||
public class RestfulServerWithLogging extends RestfulServer {
|
||||
|
||||
@Override
|
||||
protected void initialize() throws ServletException {
|
||||
|
||||
// ... define your resource providers here ...
|
||||
|
||||
// Now register the logging interceptor
|
||||
LoggingInterceptor loggingInterceptor = new LoggingInterceptor();
|
||||
registerInterceptor(loggingInterceptor);
|
||||
|
||||
// The SLF4j logger "test.accesslog" will receive the logging events
|
||||
loggingInterceptor.setLoggerName("test.accesslog");
|
||||
|
||||
// This is the format for each line. A number of substitution variables may
|
||||
// be used here. See the JavaDoc for LoggingInterceptor for information on
|
||||
// what is available.
|
||||
loggingInterceptor.setMessageFormat("Source[${remoteAddr}] Operation[${operationType} ${idOrResourceName}] UA[${requestHeader.user-agent}] Params[${requestParameters}]");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// END SNIPPET: loggingInterceptor
|
||||
}
|
|
@ -1,8 +1,15 @@
|
|||
package example;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.io.filefilter.WildcardFileFilter;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
@ -11,8 +18,7 @@ import ca.uhn.fhir.validation.ValidationFailureException;
|
|||
|
||||
public class ValidatorExamples {
|
||||
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
|
||||
public void validateResource() {
|
||||
//START SNIPPET: basicValidation
|
||||
// As always, you need a context
|
||||
FhirContext ctx = new FhirContext();
|
||||
|
@ -35,10 +41,45 @@ public class ValidatorExamples {
|
|||
|
||||
System.out.println("Validation failed");
|
||||
|
||||
// The ValidationFailureException which gets thrown by the validator
|
||||
// will contain an OperationOutcome resource describing the failure
|
||||
String results = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome());
|
||||
System.out.println(results);
|
||||
}
|
||||
//END SNIPPET: basicValidation
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws DataFormatException, IOException {
|
||||
validateFiles();
|
||||
|
||||
}
|
||||
|
||||
private static void validateFiles() throws IOException, FileNotFoundException {
|
||||
//START SNIPPET: validateFiles
|
||||
FhirContext ctx = new FhirContext();
|
||||
|
||||
// Create a validator and configure it
|
||||
FhirValidator validator = ctx.newValidator();
|
||||
validator.setValidateAgainstStandardSchema(true);
|
||||
validator.setValidateAgainstStandardSchematron(true);
|
||||
|
||||
// Get a list of files in a given directory
|
||||
String[] fileList = new File("/home/some/dir").list(new WildcardFileFilter("*.txt"));
|
||||
for (String nextFile : fileList) {
|
||||
|
||||
// For each file, load the contents into a string
|
||||
String nextFileContents = IOUtils.toString(new FileReader(nextFile));
|
||||
|
||||
// Parse that string (this example assumes JSON encoding)
|
||||
IResource resource = ctx.newJsonParser().parseResource(nextFileContents);
|
||||
|
||||
// Apply the validation. This will throw an exception on the first validation failure
|
||||
validator.validate(resource);
|
||||
}
|
||||
|
||||
// If we make it here with no exception, all the files validated!
|
||||
//START SNIPPET: validateFiles
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<parent>
|
||||
<groupId>ca.uhn.hapi.fhir</groupId>
|
||||
<artifactId>hapi-fhir</artifactId>
|
||||
<version>0.6</version>
|
||||
<version>0.7-SNAPSHOT</version>
|
||||
<relativePath>../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
|
@ -225,6 +225,13 @@
|
|||
<version>9.1.1.v20140108</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-http</artifactId>
|
||||
<version>9.1.1.v20140108</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- UNIT TEST DEPENDENCIES -->
|
||||
<dependency>
|
||||
|
@ -521,7 +528,6 @@
|
|||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<version>${maven_site_plugin_version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>stage-for-scm-publish</id>
|
||||
|
|
|
@ -6,7 +6,30 @@
|
|||
<title>HAPI FHIR Changelog</title>
|
||||
</properties>
|
||||
<body>
|
||||
<release version="0.6" date="TBD">
|
||||
<release version="0.7" date="TBD">
|
||||
<action type="add">
|
||||
Documentation update, thanks to Suranga Nath Kasthurirathne of the OpenMRS project.
|
||||
</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">
|
||||
XHTML (in narratives) containing escapable characters (e.g. < or ") will now always have those characters
|
||||
escaped properly in encoded messages.
|
||||
</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
|
||||
|
|
|
@ -0,0 +1,324 @@
|
|||
<?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.7" date="TBD">
|
||||
<action type="add">
|
||||
Documentation update, thanks to Suranga Nath Kasthurirathne of the OpenMRS project.
|
||||
</action>
|
||||
<action type="fix">
|
||||
<<<<<<< HEAD
|
||||
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!
|
||||
=======
|
||||
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">
|
||||
XHTML (in narratives) containing escapable characters (e.g. < or ") will now always have those characters
|
||||
escaped properly in encoded messages.
|
||||
>>>>>>> 83f9c1c6a992266de12f9076b733dffdaaf63203
|
||||
</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<Patient> 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<IResource>
|
||||
</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. <xhtml:div xmlns:xhtml="...">...</xhtml:div>)
|
||||
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">
|
||||
having multiple ways of accomplishing the same thing. 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<? extends IResource>)
|
||||
</action>
|
||||
<action type="add">
|
||||
Search parameters are not properly escaped and unescaped. E.g. for a token parameter such as
|
||||
"&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>
|
|
@ -107,6 +107,8 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
|
||||
if (IResource.class.isAssignableFrom(next)) {
|
||||
myDatatypeToElementDefinition.put(ResourceReferenceDt.class, nextDef);
|
||||
alternateElementName = getElementName() + "Resource";
|
||||
myDatatypeToElementName.put(ResourceReferenceDt.class, alternateElementName);
|
||||
}
|
||||
|
||||
myDatatypeToElementDefinition.put(next, nextDef);
|
||||
|
|
|
@ -20,8 +20,12 @@ package ca.uhn.fhir.model.primitive;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -33,6 +37,10 @@ import javax.xml.stream.XMLOutputFactory;
|
|||
import javax.xml.stream.XMLStreamException;
|
||||
import javax.xml.stream.events.XMLEvent;
|
||||
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.codehaus.stax2.XMLOutputFactory2;
|
||||
import org.codehaus.stax2.io.EscapingWriterFactory;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.model.api.BasePrimitive;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
|
@ -50,7 +58,7 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
public XhtmlDt() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor which accepts a string code
|
||||
*
|
||||
|
@ -64,9 +72,8 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
/**
|
||||
* Accepts a textual DIV and parses it into XHTML events which are stored internally.
|
||||
* <p>
|
||||
* <b>Formatting note:</b> The text will be trimmed {@link String#trim()}. If the text does not start with
|
||||
* an HTML tag (generally this would be a div tag), a div tag will be automatically
|
||||
* placed surrounding the text.
|
||||
* <b>Formatting note:</b> The text will be trimmed {@link String#trim()}. If the text does not start with an HTML tag (generally this would be a div tag), a div tag will be automatically placed
|
||||
* surrounding the text.
|
||||
* </p>
|
||||
*/
|
||||
@Override
|
||||
|
@ -75,7 +82,7 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
myValue = null;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
String val = theValue.trim();
|
||||
if (!val.startsWith("<")) {
|
||||
val = "<div>" + val + "</div>";
|
||||
|
@ -84,7 +91,7 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
myValue = null;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
ArrayList<XMLEvent> value = new ArrayList<XMLEvent>();
|
||||
XMLEventReader er = XMLInputFactory.newInstance().createXMLEventReader(new StringReader(val));
|
||||
|
@ -101,9 +108,9 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
}
|
||||
}
|
||||
setValue(value);
|
||||
|
||||
|
||||
} catch (XMLStreamException e) {
|
||||
throw new DataFormatException("String does not appear to be valid XML/XHTML (error is \""+e.getMessage() + "\"): " + theValue, e);
|
||||
throw new DataFormatException("String does not appear to be valid XML/XHTML (error is \"" + e.getMessage() + "\"): " + theValue, e);
|
||||
} catch (FactoryConfigurationError e) {
|
||||
throw new ConfigurationException(e);
|
||||
}
|
||||
|
@ -116,9 +123,17 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
}
|
||||
try {
|
||||
StringWriter w = new StringWriter();
|
||||
XMLEventWriter ew = XMLOutputFactory.newInstance().createXMLEventWriter(w);
|
||||
XMLOutputFactory newInstance = XMLOutputFactory.newInstance();
|
||||
|
||||
newInstance.setProperty(XMLOutputFactory2.P_TEXT_ESCAPER, new MyEscaper());
|
||||
|
||||
XMLEventWriter ew = newInstance.createXMLEventWriter(w);
|
||||
for (XMLEvent next : myValue) {
|
||||
ew.add(next);
|
||||
if (next.isCharacters()) {
|
||||
ew.add(next);
|
||||
} else {
|
||||
ew.add(next);
|
||||
}
|
||||
}
|
||||
ew.close();
|
||||
return w.toString();
|
||||
|
@ -129,6 +144,55 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
|
|||
}
|
||||
}
|
||||
|
||||
private static class MyEscaper implements EscapingWriterFactory {
|
||||
|
||||
@Override
|
||||
public Writer createEscapingWriterFor(final Writer theW, String theEnc) throws UnsupportedEncodingException {
|
||||
return new Writer() {
|
||||
|
||||
@Override
|
||||
public void write(char[] theCbuf, int theOff, int theLen) throws IOException {
|
||||
boolean hasEscapable = false;
|
||||
for (int i = 0; i < theLen && !hasEscapable; i++) {
|
||||
char nextChar = theCbuf[i + theOff];
|
||||
switch (nextChar) {
|
||||
case '<':
|
||||
case '>':
|
||||
case '"':
|
||||
case '&':
|
||||
hasEscapable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasEscapable) {
|
||||
theW.write(theCbuf, theOff, theLen);
|
||||
return;
|
||||
}
|
||||
|
||||
String escaped = StringEscapeUtils.escapeXml10(new String(theCbuf, theOff, theLen));
|
||||
theW.write(escaped.toCharArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
theW.flush();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
theW.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Writer createEscapingWriterFor(OutputStream theOut, String theEnc) throws UnsupportedEncodingException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<XMLEvent> getValue() {
|
||||
return myValue;
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.lang.annotation.Target;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
|
||||
|
||||
|
@ -76,5 +77,12 @@ public @interface Search {
|
|||
*/
|
||||
// NB: Read, Search (maybe others) share this annotation method, so update the javadocs everywhere
|
||||
Class<? extends IResource> type() default IResource.class;
|
||||
|
||||
/**
|
||||
* This is an experimental option - Use with caution
|
||||
*
|
||||
* @see IDynamicSearchResourceProvider
|
||||
*/
|
||||
boolean dynamic() default false;
|
||||
|
||||
}
|
||||
|
|
|
@ -63,8 +63,10 @@ import ca.uhn.fhir.rest.server.BundleProviders;
|
|||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.rest.server.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
@ -82,7 +84,6 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
|||
private FhirContext myContext;
|
||||
private Method myMethod;
|
||||
private List<IParameter> myParameters;
|
||||
|
||||
private Object myProvider;
|
||||
|
||||
public BaseMethodBinding(Method theMethod, FhirContext theContext, Object theProvider) {
|
||||
|
@ -92,7 +93,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
|||
myMethod = theMethod;
|
||||
myContext = theContext;
|
||||
myProvider = theProvider;
|
||||
myParameters = MethodUtil.getResourceParameters(theMethod);
|
||||
myParameters = MethodUtil.getResourceParameters(theMethod, theProvider);
|
||||
}
|
||||
|
||||
public List<Class<?>> getAllowableParamAnnotations() {
|
||||
|
@ -349,7 +350,12 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
|
|||
if (read != null) {
|
||||
return new ReadMethodBinding(returnType, theMethod, theContext, theProvider);
|
||||
} else if (search != null) {
|
||||
return new SearchMethodBinding(returnType, theMethod, theContext, theProvider);
|
||||
if (search.dynamic()) {
|
||||
IDynamicSearchResourceProvider provider = (IDynamicSearchResourceProvider) theProvider;
|
||||
return new DynamicSearchMethodBinding(returnType, theMethod, theContext, provider);
|
||||
} else {
|
||||
return new SearchMethodBinding(returnType, theMethod, theContext, theProvider);
|
||||
}
|
||||
} else if (conformance != null) {
|
||||
return new ConformanceMethodBinding(theMethod, theContext, theProvider);
|
||||
} else if (create != null) {
|
||||
|
|
|
@ -172,12 +172,14 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
|
|||
break;
|
||||
|
||||
case UPDATE:
|
||||
if (response.getCreated() == null || Boolean.FALSE.equals(response.getCreated())) {
|
||||
if (response == null || response.getCreated() == null || Boolean.FALSE.equals(response.getCreated())) {
|
||||
servletResponse.setStatus(Constants.STATUS_HTTP_200_OK);
|
||||
} else {
|
||||
servletResponse.setStatus(Constants.STATUS_HTTP_201_CREATED);
|
||||
}
|
||||
addLocationHeader(theRequest, servletResponse, response);
|
||||
if (response != null && response.getId() != null) {
|
||||
addLocationHeader(theRequest, servletResponse, response);
|
||||
}
|
||||
break;
|
||||
|
||||
case VALIDATE:
|
||||
|
|
|
@ -0,0 +1,164 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.IBundleProvider;
|
||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBinding {
|
||||
|
||||
private IDynamicSearchResourceProvider myProvider;
|
||||
private List<RuntimeSearchParam> mySearchParameters;
|
||||
private HashSet<String> myParamNames;
|
||||
private Integer myIdParamIndex;
|
||||
|
||||
public DynamicSearchMethodBinding(Class<? extends IResource> theReturnResourceType, Method theMethod, FhirContext theConetxt, IDynamicSearchResourceProvider theProvider) {
|
||||
super(theReturnResourceType, theMethod, theConetxt, theProvider);
|
||||
|
||||
myProvider = theProvider;
|
||||
mySearchParameters = myProvider.getSearchParameters();
|
||||
|
||||
myParamNames = new HashSet<String>();
|
||||
for (RuntimeSearchParam next : mySearchParameters) {
|
||||
myParamNames.add(next.getName());
|
||||
}
|
||||
|
||||
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IParameter> getParameters() {
|
||||
List<IParameter> retVal = new ArrayList<IParameter>(super.getParameters());
|
||||
|
||||
for (RuntimeSearchParam next : mySearchParameters) {
|
||||
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnTypeEnum getReturnType() {
|
||||
return ReturnTypeEnum.BUNDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBundleProvider invokeServer(RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
|
||||
if (myIdParamIndex != null) {
|
||||
theMethodParams[myIdParamIndex] = theRequest.getId();
|
||||
}
|
||||
|
||||
Object response = invokeServerMethod(theMethodParams);
|
||||
return toResourceList(response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestfulOperationTypeEnum getResourceOperationType() {
|
||||
return RestfulOperationTypeEnum.SEARCH_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestfulOperationSystemEnum getSystemOperationType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DynamicSearchMethodBinding.class);
|
||||
|
||||
@Override
|
||||
public boolean incomingServerRequestMatchesMethod(Request theRequest) {
|
||||
if (!theRequest.getResourceName().equals(getResourceName())) {
|
||||
ourLog.trace("Method {} doesn't match because resource name {} != {}", getMethod().getName(), theRequest.getResourceName(), getResourceName());
|
||||
return false;
|
||||
}
|
||||
if (theRequest.getId() != null && myIdParamIndex == null) {
|
||||
ourLog.trace("Method {} doesn't match because ID is not null: {}", theRequest.getId());
|
||||
return false;
|
||||
}
|
||||
if (theRequest.getRequestType() == RequestType.GET && theRequest.getOperation() != null && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) {
|
||||
ourLog.trace("Method {} doesn't match because request type is GET but operation is not null: {}", theRequest.getId(), theRequest.getOperation());
|
||||
return false;
|
||||
}
|
||||
if (theRequest.getRequestType() == RequestType.POST && !Constants.PARAM_SEARCH.equals(theRequest.getOperation())) {
|
||||
ourLog.trace("Method {} doesn't match because request type is POST but operation is not _search: {}", theRequest.getId(), theRequest.getOperation());
|
||||
return false;
|
||||
}
|
||||
if (theRequest.getRequestType() != RequestType.GET && theRequest.getRequestType() != RequestType.POST) {
|
||||
ourLog.trace("Method {} doesn't match because request type is {}", getMethod());
|
||||
return false;
|
||||
}
|
||||
if (theRequest.getCompartmentName() != null) {
|
||||
ourLog.trace("Method {} doesn't match because it is for compartment {}", new Object[] { getMethod(), theRequest.getCompartmentName() });
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String next : theRequest.getParameters().keySet()) {
|
||||
if (next.charAt(0) == '_') {
|
||||
continue;
|
||||
}
|
||||
String nextQualified = next;
|
||||
int colonIndex = next.indexOf(':');
|
||||
int dotIndex = next.indexOf('.');
|
||||
if (colonIndex != -1 || dotIndex != -1) {
|
||||
int index;
|
||||
if (colonIndex != -1 && dotIndex != -1) {
|
||||
index = Math.min(colonIndex, dotIndex);
|
||||
} else {
|
||||
index = (colonIndex != -1) ? colonIndex : dotIndex;
|
||||
}
|
||||
next = next.substring(0, index);
|
||||
}
|
||||
if (!myParamNames.contains(next)) {
|
||||
ourLog.trace("Method {} doesn't match because has parameter {}", new Object[] { getMethod(), nextQualified });
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
|
||||
// there should be no way to call this....
|
||||
throw new UnsupportedOperationException("Dynamic search methods are only used for server implementations");
|
||||
}
|
||||
|
||||
public Collection<? extends RuntimeSearchParam> getSearchParams() {
|
||||
return mySearchParameters;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.param.CompositeOrListParam;
|
||||
import ca.uhn.fhir.rest.param.DateOrListParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.NumberOrListParam;
|
||||
import ca.uhn.fhir.rest.param.NumberParam;
|
||||
import ca.uhn.fhir.rest.param.QuantityOrListParam;
|
||||
import ca.uhn.fhir.rest.param.QuantityParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenParam;
|
||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.SearchParameterMap;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class DynamicSearchParameter implements IParameter {
|
||||
|
||||
private Map<String, RuntimeSearchParam> myNameToParam = new HashMap<String, RuntimeSearchParam>();
|
||||
|
||||
public DynamicSearchParameter(IDynamicSearchResourceProvider theProvider) {
|
||||
for (RuntimeSearchParam next : theProvider.getSearchParameters()) {
|
||||
myNameToParam.put(next.getName(), next);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void translateClientArgumentIntoQueryArgument(FhirContext theContext, Object theSourceClientArgument, Map<String, List<String>> theTargetQueryArguments, BaseHttpClientInvocation theClientInvocation) throws InternalErrorException {
|
||||
throw new UnsupportedOperationException("Dynamic search is not supported in client mode (use fluent client for dynamic-like searches)");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Object translateQueryParametersIntoServerArgument(Request theRequest, Object theRequestContents) throws InternalErrorException, InvalidRequestException {
|
||||
SearchParameterMap retVal = new SearchParameterMap();
|
||||
|
||||
for (String next : theRequest.getParameters().keySet()) {
|
||||
String qualifier = null;
|
||||
String qualifiedParamName = next;
|
||||
RuntimeSearchParam param = myNameToParam.get(next);
|
||||
if (param == null) {
|
||||
int colonIndex = next.indexOf(':');
|
||||
int dotIndex = next.indexOf('.');
|
||||
if (colonIndex != -1 || dotIndex != -1) {
|
||||
int index;
|
||||
if (colonIndex != -1 && dotIndex != -1) {
|
||||
index = Math.min(colonIndex, dotIndex);
|
||||
} else {
|
||||
index = (colonIndex != -1) ? colonIndex : dotIndex;
|
||||
}
|
||||
qualifier = next.substring(index);
|
||||
next = next.substring(0, index);
|
||||
param = myNameToParam.get(next);
|
||||
}
|
||||
}
|
||||
|
||||
if (param != null) {
|
||||
|
||||
for (String nextValue : theRequest.getParameters().get(qualifiedParamName)) {
|
||||
QualifiedParamList paramList = QualifiedParamList.splitQueryStringByCommasIgnoreEscape(qualifier, nextValue);
|
||||
|
||||
switch (param.getParamType()) {
|
||||
case COMPOSITE:
|
||||
Class<? extends IQueryParameterType> left = toParamType(param.getCompositeOf().get(0));
|
||||
Class<? extends IQueryParameterType> right = toParamType(param.getCompositeOf().get(0));
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
CompositeOrListParam compositeOrListParam = new CompositeOrListParam(left, right);
|
||||
compositeOrListParam.setValuesAsQueryTokens(paramList);
|
||||
retVal.add(next, compositeOrListParam);
|
||||
break;
|
||||
case DATE:
|
||||
DateOrListParam dateOrListParam = new DateOrListParam();
|
||||
dateOrListParam.setValuesAsQueryTokens(paramList);
|
||||
retVal.add(next, dateOrListParam);
|
||||
break;
|
||||
case NUMBER:
|
||||
NumberOrListParam numberOrListParam = new NumberOrListParam();
|
||||
numberOrListParam.setValuesAsQueryTokens(paramList);
|
||||
retVal.add(next, numberOrListParam);
|
||||
break;
|
||||
case QUANTITY:
|
||||
QuantityOrListParam quantityOrListParam = new QuantityOrListParam();
|
||||
quantityOrListParam.setValuesAsQueryTokens(paramList);
|
||||
retVal.add(next, quantityOrListParam);
|
||||
break;
|
||||
case REFERENCE:
|
||||
ReferenceOrListParam referenceOrListParam = new ReferenceOrListParam();
|
||||
referenceOrListParam.setValuesAsQueryTokens(paramList);
|
||||
retVal.add(next, referenceOrListParam);
|
||||
break;
|
||||
case STRING:
|
||||
StringOrListParam stringOrListParam = new StringOrListParam();
|
||||
stringOrListParam.setValuesAsQueryTokens(paramList);
|
||||
retVal.add(next, stringOrListParam);
|
||||
break;
|
||||
case TOKEN:
|
||||
TokenOrListParam tokenOrListParam = new TokenOrListParam();
|
||||
tokenOrListParam.setValuesAsQueryTokens(paramList);
|
||||
retVal.add(next, tokenOrListParam);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private Class<? extends IQueryParameterType> toParamType(RuntimeSearchParam theRuntimeSearchParam) {
|
||||
switch (theRuntimeSearchParam.getParamType()) {
|
||||
case COMPOSITE:
|
||||
throw new IllegalStateException("Composite subtype");
|
||||
case DATE:
|
||||
return DateParam.class;
|
||||
case NUMBER:
|
||||
return NumberParam.class;
|
||||
case QUANTITY:
|
||||
return QuantityParam.class;
|
||||
case REFERENCE:
|
||||
return ReferenceParam.class;
|
||||
case STRING:
|
||||
return StringParam.class;
|
||||
case TOKEN:
|
||||
return TokenParam.class;
|
||||
default:
|
||||
throw new IllegalStateException("null type");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initializeTypes(Method theMethod, Class<? extends Collection<?>> theOuterCollectionType, Class<? extends Collection<?>> theInnerCollectionType, Class<?> theParameterType) {
|
||||
// nothing
|
||||
}
|
||||
|
||||
}
|
|
@ -1,7 +1,6 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PushbackReader;
|
||||
|
@ -45,6 +44,7 @@ import ca.uhn.fhir.rest.annotation.IncludeParam;
|
|||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.ServerBase;
|
||||
import ca.uhn.fhir.rest.annotation.Since;
|
||||
import ca.uhn.fhir.rest.annotation.Sort;
|
||||
|
@ -57,6 +57,8 @@ import ca.uhn.fhir.rest.param.CollectionBinder;
|
|||
import ca.uhn.fhir.rest.param.ResourceParameter;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.SearchParameterMap;
|
||||
import ca.uhn.fhir.util.ReflectionUtil;
|
||||
|
||||
/*
|
||||
|
@ -91,7 +93,7 @@ public class MethodUtil {
|
|||
urlBuilder.append(resourceName);
|
||||
urlBuilder.append('/');
|
||||
urlBuilder.append(theId.getIdPart());
|
||||
|
||||
|
||||
HttpPutClientInvocation retVal;
|
||||
String urlExtension = urlBuilder.toString();
|
||||
if (StringUtils.isBlank(theResourceBody)) {
|
||||
|
@ -109,10 +111,10 @@ public class MethodUtil {
|
|||
urlBuilder.append(versionId);
|
||||
retVal.addHeader(Constants.HEADER_CONTENT_LOCATION, urlBuilder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
addTagsToPostOrPut(theResource, retVal);
|
||||
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -135,7 +137,7 @@ public class MethodUtil {
|
|||
String headerValue = clHeaders.get(0);
|
||||
resource.getId().setValue(headerValue);
|
||||
}
|
||||
|
||||
|
||||
List<String> categoryHeaders = theHeaders.get(Constants.HEADER_CATEGORY_LC);
|
||||
if (categoryHeaders != null && categoryHeaders.size() > 0 && StringUtils.isNotBlank(categoryHeaders.get(0))) {
|
||||
TagList tagList = new TagList();
|
||||
|
@ -223,7 +225,6 @@ public class MethodUtil {
|
|||
|
||||
}
|
||||
|
||||
|
||||
static void addTagsToPostOrPut(IResource resource, BaseHttpClientInvocation retVal) {
|
||||
TagList list = (TagList) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
|
||||
if (list != null) {
|
||||
|
@ -265,8 +266,7 @@ public class MethodUtil {
|
|||
return new HttpGetClientInvocation("metadata");
|
||||
}
|
||||
|
||||
public static MethodOutcome process2xxResponse(FhirContext theContext, String theResourceName, int theResponseStatusCode, String theResponseMimeType, Reader theResponseReader,
|
||||
Map<String, List<String>> theHeaders) {
|
||||
public static MethodOutcome process2xxResponse(FhirContext theContext, String theResourceName, int theResponseStatusCode, String theResponseMimeType, Reader theResponseReader, Map<String, List<String>> theHeaders) {
|
||||
List<String> locationHeaders = new ArrayList<String>();
|
||||
List<String> lh = theHeaders.get(Constants.HEADER_LOCATION_LC);
|
||||
if (lh != null) {
|
||||
|
@ -378,7 +378,7 @@ public class MethodUtil {
|
|||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static List<IParameter> getResourceParameters(Method theMethod) {
|
||||
public static List<IParameter> getResourceParameters(Method theMethod, Object theProvider) {
|
||||
List<IParameter> parameters = new ArrayList<IParameter>();
|
||||
|
||||
Class<?>[] parameterTypes = theMethod.getParameterTypes();
|
||||
|
@ -389,7 +389,14 @@ public class MethodUtil {
|
|||
Class<?> parameterType = parameterTypes[paramIndex];
|
||||
Class<? extends java.util.Collection<?>> outerCollectionType = null;
|
||||
Class<? extends java.util.Collection<?>> innerCollectionType = null;
|
||||
if (TagList.class.isAssignableFrom(parameterType)) {
|
||||
if (SearchParameterMap.class.equals(parameterType)) {
|
||||
if (theProvider instanceof IDynamicSearchResourceProvider) {
|
||||
Search searchAnnotation = theMethod.getAnnotation(Search.class);
|
||||
if (searchAnnotation != null && searchAnnotation.dynamic()) {
|
||||
param = new DynamicSearchParameter((IDynamicSearchResourceProvider) theProvider);
|
||||
}
|
||||
}
|
||||
} else if (TagList.class.isAssignableFrom(parameterType)) {
|
||||
// TagList is handled directly within the method bindings
|
||||
param = new NullParameter();
|
||||
} else {
|
||||
|
@ -403,8 +410,7 @@ public class MethodUtil {
|
|||
parameterType = ReflectionUtil.getGenericCollectionTypeOfMethodParameter(theMethod, paramIndex);
|
||||
}
|
||||
if (Collection.class.isAssignableFrom(parameterType)) {
|
||||
throw new ConfigurationException("Argument #" + paramIndex + " of Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName()
|
||||
+ "' is of an invalid generic type (can not be a collection of a collection of a collection)");
|
||||
throw new ConfigurationException("Argument #" + paramIndex + " of Method '" + theMethod.getName() + "' in type '" + theMethod.getDeclaringClass().getCanonicalName() + "' is of an invalid generic type (can not be a collection of a collection of a collection)");
|
||||
}
|
||||
}
|
||||
if (parameterType.equals(HttpServletRequest.class) || parameterType.equals(ServletRequest.class)) {
|
||||
|
@ -443,19 +449,16 @@ public class MethodUtil {
|
|||
instantiableCollectionType = null;
|
||||
specType = String.class;
|
||||
} else if ((parameterType != Include.class && parameterType != PathSpecification.class) || innerCollectionType == null || outerCollectionType != null) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + IncludeParam.class.getSimpleName() + " but has a type other than Collection<"
|
||||
+ Include.class.getSimpleName() + ">");
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + IncludeParam.class.getSimpleName() + " but has a type other than Collection<" + Include.class.getSimpleName() + ">");
|
||||
} else {
|
||||
instantiableCollectionType = (Class<? extends Collection<Include>>) CollectionBinder.getInstantiableCollectionType(innerCollectionType, "Method '" + theMethod.getName()
|
||||
+ "'");
|
||||
instantiableCollectionType = (Class<? extends Collection<Include>>) CollectionBinder.getInstantiableCollectionType(innerCollectionType, "Method '" + theMethod.getName() + "'");
|
||||
specType = parameterType;
|
||||
}
|
||||
|
||||
param = new IncludeParameter((IncludeParam) nextAnnotation, instantiableCollectionType, specType);
|
||||
} else if (nextAnnotation instanceof ResourceParam) {
|
||||
if (!IResource.class.isAssignableFrom(parameterType)) {
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + ResourceParam.class.getSimpleName()
|
||||
+ " but has a type that is not an implemtation of " + IResource.class.getCanonicalName());
|
||||
throw new ConfigurationException("Method '" + theMethod.getName() + "' is annotated with @" + ResourceParam.class.getSimpleName() + " but has a type that is not an implemtation of " + IResource.class.getCanonicalName());
|
||||
}
|
||||
param = new ResourceParameter((Class<? extends IResource>) parameterType);
|
||||
} else if (nextAnnotation instanceof IdParam || nextAnnotation instanceof VersionIdParam) {
|
||||
|
@ -479,8 +482,8 @@ public class MethodUtil {
|
|||
}
|
||||
|
||||
if (param == null) {
|
||||
throw new ConfigurationException("Parameter #" + ((paramIndex + 1)) + "/" + (parameterTypes.length) + " of method '" + theMethod.getName() + "' on type '"
|
||||
+ theMethod.getDeclaringClass().getCanonicalName() + "' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter");
|
||||
throw new ConfigurationException("Parameter #" + ((paramIndex + 1)) + "/" + (parameterTypes.length) + " of method '" + theMethod.getName() + "' on type '" + theMethod.getDeclaringClass().getCanonicalName()
|
||||
+ "' has no recognized FHIR interface parameter annotations. Don't know how to handle this parameter");
|
||||
}
|
||||
|
||||
param.initializeTypes(theMethod, outerCollectionType, innerCollectionType, parameterType);
|
||||
|
|
|
@ -23,7 +23,6 @@ package ca.uhn.fhir.rest.method;
|
|||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
|
||||
|
@ -41,7 +40,7 @@ public class QualifiedParamList extends ArrayList<String> {
|
|||
super(theCapacity);
|
||||
}
|
||||
|
||||
public QualifiedParamList(FhirContext theContext, IQueryParameterOr<?> theNextOr) {
|
||||
public QualifiedParamList(IQueryParameterOr<?> theNextOr) {
|
||||
for (IQueryParameterType next : theNextOr.getValuesAsQueryTokens()) {
|
||||
if (myQualifier==null) {
|
||||
myQualifier=next.getQueryParameterQualifier();
|
||||
|
|
|
@ -60,7 +60,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
private Class<? extends IResource> myDeclaredResourceType;
|
||||
private String myDescription;
|
||||
private Integer myIdParamIndex;
|
||||
|
||||
private String myQueryName;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -118,40 +117,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
|
||||
}
|
||||
|
||||
public static QualifierDetails extractQualifiersFromParameterName(String theParamName) {
|
||||
QualifierDetails retVal = new QualifierDetails();
|
||||
if (theParamName == null || theParamName.length() == 0) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int dotIdx = -1;
|
||||
int colonIdx = -1;
|
||||
for (int idx = 0; idx < theParamName.length(); idx++) {
|
||||
char nextChar = theParamName.charAt(idx);
|
||||
if (nextChar == '.' && dotIdx == -1) {
|
||||
dotIdx = idx;
|
||||
} else if (nextChar == ':' && colonIdx == -1) {
|
||||
colonIdx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (dotIdx != -1 && colonIdx != -1) {
|
||||
if (dotIdx < colonIdx) {
|
||||
retVal.setDotQualifier(theParamName.substring(dotIdx, colonIdx));
|
||||
retVal.setColonQualifier(theParamName.substring(colonIdx));
|
||||
} else {
|
||||
retVal.setColonQualifier(theParamName.substring(colonIdx, dotIdx));
|
||||
retVal.setDotQualifier(theParamName.substring(dotIdx));
|
||||
}
|
||||
} else if (dotIdx != -1) {
|
||||
retVal.setDotQualifier(theParamName.substring(dotIdx));
|
||||
} else if (colonIdx != -1) {
|
||||
retVal.setColonQualifier(theParamName.substring(colonIdx));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public Class<? extends IResource> getDeclaredResourceType() {
|
||||
return myDeclaredResourceType;
|
||||
}
|
||||
|
@ -322,6 +287,15 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
|
||||
}
|
||||
|
||||
public void setResourceType(Class<? extends IResource> resourceType) {
|
||||
this.myDeclaredResourceType = resourceType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getMethod().toString();
|
||||
}
|
||||
|
||||
private List<String> processWhitelistAndBlacklist(List<String> theQualifiedNames, Set<String> theQualifierWhitelist, Set<String> theQualifierBlacklist) {
|
||||
if (theQualifierWhitelist == null && theQualifierBlacklist == null) {
|
||||
return theQualifiedNames;
|
||||
|
@ -337,10 +311,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
public void setResourceType(Class<? extends IResource> resourceType) {
|
||||
this.myDeclaredResourceType = resourceType;
|
||||
}
|
||||
|
||||
public static BaseHttpClientInvocation createSearchInvocation(FhirContext theContext, String theResourceName, Map<String, List<String>> theParameters, IdDt theId, String theCompartmentName,
|
||||
SearchStyleEnum theSearchStyle) {
|
||||
SearchStyleEnum searchStyle = theSearchStyle;
|
||||
|
@ -402,6 +372,40 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
return invocation;
|
||||
}
|
||||
|
||||
public static QualifierDetails extractQualifiersFromParameterName(String theParamName) {
|
||||
QualifierDetails retVal = new QualifierDetails();
|
||||
if (theParamName == null || theParamName.length() == 0) {
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int dotIdx = -1;
|
||||
int colonIdx = -1;
|
||||
for (int idx = 0; idx < theParamName.length(); idx++) {
|
||||
char nextChar = theParamName.charAt(idx);
|
||||
if (nextChar == '.' && dotIdx == -1) {
|
||||
dotIdx = idx;
|
||||
} else if (nextChar == ':' && colonIdx == -1) {
|
||||
colonIdx = idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (dotIdx != -1 && colonIdx != -1) {
|
||||
if (dotIdx < colonIdx) {
|
||||
retVal.setDotQualifier(theParamName.substring(dotIdx, colonIdx));
|
||||
retVal.setColonQualifier(theParamName.substring(colonIdx));
|
||||
} else {
|
||||
retVal.setColonQualifier(theParamName.substring(colonIdx, dotIdx));
|
||||
retVal.setDotQualifier(theParamName.substring(dotIdx));
|
||||
}
|
||||
} else if (dotIdx != -1) {
|
||||
retVal.setDotQualifier(theParamName.substring(dotIdx));
|
||||
} else if (colonIdx != -1) {
|
||||
retVal.setColonQualifier(theParamName.substring(colonIdx));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public static class QualifierDetails {
|
||||
|
||||
private String myColonQualifier;
|
||||
|
@ -467,11 +471,6 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getMethod().toString();
|
||||
}
|
||||
|
||||
public static enum RequestType {
|
||||
DELETE, GET, OPTIONS, POST, PUT
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ public class SearchParameter extends BaseQueryParameter {
|
|||
|
||||
List<IQueryParameterOr<?>> val = myParamBinder.encode(theContext, theObject);
|
||||
for (IQueryParameterOr<?> nextOr : val) {
|
||||
retVal.add(new QualifiedParamList(theContext, nextOr));
|
||||
retVal.add(new QualifiedParamList(nextOr));
|
||||
}
|
||||
|
||||
return retVal;
|
||||
|
|
|
@ -25,13 +25,18 @@ import java.util.List;
|
|||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
abstract class BaseAndListParam<T extends IQueryParameterOr<?>> implements IQueryParameterAnd<T> {
|
||||
public abstract class BaseAndListParam<T extends IQueryParameterOr<?>> implements IQueryParameterAnd<T> {
|
||||
|
||||
private List<T> myValues=new ArrayList<T>();
|
||||
|
||||
public void addValue(T theValue) {
|
||||
myValues.add(theValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(List<QualifiedParamList> theParameters) throws InvalidRequestException {
|
||||
myValues.clear();
|
||||
|
@ -42,6 +47,8 @@ abstract class BaseAndListParam<T extends IQueryParameterOr<?>> implements IQuer
|
|||
}
|
||||
}
|
||||
|
||||
public abstract SearchParamTypeEnum getSearchParamType();
|
||||
|
||||
abstract T newInstance();
|
||||
|
||||
@Override
|
||||
|
|
|
@ -25,6 +25,7 @@ import java.util.List;
|
|||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterAnd;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterOr;
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.method.QualifiedParamList;
|
||||
|
@ -33,10 +34,10 @@ abstract class BaseOrListParam<T extends IQueryParameterType> implements IQueryP
|
|||
|
||||
private List<T> myList=new ArrayList<T>();
|
||||
|
||||
public void addToken(T theParam) {
|
||||
Validate.notNull(theParam,"Param can not be null");
|
||||
myList.add(theParam);
|
||||
}
|
||||
// public void addToken(T theParam) {
|
||||
// Validate.notNull(theParam,"Param can not be null");
|
||||
// myList.add(theParam);
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
|
|
|
@ -117,7 +117,7 @@ public class CodingListParam implements IQueryParameterOr<IQueryParameterType>,
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
getCodings().clear();
|
||||
for (String string : theParameters) {
|
||||
CodingDt dt = new CodingDt();
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
|
@ -38,6 +39,11 @@ public class CompositeAndListParam<A extends IQueryParameterType, B extends IQue
|
|||
CompositeOrListParam<A,B> newInstance() {
|
||||
return new CompositeOrListParam<A,B>(myLeftType, myRightType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamTypeEnum getSearchParamType() {
|
||||
return SearchParamTypeEnum.COMPOSITE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -34,6 +34,14 @@ public class CompositeOrListParam<A extends IQueryParameterType, B extends IQuer
|
|||
myRightType = theRightType;
|
||||
}
|
||||
|
||||
public Class<A> getLeftType() {
|
||||
return myLeftType;
|
||||
}
|
||||
|
||||
public Class<B> getRightType() {
|
||||
return myRightType;
|
||||
}
|
||||
|
||||
@Override
|
||||
CompositeParam<A,B> newInstance() {
|
||||
return new CompositeParam<A,B>(myLeftType, myRightType);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -28,4 +30,9 @@ public class DateAndListParam extends BaseAndListParam<DateOrListParam> {
|
|||
return new DateOrListParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamTypeEnum getSearchParamType() {
|
||||
return SearchParamTypeEnum.DATE;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -154,7 +154,7 @@ public class DateParam extends DateTimeDt implements IQueryParameterType, IQuery
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
myBase.setMissing(null);
|
||||
myComparator = null;
|
||||
setValueAsString(null);
|
||||
|
@ -164,6 +164,7 @@ public class DateParam extends DateTimeDt implements IQueryParameterType, IQuery
|
|||
} else if (theParameters.size() > 1) {
|
||||
throw new InvalidRequestException("This server does not support multi-valued dates for this paramater: " + theParameters);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -59,7 +59,7 @@ public class IdentifierListParam implements IQueryParameterOr<IQueryParameterTyp
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
public void setValuesAsQueryTokens(QualifiedParamList theParameters) {
|
||||
for (String string : theParameters) {
|
||||
IdentifierDt dt = new IdentifierDt();
|
||||
dt.setValueAsQueryToken(null, string);
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -27,5 +29,10 @@ public class NumberAndListParam extends BaseAndListParam<NumberOrListParam> {
|
|||
NumberOrListParam newInstance() {
|
||||
return new NumberOrListParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamTypeEnum getSearchParamType() {
|
||||
return SearchParamTypeEnum.NUMBER;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -28,4 +30,9 @@ public class QuantityAndListParam extends BaseAndListParam<QuantityOrListParam>
|
|||
return new QuantityOrListParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamTypeEnum getSearchParamType() {
|
||||
return SearchParamTypeEnum.QUANTITY;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -28,4 +30,10 @@ public class ReferenceAndListParam extends BaseAndListParam<ReferenceOrListParam
|
|||
return new ReferenceOrListParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamTypeEnum getSearchParamType() {
|
||||
return SearchParamTypeEnum.REFERENCE;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -28,4 +30,9 @@ public class StringAndListParam extends BaseAndListParam<StringOrListParam> {
|
|||
return new StringOrListParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamTypeEnum getSearchParamType() {
|
||||
return SearchParamTypeEnum.STRING;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.rest.param;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR - Core Library
|
||||
|
@ -28,4 +30,10 @@ public class TokenAndListParam extends BaseAndListParam<TokenOrListParam> {
|
|||
return new TokenOrListParam();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SearchParamTypeEnum getSearchParamType() {
|
||||
return SearchParamTypeEnum.TOKEN;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
|
@ -30,16 +31,11 @@ public class HardcodedServerAddressStrategy implements IServerAddressStrategy {
|
|||
private String myValue;
|
||||
|
||||
public HardcodedServerAddressStrategy() {
|
||||
//nothing
|
||||
}
|
||||
|
||||
public HardcodedServerAddressStrategy(String theValue) {
|
||||
myValue=theValue;
|
||||
// nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public String determineServerBase(HttpServletRequest theRequest) {
|
||||
return myValue;
|
||||
public HardcodedServerAddressStrategy(String theValue) {
|
||||
myValue = theValue;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
|
@ -50,4 +46,9 @@ public class HardcodedServerAddressStrategy implements IServerAddressStrategy {
|
|||
myValue = theValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
||||
return myValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
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 java.util.List;
|
||||
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
|
||||
/**
|
||||
* This is still an experimental API - It isn't meant for public consumption yet. Get in touch if you'd like to use it
|
||||
* and maybe we can help work out a good design together.
|
||||
*/
|
||||
public interface IDynamicSearchResourceProvider extends IResourceProvider {
|
||||
|
||||
List<RuntimeSearchParam> getSearchParameters();
|
||||
|
||||
}
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
|
@ -31,6 +32,6 @@ public interface IServerAddressStrategy {
|
|||
/**
|
||||
* Determine the server base for a given request
|
||||
*/
|
||||
public String determineServerBase(HttpServletRequest theRequest);
|
||||
String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest);
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -30,13 +31,13 @@ import org.apache.commons.lang3.StringUtils;
|
|||
public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
||||
|
||||
@Override
|
||||
public String determineServerBase(HttpServletRequest theRequest) {
|
||||
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
|
||||
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
|
||||
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
|
||||
StringBuffer requestUrl = theRequest.getRequestURL();
|
||||
String servletContextPath = "";
|
||||
if (theRequest.getServletContext() != null) {
|
||||
servletContextPath = StringUtils.defaultString(theRequest.getServletContext().getContextPath());
|
||||
if (theServletContext != null) {
|
||||
servletContextPath = StringUtils.defaultString(theServletContext.getContextPath());
|
||||
// } else {
|
||||
// servletContextPath = servletPath;
|
||||
}
|
||||
|
@ -46,15 +47,23 @@ public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
|
|||
requestPath = requestPath.substring(1);
|
||||
}
|
||||
|
||||
int startOfPath = requestUrl.indexOf("//");
|
||||
if (startOfPath != -1 && (startOfPath + 2) < requestUrl.length()) {
|
||||
startOfPath = requestUrl.indexOf("/", startOfPath + 2);
|
||||
}
|
||||
if (startOfPath == -1) {
|
||||
startOfPath = 0;
|
||||
}
|
||||
|
||||
int contextIndex;
|
||||
if (servletPath.length() == 0) {
|
||||
if (requestPath.length() == 0) {
|
||||
contextIndex = requestUrl.length();
|
||||
} else {
|
||||
contextIndex = requestUrl.indexOf(requestPath);
|
||||
contextIndex = requestUrl.indexOf(requestPath, startOfPath);
|
||||
}
|
||||
} else {
|
||||
contextIndex = requestUrl.indexOf(servletPath);
|
||||
contextIndex = requestUrl.indexOf(servletPath, startOfPath);
|
||||
}
|
||||
|
||||
String fhirServerBase;
|
||||
|
|
|
@ -454,12 +454,14 @@ public class RestfulServer extends HttpServlet {
|
|||
String servletPath = StringUtils.defaultString(theRequest.getServletPath());
|
||||
StringBuffer requestUrl = theRequest.getRequestURL();
|
||||
String servletContextPath = "";
|
||||
if (theRequest.getServletContext() != null) {
|
||||
servletContextPath = StringUtils.defaultString(theRequest.getServletContext().getContextPath());
|
||||
// } else {
|
||||
// servletContextPath = servletPath;
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
@ -476,7 +478,7 @@ public class RestfulServer extends HttpServlet {
|
|||
requestPath = requestPath.substring(1);
|
||||
}
|
||||
|
||||
fhirServerBase = myServerAddressStrategy.determineServerBase(theRequest);
|
||||
fhirServerBase = myServerAddressStrategy.determineServerBase(getServletContext(), theRequest);
|
||||
|
||||
if (fhirServerBase.endsWith("/")) {
|
||||
fhirServerBase = fhirServerBase.substring(0, fhirServerBase.length() - 1);
|
||||
|
@ -951,6 +953,8 @@ public class RestfulServer extends HttpServlet {
|
|||
if (theServer.getPagingProvider() == null) {
|
||||
numToReturn = theResult.size();
|
||||
resourceList = theResult.getResources(0, numToReturn);
|
||||
validateResourceListNotNull(resourceList);
|
||||
|
||||
} else {
|
||||
IPagingProvider pagingProvider = theServer.getPagingProvider();
|
||||
if (theLimit == null) {
|
||||
|
@ -961,6 +965,7 @@ public class RestfulServer extends HttpServlet {
|
|||
|
||||
numToReturn = Math.min(numToReturn, theResult.size() - theOffset);
|
||||
resourceList = theResult.getResources(theOffset, numToReturn + theOffset);
|
||||
validateResourceListNotNull(resourceList);
|
||||
|
||||
if (theSearchId != null) {
|
||||
searchId = theSearchId;
|
||||
|
@ -1012,6 +1017,12 @@ public class RestfulServer extends HttpServlet {
|
|||
return bundle;
|
||||
}
|
||||
|
||||
private static void validateResourceListNotNull(List<IResource> theResourceList) {
|
||||
if (theResourceList == null) {
|
||||
throw new InternalErrorException("IBundleProvider returned a null list of resources - This is not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
public static Bundle createBundleFromResourceList(FhirContext theContext, String theAuthor, List<IResource> theResult, String theServerBase, String theCompleteUrl, int theTotalResults) {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.getAuthorName().setValue(theAuthor);
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
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 java.util.LinkedHashMap;
|
||||
|
||||
import ca.uhn.fhir.model.api.IQueryParameterType;
|
||||
import ca.uhn.fhir.rest.param.BaseAndListParam;
|
||||
import ca.uhn.fhir.rest.param.CompositeAndListParam;
|
||||
import ca.uhn.fhir.rest.param.CompositeOrListParam;
|
||||
import ca.uhn.fhir.rest.param.DateAndListParam;
|
||||
import ca.uhn.fhir.rest.param.DateOrListParam;
|
||||
import ca.uhn.fhir.rest.param.NumberAndListParam;
|
||||
import ca.uhn.fhir.rest.param.NumberOrListParam;
|
||||
import ca.uhn.fhir.rest.param.QuantityAndListParam;
|
||||
import ca.uhn.fhir.rest.param.QuantityOrListParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceAndListParam;
|
||||
import ca.uhn.fhir.rest.param.ReferenceOrListParam;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenAndListParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
|
||||
public class SearchParameterMap extends LinkedHashMap<String, BaseAndListParam<?>> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public <A extends IQueryParameterType, B extends IQueryParameterType> void add(String theName, CompositeOrListParam<A, B> theCompositeOrListParam) {
|
||||
@SuppressWarnings("unchecked")
|
||||
CompositeAndListParam<A, B> andList = (CompositeAndListParam<A, B>) get(theName);
|
||||
if (andList == null) {
|
||||
andList = new CompositeAndListParam<A, B>(theCompositeOrListParam.getLeftType(), theCompositeOrListParam.getRightType());
|
||||
put(theName, andList);
|
||||
}
|
||||
andList.addValue(theCompositeOrListParam);
|
||||
}
|
||||
|
||||
public void add(String theName, DateOrListParam theOrListParam) {
|
||||
DateAndListParam andList = (DateAndListParam) get(theName);
|
||||
if (andList == null) {
|
||||
andList = new DateAndListParam();
|
||||
put(theName, andList);
|
||||
}
|
||||
andList.addValue(theOrListParam);
|
||||
}
|
||||
|
||||
public void add(String theName, NumberOrListParam theOrListParam) {
|
||||
NumberAndListParam andList = (NumberAndListParam) get(theName);
|
||||
if (andList == null) {
|
||||
andList = new NumberAndListParam();
|
||||
put(theName, andList);
|
||||
}
|
||||
andList.addValue(theOrListParam);
|
||||
}
|
||||
|
||||
public void add(String theName, TokenOrListParam theOrListParam) {
|
||||
TokenAndListParam andList = (TokenAndListParam) get(theName);
|
||||
if (andList == null) {
|
||||
andList = new TokenAndListParam();
|
||||
put(theName, andList);
|
||||
}
|
||||
andList.addValue(theOrListParam);
|
||||
}
|
||||
|
||||
public void add(String theName, StringOrListParam theOrListParam) {
|
||||
StringAndListParam andList = (StringAndListParam) get(theName);
|
||||
if (andList == null) {
|
||||
andList = new StringAndListParam();
|
||||
put(theName, andList);
|
||||
}
|
||||
andList.addValue(theOrListParam);
|
||||
}
|
||||
|
||||
public void add(String theName, QuantityOrListParam theOrListParam) {
|
||||
QuantityAndListParam andList = (QuantityAndListParam) get(theName);
|
||||
if (andList == null) {
|
||||
andList = new QuantityAndListParam();
|
||||
put(theName, andList);
|
||||
}
|
||||
andList.addValue(theOrListParam);
|
||||
}
|
||||
|
||||
public void add(String theName, ReferenceOrListParam theOrListParam) {
|
||||
ReferenceAndListParam andList = (ReferenceAndListParam) get(theName);
|
||||
if (andList == null) {
|
||||
andList = new ReferenceAndListParam();
|
||||
put(theName, andList);
|
||||
}
|
||||
andList.addValue(theOrListParam);
|
||||
}
|
||||
|
||||
// public void add(String theName, IQueryParameterOr<?> theOr) {
|
||||
// if (theOr == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// switch (theOr.getClass()) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if (!containsKey(theName)) {
|
||||
// put(theName, new ArrayList<List<? extends IQueryParameterType>>());
|
||||
// }
|
||||
//
|
||||
// StringAndListParam
|
||||
//
|
||||
// IQueryParameterAnd<IQueryParameterOr<?>> and = get(theName);
|
||||
// and.add(theOr);
|
||||
// }
|
||||
|
||||
}
|
|
@ -49,6 +49,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.Metadata;
|
||||
import ca.uhn.fhir.rest.method.BaseMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.DynamicSearchMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.IParameter;
|
||||
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.SearchParameter;
|
||||
|
@ -61,11 +62,10 @@ import ca.uhn.fhir.util.ExtensionConstants;
|
|||
* Server FHIR Provider which serves the conformance statement for a RESTful server implementation
|
||||
*
|
||||
* <p>
|
||||
* Note: This class is safe to extend, but it is important to note that the same instance of
|
||||
* {@link Conformance} is always returned unless {@link #setCache(boolean)} is called with a value
|
||||
* of <code>false</code>. This means that if you are adding anything to the returned
|
||||
* conformance instance on each call you should call <code>setCache(false)</code> in
|
||||
* your provider constructor.
|
||||
* Note: This class is safe to extend, but it is important to note that the same instance of {@link Conformance} is
|
||||
* always returned unless {@link #setCache(boolean)} is called with a value of <code>false</code>. This means that if
|
||||
* you are adding anything to the returned conformance instance on each call you should call
|
||||
* <code>setCache(false)</code> in your provider constructor.
|
||||
* </p>
|
||||
*/
|
||||
public class ServerConformanceProvider {
|
||||
|
@ -142,91 +142,9 @@ public class ServerConformanceProvider {
|
|||
}
|
||||
|
||||
if (nextMethodBinding instanceof SearchMethodBinding) {
|
||||
SearchMethodBinding searchMethodBinding = (SearchMethodBinding) nextMethodBinding;
|
||||
includes.addAll(searchMethodBinding.getIncludes());
|
||||
|
||||
List<IParameter> params = searchMethodBinding.getParameters();
|
||||
List<SearchParameter> searchParameters = new ArrayList<SearchParameter>();
|
||||
for (IParameter nextParameter : params) {
|
||||
if ((nextParameter instanceof SearchParameter)) {
|
||||
searchParameters.add((SearchParameter) nextParameter);
|
||||
}
|
||||
}
|
||||
Collections.sort(searchParameters, new Comparator<SearchParameter>() {
|
||||
@Override
|
||||
public int compare(SearchParameter theO1, SearchParameter theO2) {
|
||||
if (theO1.isRequired() == theO2.isRequired()) {
|
||||
return theO1.getName().compareTo(theO2.getName());
|
||||
}
|
||||
if (theO1.isRequired()) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
if (searchParameters.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
boolean allOptional = searchParameters.get(0).isRequired() == false;
|
||||
|
||||
RestQuery query = null;
|
||||
if (!allOptional) {
|
||||
query = rest.addQuery();
|
||||
query.getDocumentation().setValue(searchMethodBinding.getDescription());
|
||||
query.addUndeclaredExtension(false, ExtensionConstants.QUERY_RETURN_TYPE, new CodeDt(resourceName));
|
||||
for (String nextInclude : searchMethodBinding.getIncludes()) {
|
||||
query.addUndeclaredExtension(false, ExtensionConstants.QUERY_ALLOWED_INCLUDE, new StringDt(nextInclude));
|
||||
}
|
||||
}
|
||||
|
||||
for (SearchParameter nextParameter : searchParameters) {
|
||||
|
||||
String nextParamName = nextParameter.getName();
|
||||
|
||||
// String chain = null;
|
||||
String nextParamUnchainedName = nextParamName;
|
||||
if (nextParamName.contains(".")) {
|
||||
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
|
||||
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
|
||||
}
|
||||
|
||||
String nextParamDescription = nextParameter.getDescription();
|
||||
|
||||
/*
|
||||
* If the parameter has no description, default to the one from the resource
|
||||
*/
|
||||
if (StringUtils.isBlank(nextParamDescription)) {
|
||||
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
|
||||
if (paramDef != null) {
|
||||
nextParamDescription = paramDef.getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
RestResourceSearchParam param;
|
||||
if (query == null) {
|
||||
param = resource.addSearchParam();
|
||||
} else {
|
||||
param = query.addParameter();
|
||||
param.addUndeclaredExtension(false, ExtensionConstants.PARAM_IS_REQUIRED, new BooleanDt(nextParameter.isRequired()));
|
||||
}
|
||||
|
||||
param.setName(nextParamName);
|
||||
// if (StringUtils.isNotBlank(chain)) {
|
||||
// param.addChain(chain);
|
||||
// }
|
||||
param.setDocumentation(nextParamDescription);
|
||||
param.setType(nextParameter.getParamType());
|
||||
for (Class<? extends IResource> nextTarget : nextParameter.getDeclaredTypes()) {
|
||||
RuntimeResourceDefinition targetDef = myRestfulServer.getFhirContext().getResourceDefinition(nextTarget);
|
||||
if (targetDef != null) {
|
||||
ResourceTypeEnum code = ResourceTypeEnum.VALUESET_BINDER.fromCodeString(targetDef.getName());
|
||||
if (code != null) {
|
||||
param.addTarget(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
|
||||
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
|
||||
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
|
||||
}
|
||||
|
||||
Collections.sort(resource.getOperation(), new Comparator<RestResourceOperation>() {
|
||||
|
@ -259,6 +177,149 @@ public class ServerConformanceProvider {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
private void handleSearchMethodBinding(Rest rest, RestResource resource, String resourceName, RuntimeResourceDefinition def, TreeSet<String> includes, SearchMethodBinding searchMethodBinding) {
|
||||
includes.addAll(searchMethodBinding.getIncludes());
|
||||
|
||||
List<IParameter> params = searchMethodBinding.getParameters();
|
||||
List<SearchParameter> searchParameters = new ArrayList<SearchParameter>();
|
||||
for (IParameter nextParameter : params) {
|
||||
if ((nextParameter instanceof SearchParameter)) {
|
||||
searchParameters.add((SearchParameter) nextParameter);
|
||||
}
|
||||
}
|
||||
sortSearchParameters(searchParameters);
|
||||
if (!searchParameters.isEmpty()) {
|
||||
boolean allOptional = searchParameters.get(0).isRequired() == false;
|
||||
|
||||
RestQuery query = null;
|
||||
if (!allOptional) {
|
||||
query = rest.addQuery();
|
||||
query.getDocumentation().setValue(searchMethodBinding.getDescription());
|
||||
query.addUndeclaredExtension(false, ExtensionConstants.QUERY_RETURN_TYPE, new CodeDt(resourceName));
|
||||
for (String nextInclude : searchMethodBinding.getIncludes()) {
|
||||
query.addUndeclaredExtension(false, ExtensionConstants.QUERY_ALLOWED_INCLUDE, new StringDt(nextInclude));
|
||||
}
|
||||
}
|
||||
|
||||
for (SearchParameter nextParameter : searchParameters) {
|
||||
|
||||
String nextParamName = nextParameter.getName();
|
||||
|
||||
// String chain = null;
|
||||
String nextParamUnchainedName = nextParamName;
|
||||
if (nextParamName.contains(".")) {
|
||||
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
|
||||
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
|
||||
}
|
||||
|
||||
String nextParamDescription = nextParameter.getDescription();
|
||||
|
||||
/*
|
||||
* If the parameter has no description, default to the one from the resource
|
||||
*/
|
||||
if (StringUtils.isBlank(nextParamDescription)) {
|
||||
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
|
||||
if (paramDef != null) {
|
||||
nextParamDescription = paramDef.getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
RestResourceSearchParam param;
|
||||
if (query == null) {
|
||||
param = resource.addSearchParam();
|
||||
} else {
|
||||
param = query.addParameter();
|
||||
param.addUndeclaredExtension(false, ExtensionConstants.PARAM_IS_REQUIRED, new BooleanDt(nextParameter.isRequired()));
|
||||
}
|
||||
|
||||
param.setName(nextParamName);
|
||||
// if (StringUtils.isNotBlank(chain)) {
|
||||
// param.addChain(chain);
|
||||
// }
|
||||
param.setDocumentation(nextParamDescription);
|
||||
param.setType(nextParameter.getParamType());
|
||||
for (Class<? extends IResource> nextTarget : nextParameter.getDeclaredTypes()) {
|
||||
RuntimeResourceDefinition targetDef = myRestfulServer.getFhirContext().getResourceDefinition(nextTarget);
|
||||
if (targetDef != null) {
|
||||
ResourceTypeEnum code = ResourceTypeEnum.VALUESET_BINDER.fromCodeString(targetDef.getName());
|
||||
if (code != null) {
|
||||
param.addTarget(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDynamicSearchMethodBinding(RestResource resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
|
||||
includes.addAll(searchMethodBinding.getIncludes());
|
||||
|
||||
List<RuntimeSearchParam> searchParameters = new ArrayList<RuntimeSearchParam>();
|
||||
searchParameters.addAll(searchMethodBinding.getSearchParams());
|
||||
sortRuntimeSearchParameters(searchParameters);
|
||||
|
||||
if (!searchParameters.isEmpty()) {
|
||||
|
||||
for (RuntimeSearchParam nextParameter : searchParameters) {
|
||||
|
||||
String nextParamName = nextParameter.getName();
|
||||
|
||||
// String chain = null;
|
||||
String nextParamUnchainedName = nextParamName;
|
||||
if (nextParamName.contains(".")) {
|
||||
// chain = nextParamName.substring(nextParamName.indexOf('.') + 1);
|
||||
nextParamUnchainedName = nextParamName.substring(0, nextParamName.indexOf('.'));
|
||||
}
|
||||
|
||||
String nextParamDescription = nextParameter.getDescription();
|
||||
|
||||
/*
|
||||
* If the parameter has no description, default to the one from the resource
|
||||
*/
|
||||
if (StringUtils.isBlank(nextParamDescription)) {
|
||||
RuntimeSearchParam paramDef = def.getSearchParam(nextParamUnchainedName);
|
||||
if (paramDef != null) {
|
||||
nextParamDescription = paramDef.getDescription();
|
||||
}
|
||||
}
|
||||
|
||||
RestResourceSearchParam param;
|
||||
param = resource.addSearchParam();
|
||||
|
||||
param.setName(nextParamName);
|
||||
// if (StringUtils.isNotBlank(chain)) {
|
||||
// param.addChain(chain);
|
||||
// }
|
||||
param.setDocumentation(nextParamDescription);
|
||||
param.setType(nextParameter.getParamType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sortRuntimeSearchParameters(List<RuntimeSearchParam> searchParameters) {
|
||||
Collections.sort(searchParameters, new Comparator<RuntimeSearchParam>() {
|
||||
@Override
|
||||
public int compare(RuntimeSearchParam theO1, RuntimeSearchParam theO2) {
|
||||
return theO1.getName().compareTo(theO2.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void sortSearchParameters(List<SearchParameter> searchParameters) {
|
||||
Collections.sort(searchParameters, new Comparator<SearchParameter>() {
|
||||
@Override
|
||||
public int compare(SearchParameter theO1, SearchParameter theO2) {
|
||||
if (theO1.isRequired() == theO2.isRequired()) {
|
||||
return theO1.getName().compareTo(theO2.getName());
|
||||
}
|
||||
if (theO1.isRequired()) {
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache property (default is true). If set to true, the same response will be returned for each
|
||||
* invocation.
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package ca.uhn.fhir.util;
|
||||
|
||||
/*
|
||||
* #%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 java.net.ServerSocket;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Provides server ports
|
||||
*/
|
||||
public class PortUtil {
|
||||
|
||||
private static List<Integer> ourPorts = new ArrayList<Integer>();
|
||||
|
||||
/**
|
||||
* This is really only used for unit tests but is included in the library so it can be reused across modules. Use with caution.
|
||||
*/
|
||||
public static int findFreePort() {
|
||||
ServerSocket server;
|
||||
try {
|
||||
server = new ServerSocket(0);
|
||||
int port = server.getLocalPort();
|
||||
ourPorts.add(port);
|
||||
server.close();
|
||||
Thread.sleep(500);
|
||||
return port;
|
||||
} catch (IOException e) {
|
||||
throw new Error(e);
|
||||
} catch (InterruptedException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static List<Integer> list() {
|
||||
return ourPorts;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -26,14 +26,15 @@ import java.util.List;
|
|||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import com.phloc.schematron.ISchematronResource;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
|
||||
/**
|
||||
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons,
|
||||
* etc.)
|
||||
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, etc.)
|
||||
*
|
||||
* <p>
|
||||
* To obtain a resource validator, call {@link FhirContext#newValidator()}
|
||||
|
@ -43,17 +44,33 @@ public class FhirValidator {
|
|||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirValidator.class);
|
||||
|
||||
private static final String I18N_KEY_NO_PHLOC_WARNING = FhirValidator.class.getName()+".noPhlocWarningOnStartup";
|
||||
private static final String I18N_KEY_NO_PHLOC_ERROR = FhirValidator.class.getName()+".noPhlocError";
|
||||
|
||||
private FhirContext myContext;
|
||||
private List<IValidator> myValidators = new ArrayList<IValidator>();
|
||||
private static volatile Boolean ourPhlocPresentOnClasspath;
|
||||
|
||||
/**
|
||||
* Constructor (this should not be called directly, but rather {@link FhirContext#newValidator()} should be called
|
||||
* to obtain an instance of {@link FhirValidator})
|
||||
* Constructor (this should not be called directly, but rather {@link FhirContext#newValidator()} should be called to obtain an instance of {@link FhirValidator})
|
||||
*/
|
||||
public FhirValidator(FhirContext theFhirContext) {
|
||||
myContext = theFhirContext;
|
||||
setValidateAgainstStandardSchema(true);
|
||||
setValidateAgainstStandardSchematron(true);
|
||||
|
||||
if (ourPhlocPresentOnClasspath == null) {
|
||||
try {
|
||||
Class.forName("com.phloc.schematron.ISchematronResource");
|
||||
ourPhlocPresentOnClasspath = true;
|
||||
} catch (ClassNotFoundException e) {
|
||||
ourLog.info(theFhirContext.getLocalizer().getMessage(I18N_KEY_NO_PHLOC_WARNING));
|
||||
ourPhlocPresentOnClasspath = false;
|
||||
}
|
||||
}
|
||||
if (ourPhlocPresentOnClasspath) {
|
||||
setValidateAgainstStandardSchematron(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void addOrRemoveValidator(boolean theValidateAgainstStandardSchema, Class<? extends IValidator> type, IValidator instance) {
|
||||
|
@ -83,43 +100,43 @@ public class FhirValidator {
|
|||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
|
||||
* distribution itself)
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
|
||||
*/
|
||||
public boolean isValidateAgainstStandardSchema() {
|
||||
return haveValidatorOfType(SchemaBaseValidator.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
|
||||
* distribution itself)
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
|
||||
*/
|
||||
public boolean isValidateAgainstStandardSchematron() {
|
||||
return haveValidatorOfType(SchematronBaseValidator.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR
|
||||
* distribution itself)
|
||||
* Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
|
||||
*/
|
||||
public void setValidateAgainstStandardSchema(boolean theValidateAgainstStandardSchema) {
|
||||
addOrRemoveValidator(theValidateAgainstStandardSchema, SchemaBaseValidator.class, new SchemaBaseValidator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Should the validator validate the resource against the base schematron (the schematron provided with the FHIR
|
||||
* distribution itself)
|
||||
* Should the validator validate the resource against the base schematron (the schematron provided with the FHIR distribution itself)
|
||||
*/
|
||||
public void setValidateAgainstStandardSchematron(boolean theValidateAgainstStandardSchematron) {
|
||||
if (theValidateAgainstStandardSchematron && !ourPhlocPresentOnClasspath) {
|
||||
throw new IllegalArgumentException(myContext.getLocalizer().getMessage(I18N_KEY_NO_PHLOC_ERROR));
|
||||
}
|
||||
addOrRemoveValidator(theValidateAgainstStandardSchematron, SchematronBaseValidator.class, new SchematronBaseValidator());
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a bundle instance, throwing a {@link ValidationFailureException} if the validation fails. This
|
||||
* validation includes validation of all resources in the bundle.
|
||||
* Validates a bundle instance, throwing a {@link ValidationFailureException} if the validation fails. This validation includes validation of all resources in the bundle.
|
||||
*
|
||||
* @param theResource The resource to validate
|
||||
* @throws ValidationFailureException If the validation fails
|
||||
* @param theResource
|
||||
* The resource to validate
|
||||
* @throws ValidationFailureException
|
||||
* If the validation fails
|
||||
*/
|
||||
public void validate(Bundle theBundle) {
|
||||
Validate.notNull(theBundle, "theBundle must not be null");
|
||||
|
@ -140,8 +157,10 @@ public class FhirValidator {
|
|||
/**
|
||||
* Validates a resource instance, throwing a {@link ValidationFailureException} if the validation fails
|
||||
*
|
||||
* @param theResource The resource to validate
|
||||
* @throws ValidationFailureException If the validation fails
|
||||
* @param theResource
|
||||
* The resource to validate
|
||||
* @throws ValidationFailureException
|
||||
* If the validation fails
|
||||
*/
|
||||
public void validate(IResource theResource) throws ValidationFailureException {
|
||||
Validate.notNull(theResource, "theResource must not be null");
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
|
||||
ca.uhn.fhir.rest.method.SearchMethodBinding.invalidSpecialParamName=Method [{0}] in provider [{1}] contains search parameter annotated to use name [{2}] - This name is reserved according to the FHIR specification and can not be used as a search parameter name.
|
||||
ca.uhn.fhir.rest.method.SearchMethodBinding.idWithoutCompartment=Method [{0}] in provider [{1}] has an @IdParam parameter. This is only allowable for compartment search (e.g. @Search(compartment="foo") )
|
||||
ca.uhn.fhir.rest.method.SearchMethodBinding.idNullForCompartmentSearch=ID parameter can not be null or empty for compartment search
|
||||
ca.uhn.fhir.rest.method.SearchMethodBinding.idNullForCompartmentSearch=ID parameter can not be null or empty for compartment search
|
||||
|
||||
ca.uhn.fhir.validation.FhirValidator.noPhlocWarningOnStartup=Phloc-schematron library not found on classpath, will not attempt to perform schematron validation
|
||||
ca.uhn.fhir.validation.FhirValidator.noPhlocError=Phloc-schematron library not found on classpath, can not enable perform schematron validation
|
||||
|
|
|
@ -86,12 +86,12 @@
|
|||
}
|
||||
|
||||
tt {
|
||||
margin-left: 10px;
|
||||
white-space: pre;
|
||||
color: #448;
|
||||
padding: 4px;
|
||||
margin-bottom: 5px;
|
||||
margin-top: 10px;
|
||||
padding: 2px;
|
||||
border: 1px solid #AAA;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5 {
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -4,18 +4,18 @@
|
|||
<bannerLeft>
|
||||
<name>HAPI</name>
|
||||
<src>images/hapi_fhir_banner.png</src>
|
||||
<href>http://hl7api.sourceforge.net/hapi-fhir/</href>
|
||||
<href>http://jamesagnew.github.io/hapi-fhir/</href>
|
||||
</bannerLeft>
|
||||
|
||||
<bannerRight>
|
||||
<name>FHIR</name>
|
||||
<src>images/hapi_fhir_banner_right.png</src>
|
||||
<href>http://hl7api.sourceforge.net/hapi-fhir/</href>
|
||||
<href>http://jamesagnew.github.io/hapi-fhir/</href>
|
||||
</bannerRight>
|
||||
|
||||
<poweredBy>
|
||||
<logo name="Hosted on SourceForge.net" href="https://sourceforge.net/projects/hl7api/" img="http://sflogo.sourceforge.net/sflogo.php?group_id=38899&type=2" />
|
||||
<logo name="Built with Maven 2" href="http://maven.apache.org" img="images/logos/maven-feather.png" />
|
||||
<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" />
|
||||
|
|
|
@ -103,7 +103,24 @@
|
|||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="Examples">
|
||||
|
||||
<subsection name="Populating an Observation Resource">
|
||||
|
||||
<p>
|
||||
The following example shows how to create an observation resource containing
|
||||
a numeric datatype.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="observation" />
|
||||
<param name="file" value="examples/src/main/java/example/FhirDataModel.java" />
|
||||
</macro>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
||||
</document>
|
||||
|
|
|
@ -108,6 +108,16 @@
|
|||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
<section name="Server Request Logging">
|
||||
|
||||
<p>
|
||||
To enable detailed logging of server requests and responses,
|
||||
an interceptor may be added to the server which logs each transaction. See
|
||||
<a href="./doc_rest_server_interceptor.html#Logging">Logging Server Requests</a> for more information.
|
||||
</p>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
||||
|
|
|
@ -110,6 +110,21 @@
|
|||
of detail about each incoming request.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following example shows how to register a logging interceptor within
|
||||
a FHIR RESTful server.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="loggingInterceptor" />
|
||||
<param name="file" value="examples/src/main/java/example/ServletExamples.java" />
|
||||
</macro>
|
||||
|
||||
<p>
|
||||
This interceptor will then produce output similar to the following:
|
||||
</p>
|
||||
<source><![CDATA[2014-09-04 02:37:30.030 Source[127.0.0.1] Operation[vread Patient/1667/_history/1] UA[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.94 Safari/537.36] Params[?_format=json]
|
||||
2014-09-04 03:30:00.443 Source[127.0.0.1] Operation[search-type Organization] UA[Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)] Params[]]]></source>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
<p>
|
||||
HAPI provides a built-in and configurable mechanism for validating resources.
|
||||
This mechanism is called the <i>Resource Validator</i>.
|
||||
This mechanism is called the <i>FHIR Validator</i>.
|
||||
</p>
|
||||
|
||||
<subsection name="Background">
|
||||
|
||||
<p>
|
||||
FHIR resource definitions are distributed with a set of XML schema files (XDS)
|
||||
FHIR resource definitions are distributed with a set of XML schema files (XSD)
|
||||
as well as a set of XML Schematron (SCH) files. These two sets of files are
|
||||
complimentary to each other, meaning that in order to claim compliance to the
|
||||
FHIR specification, your resources must validate against both sets.
|
||||
|
@ -60,6 +60,19 @@
|
|||
|
||||
</subsection>
|
||||
|
||||
<subsection name="Validating a Set of Files">
|
||||
|
||||
<p>
|
||||
The following example shows how to load a set of resources from files
|
||||
on disk and validate each one.
|
||||
</p>
|
||||
<macro name="snippet">
|
||||
<param name="id" value="validateFiles" />
|
||||
<param name="file" value="examples/src/main/java/example/ValidatorExamples.java" />
|
||||
</macro>
|
||||
|
||||
</subsection>
|
||||
|
||||
</section>
|
||||
|
||||
</body>
|
||||
|
|
|
@ -39,6 +39,14 @@
|
|||
|
||||
<section name="Announcements">
|
||||
|
||||
<p>
|
||||
<b>Sep 8, 2014 - HAPI FHIR 0.6 Released</b> - A new build has been uploaded,
|
||||
containing a number of new features and bug fixes. See the changelog
|
||||
for a complete list of what has changed.
|
||||
<br/>
|
||||
- <a href="mailto:jamesagnew@users.sourceforge.net">James Agnew</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<b>July 30, 2014 - HAPI FHIR 0.5 Released</b> - HAPI 0.5 has now been released.
|
||||
This is surprisingly soon after the last release (and probably not a
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
package ca.uhn.fhir.model.primitive;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class XhtmlDtTest {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XhtmlDtTest.class);
|
||||
|
||||
@Test
|
||||
public void testRoundtripTiny() {
|
||||
String div = "<div>xmlns="http://hl7.org/fhir"</div>";
|
||||
|
||||
XhtmlDt x = new XhtmlDt();
|
||||
x.setValueAsString(div);
|
||||
|
||||
String actual = x.getValueAsString();
|
||||
|
||||
ourLog.info("Expected {}", div.replace("\r", "").replace("\n", "\\n"));
|
||||
ourLog.info("Actual {}", actual.replace("\r\n", "\\r\\n").replace("\n", "\\n"));
|
||||
|
||||
assertEquals(div.replace("\r", ""), actual);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRoundtrip() {
|
||||
String div = "<div><pre>\r\n<<a title=\"Prospective warnings of potential issues when providing care to the patient.\" class=\"dict\" href=\"alert-definitions.html#Alert\"><b>Alert</b></a> xmlns="http://hl7.org/fhir"> <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n <!-- from <a href=\"resources.html\">Resource</a>: <a href=\"extensibility.html\">extension</a>, <a href=\"extensibility.html#modifierExtension\">modifierExtension</a>, language, <a href=\"narrative.html#Narrative\">text</a>, and <a href=\"references.html#contained\">contained</a> -->\r\n <<a title=\"Identifier assigned to the alert for external use (outside the FHIR environment).\" class=\"dict\" href=\"alert-definitions.html#Alert.identifier\"><b>identifier</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>0..*</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#Identifier\">Identifier</a></span> <span style=\"color: navy\">Business identifier</span><span style=\"color: Gray\"> --></span></identifier>\r\n <<a title=\"Allows an alert to be divided into different categories like clinical, administrative etc.\" class=\"dict\" href=\"alert-definitions.html#Alert.category\"><b>category</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#CodeableConcept\">CodeableConcept</a></span> <span style=\"color: navy\">Clinical, administrative, etc.</span><span style=\"color: Gray\"> --></span></category>\r\n <<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]"/><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\"><a style=\"color: navy\" href=\"alert-status.html\">active | inactive | entered in error</a></span><span style=\"color: Gray\"> --></span>\r\n <<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"patient.html#Patient\">Patient</a>)</span> <span style=\"color: navy\">Who is alert about?</span><span style=\"color: Gray\"> --></span></subject>\r\n <<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"practitioner.html#Practitioner\">Practitioner</a>|<a href=\"patient.html#Patient\">Patient</a>|<a href=\"device.html#Device\">Device</a>)</span> <span style=\"color: navy\">Alert creator</span><span style=\"color: Gray\"> --></span></author>\r\n <<a title=\"The textual component of the alert to display to the user.\" class=\"dict\" href=\"alert-definitions.html#Alert.note\"><b>note</b></a> value="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]"/><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --></span>\r\n</Alert>\r\n</pre></div>";
|
||||
|
||||
XhtmlDt x = new XhtmlDt();
|
||||
x.setValueAsString(div);
|
||||
|
||||
String actual = x.getValueAsString();
|
||||
|
||||
ourLog.info("Expected {}", div.replace("\r", "").replace("\n", "\\n"));
|
||||
ourLog.info("Actual {}", actual.replace("\r\n", "\\r\\n").replace("\n", "\\n"));
|
||||
|
||||
assertEquals(div.replace("\r", ""), actual);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -86,7 +86,8 @@ public class DefaultThymeleafNarrativeGeneratorTest {
|
|||
enc.setType(EncounterTypeEnum.ANNUAL_DIABETES_MELLITUS_SCREENING);
|
||||
|
||||
String title = gen.generateTitle(enc);
|
||||
assertEquals("1234567 / ADMS / ambulatory / Tue Jan 02 11:11:00 EST 2001 - ?", title);
|
||||
title = title.replaceAll("00 [A-Z]+ 2001", "00 TZ 2001"); // account for whatever time zone
|
||||
assertEquals("1234567 / ADMS / ambulatory / Tue Jan 02 11:11:00 TZ 2001 - ?", title);
|
||||
ourLog.info(title);
|
||||
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
|||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile;
|
||||
import ca.uhn.fhir.model.dstu.resource.Query;
|
||||
import ca.uhn.fhir.model.dstu.resource.Specimen;
|
||||
import ca.uhn.fhir.model.dstu.resource.ValueSet;
|
||||
|
@ -442,6 +443,31 @@ public class JsonParserTest {
|
|||
ourLog.info(encoded);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseJsonProfile() throws IOException {
|
||||
|
||||
String msg = IOUtils.toString(XmlParser.class.getResourceAsStream("/alert.profile.json"));
|
||||
ourLog.info(msg);
|
||||
|
||||
IParser p = ourCtx.newJsonParser();
|
||||
Profile res = p.parseResource(Profile.class, msg);
|
||||
|
||||
String encoded = ourCtx.newJsonParser().setPrettyPrint(true).encodeResourceToString(res);
|
||||
ourLog.info(encoded);
|
||||
|
||||
JSON expected = JSONSerializer.toJSON(msg.trim());
|
||||
JSON actual = JSONSerializer.toJSON(encoded.trim());
|
||||
|
||||
String exp = expected.toString().replace("\\r\\n", "\\n");
|
||||
String act = actual.toString().replace("\\r\\n","\\n");
|
||||
|
||||
ourLog.info("Expected: {}", exp);
|
||||
ourLog.info("Actual : {}", act);
|
||||
|
||||
assertEquals(exp, act);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
|
@ -926,9 +952,13 @@ public class JsonParserTest {
|
|||
JSON expected = JSONSerializer.toJSON(jsonString);
|
||||
JSON actual = JSONSerializer.toJSON(encoded.trim());
|
||||
|
||||
ourLog.info("Expected: {}", expected);
|
||||
ourLog.info("Actual : {}", actual);
|
||||
assertEquals(expected.toString(), actual.toString());
|
||||
// The encoded escapes quote marks using XML escaping instead of JSON escaping, which is probably nicer anyhow...
|
||||
String exp = expected.toString().replace("\\\"Jim\\\"", ""Jim"");
|
||||
String act = actual.toString();
|
||||
|
||||
ourLog.info("Expected: {}", exp);
|
||||
ourLog.info("Actual : {}", act);
|
||||
assertEquals(exp, act);
|
||||
|
||||
}
|
||||
|
||||
|
@ -969,9 +999,13 @@ public class JsonParserTest {
|
|||
JSON expected = JSONSerializer.toJSON(jsonString);
|
||||
JSON actual = JSONSerializer.toJSON(encoded.trim());
|
||||
|
||||
ourLog.info("Expected: {}", expected);
|
||||
ourLog.info("Actual : {}", actual);
|
||||
assertEquals(expected.toString(), actual.toString());
|
||||
// The encoded escapes quote marks using XML escaping instead of JSON escaping, which is probably nicer anyhow...
|
||||
String exp = expected.toString().replace("\\\"Jim\\\"", ""Jim"");
|
||||
String act = actual.toString();
|
||||
|
||||
ourLog.info("Expected: {}", exp);
|
||||
ourLog.info("Actual : {}", act);
|
||||
assertEquals(exp, act);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ import ca.uhn.fhir.util.ElementUtil;
|
|||
|
||||
@ResourceDef(name="Patient")
|
||||
public class MyObservationWithExtensions extends Patient {
|
||||
|
||||
|
||||
@Extension(url = "urn:patientext:att", definedLocally = false, isModifier = false)
|
||||
@Child(name = "extAtt", order = 0)
|
||||
private AttachmentDt myExtAtt;
|
||||
|
|
|
@ -45,6 +45,7 @@ import ca.uhn.fhir.model.dstu.resource.ListResource;
|
|||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile;
|
||||
import ca.uhn.fhir.model.dstu.resource.Query;
|
||||
import ca.uhn.fhir.model.dstu.resource.Specimen;
|
||||
import ca.uhn.fhir.model.dstu.resource.ValueSet;
|
||||
|
@ -67,6 +68,16 @@ public class XmlParserTest {
|
|||
private static FhirContext ourCtx;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(XmlParserTest.class);
|
||||
|
||||
@Test
|
||||
public void testEncodeProfile() {
|
||||
|
||||
Profile p = new Profile();
|
||||
p.getStructureFirstRep().getElementFirstRep().getDefinition().getBinding().setReference(new ResourceReferenceDt("ValudSet/123"));
|
||||
|
||||
String encoded = ourCtx.newXmlParser().encodeResourceToString(p);
|
||||
ourLog.info(encoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeBinaryResource() {
|
||||
|
||||
|
@ -909,7 +920,11 @@ public class XmlParserTest {
|
|||
|
||||
ValueSet resource = (ValueSet) entry.getResource();
|
||||
assertEquals("LOINC Codes for Cholesterol", resource.getName().getValue());
|
||||
assertEquals(summaryText.trim(), entry.getSummary().getValueAsString().trim());
|
||||
|
||||
String exp = summaryText.trim();
|
||||
exp = exp.replace("\"LOINC", ""LOINC");
|
||||
exp = exp.replace("terol\"", "terol"");
|
||||
assertEquals(exp, entry.getSummary().getValueAsString().trim());
|
||||
|
||||
TagList tl = (TagList) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
|
||||
assertEquals(1, tl.size());
|
||||
|
|
|
@ -27,7 +27,7 @@ import ca.uhn.fhir.rest.annotation.Search;
|
|||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
public class ClientIntegrationTest {
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class ClientIntegrationTest {
|
|||
|
||||
@Before
|
||||
public void before() {
|
||||
myPort = RandomServerPortProvider.findFreePort();
|
||||
myPort = PortUtil.findFreePort();
|
||||
myServer = new Server(myPort);
|
||||
|
||||
myPatientProvider = new MyPatientResourceProvider();
|
||||
|
|
|
@ -25,7 +25,7 @@ import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
|||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.ResourceBinding;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.classic.spi.LoggingEvent;
|
||||
import ch.qos.logback.core.Appender;
|
||||
|
@ -56,12 +56,12 @@ public class InterceptorTest {
|
|||
Patient patient = client.read(Patient.class, "1");
|
||||
assertFalse(patient.getIdentifierFirstRep().isEmpty());
|
||||
|
||||
int times = 1;
|
||||
if (LoggerFactory.getLogger(ResourceBinding.class).isDebugEnabled()) {
|
||||
times = 3;
|
||||
}
|
||||
// int times = 1;
|
||||
// if (LoggerFactory.getLogger(ResourceBinding.class).isDebugEnabled()) {
|
||||
// times = 3;
|
||||
// }
|
||||
|
||||
verify(mockAppender, times(times)).doAppend(argThat(new ArgumentMatcher<ILoggingEvent>() {
|
||||
verify(mockAppender).doAppend(argThat(new ArgumentMatcher<ILoggingEvent>() {
|
||||
@Override
|
||||
public boolean matches(final Object argument) {
|
||||
return ((LoggingEvent) argument).getFormattedMessage().contains("Content-Type: application/xml+fhir; charset=UTF-8");
|
||||
|
@ -80,7 +80,7 @@ public class InterceptorTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
|
|
@ -35,7 +35,7 @@ import ca.uhn.fhir.rest.annotation.Read;
|
|||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -122,7 +122,7 @@ public class BinaryTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
ResourceProvider patientProvider = new ResourceProvider();
|
||||
|
|
|
@ -32,7 +32,7 @@ import ca.uhn.fhir.rest.param.CompositeOrListParam;
|
|||
import ca.uhn.fhir.rest.param.CompositeParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -100,7 +100,7 @@ public class CompositeParameterTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyObservationResourceProvider patientProvider = new DummyObservationResourceProvider();
|
||||
|
|
|
@ -30,7 +30,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -101,7 +101,7 @@ public class CompressionTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
|
|
@ -30,7 +30,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.rest.server.ResfulServerSelfReferenceTest.DummyPatientResourceProvider;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -42,7 +42,7 @@ public class CorsTest {
|
|||
|
||||
@Test
|
||||
public void testContextWithSpace() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
Server server = new Server(port);
|
||||
|
||||
RestfulServer restServer = new RestfulServer();
|
||||
|
|
|
@ -35,7 +35,7 @@ import ca.uhn.fhir.rest.annotation.ResourceParam;
|
|||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -146,7 +146,7 @@ public class CreateTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
PatientProvider patientProvider = new PatientProvider();
|
||||
|
|
|
@ -30,7 +30,7 @@ import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
|||
import ca.uhn.fhir.rest.annotation.OptionalParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -134,7 +134,7 @@ public class CustomTypeTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -0,0 +1,197 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.*;
|
||||
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.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.SearchParamTypeEnum;
|
||||
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.StringAndListParam;
|
||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public class DynamicSearchTest {
|
||||
|
||||
private static CloseableHttpClient ourClient;
|
||||
private static FhirContext ourCtx = new FhirContext();
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(DynamicSearchTest.class);
|
||||
private static int ourPort;
|
||||
|
||||
private static Server ourServer;
|
||||
|
||||
private static SearchParameterMap ourLastSearchParams;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ourLastSearchParams = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchOneStringParam() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?param1=param1value");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
assertEquals(1, ourLastSearchParams.size());
|
||||
StringAndListParam andList =(StringAndListParam) ourLastSearchParams.get("param1");
|
||||
assertEquals(1,andList.getValuesAsQueryTokens().size());
|
||||
StringOrListParam orList = andList.getValuesAsQueryTokens().get(0);
|
||||
assertEquals(1,orList.getValuesAsQueryTokens().size());
|
||||
StringParam param1 = orList.getValuesAsQueryTokens().get(0);
|
||||
assertEquals("param1value", param1.getValue());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchOneStringParamWithOr() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?param1=param1value,param1value2");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
assertEquals(1, ourLastSearchParams.size());
|
||||
StringAndListParam andList =(StringAndListParam) ourLastSearchParams.get("param1");
|
||||
assertEquals(1,andList.getValuesAsQueryTokens().size());
|
||||
StringOrListParam orList = andList.getValuesAsQueryTokens().get(0);
|
||||
assertEquals(2,orList.getValuesAsQueryTokens().size());
|
||||
StringParam param1 = orList.getValuesAsQueryTokens().get(0);
|
||||
assertEquals("param1value", param1.getValue());
|
||||
StringParam param1b = orList.getValuesAsQueryTokens().get(1);
|
||||
assertEquals("param1value2", param1b.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchOneStringParamWithAnd() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?param1=param1value¶m1=param1value2");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
assertEquals(1, ourLastSearchParams.size());
|
||||
StringAndListParam andList =(StringAndListParam) ourLastSearchParams.get("param1");
|
||||
assertEquals(2,andList.getValuesAsQueryTokens().size());
|
||||
StringOrListParam orList = andList.getValuesAsQueryTokens().get(0);
|
||||
assertEquals(1,orList.getValuesAsQueryTokens().size());
|
||||
StringParam param1 = orList.getValuesAsQueryTokens().get(0);
|
||||
assertEquals("param1value", param1.getValue());
|
||||
|
||||
orList = andList.getValuesAsQueryTokens().get(1);
|
||||
assertEquals(1,orList.getValuesAsQueryTokens().size());
|
||||
StringParam param1b = orList.getValuesAsQueryTokens().get(0);
|
||||
assertEquals("param1value2", param1b.getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConformance() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/metadata?_pretty=true");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Conformance conf = ourCtx.newXmlParser().parseResource(Conformance.class,responseContent);
|
||||
|
||||
ourLog.info(responseContent);
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
}
|
||||
|
||||
@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();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
*/
|
||||
public static class DummyPatientResourceProvider implements IDynamicSearchResourceProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RuntimeSearchParam> getSearchParameters() {
|
||||
ArrayList<RuntimeSearchParam> retVal = new ArrayList<RuntimeSearchParam>();
|
||||
retVal.add(new RuntimeSearchParam("param1", "This is the first parameter", "Patient.param1", SearchParamTypeEnum.STRING));
|
||||
retVal.add(new RuntimeSearchParam("param2", "This is the second parameter", "Patient.param2", SearchParamTypeEnum.DATE));
|
||||
return retVal;
|
||||
}
|
||||
|
||||
@Search(dynamic=true)
|
||||
public List<Patient> search(SearchParameterMap theSearchParams) {
|
||||
ourLastSearchParams = theSearchParams;
|
||||
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.setId("Patient/1");
|
||||
patient.addIdentifier("system", "fooCompartment");
|
||||
retVal.add(patient);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -33,7 +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.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -131,7 +131,7 @@ public class ExceptionTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -29,7 +29,7 @@ import ca.uhn.fhir.rest.annotation.History;
|
|||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Since;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -119,7 +119,7 @@ public class HistoryTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPlainProvider plainProvider = new DummyPlainProvider();
|
||||
|
|
|
@ -36,8 +36,8 @@ import ca.uhn.fhir.model.primitive.StringDt;
|
|||
import ca.uhn.fhir.rest.annotation.IncludeParam;
|
||||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -225,7 +225,7 @@ public class IncludeTest {
|
|||
public static void beforeClass() throws Exception {
|
||||
|
||||
ourCtx = new FhirContext();
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package ca.uhn.fhir.rest.server;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class IncomingRequestAddressStrategyTest {
|
||||
|
||||
/**
|
||||
* This is an incoming request from an instance of Tomcat on AWS, provided by
|
||||
* Simon Ling of Systems Made Simple
|
||||
*/
|
||||
@Test
|
||||
public void testAwsUrl() {
|
||||
|
||||
HttpServletRequest req = mock(HttpServletRequest.class);
|
||||
when(req.getRequestURI()).thenReturn("/FhirStorm/fhir/Patient/_search");
|
||||
when(req.getServletPath()).thenReturn("/fhir");
|
||||
when(req.getRequestURL()).thenReturn(new StringBuffer().append("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir/Patient/_search"));
|
||||
when(req.getContextPath()).thenReturn("/FhirStorm");
|
||||
|
||||
IncomingRequestAddressStrategy incomingRequestAddressStrategy = new IncomingRequestAddressStrategy();
|
||||
String actual = incomingRequestAddressStrategy.determineServerBase(null,req);
|
||||
assertEquals("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir", actual);
|
||||
}
|
||||
|
||||
}
|
|
@ -40,7 +40,7 @@ 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.interceptor.IServerInterceptor;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -95,7 +95,7 @@ public class InterceptorTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -28,7 +28,7 @@ import ca.uhn.fhir.rest.annotation.OptionalParam;
|
|||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -68,7 +68,7 @@ public class MethodPriorityTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
|
|
|
@ -27,7 +27,7 @@ import ca.uhn.fhir.model.api.Bundle;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -167,7 +167,7 @@ public class PagingTest {
|
|||
public static void beforeClass() throws Exception {
|
||||
ourContext = new FhirContext();
|
||||
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -43,7 +43,7 @@ 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.annotation.Since;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
public class PlainProviderTest {
|
||||
|
||||
|
@ -56,7 +56,7 @@ public class PlainProviderTest {
|
|||
|
||||
@Before
|
||||
public void before() throws Exception {
|
||||
myPort = RandomServerPortProvider.findFreePort();
|
||||
myPort = PortUtil.findFreePort();
|
||||
myServer = new Server(myPort);
|
||||
myCtx = new FhirContext(Patient.class);
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -116,7 +116,7 @@ public class ReadTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
|
|
@ -37,7 +37,7 @@ import ca.uhn.fhir.rest.annotation.Search;
|
|||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -229,7 +229,7 @@ public class ReferenceParameterTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -69,10 +69,11 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
|
|||
import ca.uhn.fhir.rest.param.CodingListParam;
|
||||
import ca.uhn.fhir.rest.param.DateParam;
|
||||
import ca.uhn.fhir.rest.param.DateRangeParam;
|
||||
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.rest.server.provider.ServerProfileProvider;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -1001,7 +1002,7 @@ public class ResfulServerMethodTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
ourCtx = new FhirContext(Patient.class);
|
||||
|
||||
|
@ -1303,6 +1304,10 @@ public class ResfulServerMethodTest {
|
|||
@Read(version=true)
|
||||
public Patient vread(@IdParam IdDt theId) {
|
||||
Patient retVal = getIdToPatient().get(theId.getIdPart());
|
||||
if (retVal == null) {
|
||||
throw new ResourceNotFoundException("Couldn't find ID " + theId.getIdPart() + " - Valid IDs are: " + getIdToPatient().keySet());
|
||||
}
|
||||
|
||||
List<HumanNameDt> name = retVal.getName();
|
||||
HumanNameDt nameDt = name.get(0);
|
||||
String value = theId.getVersionIdPart();
|
||||
|
|
|
@ -36,7 +36,7 @@ import ca.uhn.fhir.rest.annotation.ResourceParam;
|
|||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -59,7 +59,7 @@ public class ResfulServerSelfReferenceTest {
|
|||
|
||||
@Test
|
||||
public void testContextWithSpace() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
Server server = new Server(port);
|
||||
|
||||
RestfulServer restServer = new RestfulServer();
|
||||
|
@ -102,7 +102,7 @@ public class ResfulServerSelfReferenceTest {
|
|||
|
||||
@Test
|
||||
public void testSearchByParamIdentifier() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
Server hServer = new Server(port);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -15,7 +15,7 @@ import ca.uhn.fhir.model.dstu.resource.Binary;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
public class ResourceProviderWithNoMethodsTest {
|
||||
|
||||
|
@ -28,7 +28,7 @@ public class ResourceProviderWithNoMethodsTest {
|
|||
|
||||
@Test
|
||||
public void testNoAnnotatedMethods() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
ourServer = new Server(port);
|
||||
|
||||
ResourceProvider patientProvider = new ResourceProvider();
|
||||
|
@ -50,7 +50,7 @@ public class ResourceProviderWithNoMethodsTest {
|
|||
|
||||
@Test
|
||||
public void testNonPublicMethod() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
ourServer = new Server(port);
|
||||
|
||||
NonPublicMethodProvider patientProvider = new NonPublicMethodProvider();
|
||||
|
|
|
@ -39,9 +39,10 @@ import ca.uhn.fhir.rest.annotation.OptionalParam;
|
|||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.ReferenceParam;
|
||||
import ca.uhn.fhir.rest.param.StringOrListParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.param.TokenOrListParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -105,6 +106,21 @@ public class SearchTest {
|
|||
assertEquals("IDAAA (identifier123)", bundle.getEntries().get(0).getTitle().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithOrList() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?findPatientWithOrList=aaa,bbb");
|
||||
HttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
IOUtils.closeQuietly(status.getEntity().getContent());
|
||||
assertEquals(200, status.getStatusLine().getStatusCode());
|
||||
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
|
||||
assertEquals(1, bundle.getEntries().size());
|
||||
|
||||
Patient p = bundle.getResources(Patient.class).get(0);
|
||||
assertEquals("aaa", p.getIdentifier().get(0).getValue().getValue());
|
||||
assertEquals("bbb", p.getIdentifier().get(1).getValue().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchByPost() throws Exception {
|
||||
HttpPost filePost = new HttpPost("http://localhost:" + ourPort + "/Patient/_search");
|
||||
|
@ -199,7 +215,7 @@ public class SearchTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
@ -295,6 +311,20 @@ public class SearchTest {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@Search()
|
||||
public List<Patient> findPatientWithOrList(@RequiredParam(name = "findPatientWithOrList") StringOrListParam theParam) {
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.setId("1");
|
||||
for (StringParam next : theParam.getValuesAsQueryTokens()) {
|
||||
patient.addIdentifier("system", next.getValue());
|
||||
}
|
||||
retVal.add(patient);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@Search(queryName = "findWithLinks")
|
||||
public List<Patient> findWithLinks() {
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
|
|
@ -25,7 +25,7 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -51,7 +51,7 @@ public class ServerBaseTest {
|
|||
|
||||
@Test
|
||||
public void testWithContextPath() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
myServer = new Server(port);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
@ -85,7 +85,7 @@ public class ServerBaseTest {
|
|||
|
||||
@Test
|
||||
public void testWithContextAndServletPath() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
myServer = new Server(port);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
@ -118,7 +118,7 @@ public class ServerBaseTest {
|
|||
|
||||
@Test
|
||||
public void testWithNoPath() throws Exception {
|
||||
int port = RandomServerPortProvider.findFreePort();
|
||||
int port = PortUtil.findFreePort();
|
||||
myServer = new Server(port);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
|
|
@ -27,7 +27,7 @@ import ca.uhn.fhir.rest.client.interceptor.LoggingInterceptor;
|
|||
import ca.uhn.fhir.rest.gclient.StringClientParam;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
public class ServerExtraParametersTest {
|
||||
|
||||
|
@ -37,7 +37,7 @@ public class ServerExtraParametersTest {
|
|||
|
||||
@Before
|
||||
public void before() {
|
||||
myPort = RandomServerPortProvider.findFreePort();
|
||||
myPort = PortUtil.findFreePort();
|
||||
myServer = new Server(myPort);
|
||||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
|
|
|
@ -36,7 +36,7 @@ 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.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -251,7 +251,7 @@ public class ServerFeaturesTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -28,7 +28,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
|
|||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.annotation.Sort;
|
||||
import ca.uhn.fhir.rest.api.SortSpec;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -130,7 +130,7 @@ public class SortTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -26,7 +26,7 @@ import ca.uhn.fhir.rest.annotation.OptionalParam;
|
|||
import ca.uhn.fhir.rest.annotation.RequiredParam;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.param.StringParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -148,7 +148,7 @@ public class StringParameterTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -34,7 +34,7 @@ import ca.uhn.fhir.rest.annotation.GetTags;
|
|||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.TagListParam;
|
||||
import ca.uhn.fhir.rest.annotation.VersionIdParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -238,7 +238,7 @@ public class TagsServerTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
ourCtx = new FhirContext(Patient.class);
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.annotation.Transaction;
|
||||
import ca.uhn.fhir.rest.annotation.TransactionParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -224,7 +224,7 @@ public class TransactionTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
|
|
@ -32,7 +32,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.annotation.Transaction;
|
||||
import ca.uhn.fhir.rest.annotation.TransactionParam;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -173,7 +173,7 @@ public class TransactionWithBundleParamTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyProvider patientProvider = new DummyProvider();
|
||||
|
|
|
@ -29,13 +29,14 @@ import ca.uhn.fhir.model.dstu.resource.DiagnosticOrder;
|
|||
import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
||||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.annotation.Update;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -279,6 +280,21 @@ public class UpdateTest {
|
|||
fail();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateWithNoReturn() throws Exception {
|
||||
|
||||
Organization patient = new Organization();
|
||||
patient.addIdentifier().setValue("002");
|
||||
|
||||
HttpPut httpPost = new HttpPut("http://localhost:" + ourPort + "/Organization/001");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
CloseableHttpResponse response = ourClient.execute(httpPost);
|
||||
assertEquals(200, response.getStatusLine().getStatusCode());
|
||||
response.close();
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
|
@ -286,7 +302,7 @@ public class UpdateTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
PatientProvider patientProvider = new PatientProvider();
|
||||
|
@ -295,7 +311,7 @@ public class UpdateTest {
|
|||
|
||||
ServletHandler proxyHandler = new ServletHandler();
|
||||
RestfulServer servlet = new RestfulServer();
|
||||
servlet.setResourceProviders(patientProvider, ourReportProvider, new ObservationProvider());
|
||||
servlet.setResourceProviders(patientProvider, ourReportProvider, new ObservationProvider(), new OrganizationResourceProvider());
|
||||
ServletHolder servletHolder = new ServletHolder(servlet);
|
||||
proxyHandler.addServletWithMapping(servletHolder, "/*");
|
||||
ourServer.setHandler(proxyHandler);
|
||||
|
@ -308,6 +324,23 @@ public class UpdateTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
public static class OrganizationResourceProvider implements IResourceProvider
|
||||
{
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Organization.class;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Update
|
||||
public MethodOutcome update(@IdParam IdDt theId, @ResourceParam Organization theOrganization) {
|
||||
return new MethodOutcome();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class DiagnosticReportProvider implements IResourceProvider {
|
||||
private TagList myLastTags;
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ import ca.uhn.fhir.rest.annotation.RequiredParam;
|
|||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.RestfulServer;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
import ca.uhn.fhir.util.PortUtil;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
@ -124,7 +124,7 @@ public class LoggingInterceptorTest {
|
|||
|
||||
@BeforeClass
|
||||
public static void beforeClass() throws Exception {
|
||||
ourPort = RandomServerPortProvider.findFreePort();
|
||||
ourPort = PortUtil.findFreePort();
|
||||
ourServer = new Server(ourPort);
|
||||
|
||||
DummyPatientResourceProvider patientProvider = new DummyPatientResourceProvider();
|
||||
|
|
|
@ -9,6 +9,7 @@ import org.junit.Test;
|
|||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.valueset.AdministrativeGenderCodesEnum;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
|
||||
|
@ -18,6 +19,7 @@ public class FhirTerserTest {
|
|||
public void testGetAllPopulatedChildElementsOfType() {
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setGender(AdministrativeGenderCodesEnum.M);
|
||||
p.addIdentifier().setSystem("urn:foo");
|
||||
p.addAddress().addLine("Line1");
|
||||
p.addAddress().addLine("Line2");
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
package ca.uhn.fhir.validation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.validation.FhirValidator;
|
||||
|
||||
public class ValidatorInstantiatorTest {
|
||||
|
||||
@Test
|
||||
public void testValidator() {
|
||||
|
||||
FhirContext ctx = new FhirContext();
|
||||
FhirValidator val = ctx.newValidator();
|
||||
|
||||
// We have a full classpath, so take advantage
|
||||
assertTrue(val.isValidateAgainstStandardSchema());
|
||||
assertTrue(val.isValidateAgainstStandardSchematron());
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,294 @@
|
|||
{
|
||||
"resourceType": "Profile",
|
||||
"text": {
|
||||
"status": "generated",
|
||||
"div": "<div><pre>\r\n<<a title=\"Prospective warnings of potential issues when providing care to the patient.\" class=\"dict\" href=\"alert-definitions.html#Alert\"><b>Alert</b></a> xmlns="http://hl7.org/fhir"> <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n <!-- from <a href=\"resources.html\">Resource</a>: <a href=\"extensibility.html\">extension</a>, <a href=\"extensibility.html#modifierExtension\">modifierExtension</a>, language, <a href=\"narrative.html#Narrative\">text</a>, and <a href=\"references.html#contained\">contained</a> -->\r\n <<a title=\"Identifier assigned to the alert for external use (outside the FHIR environment).\" class=\"dict\" href=\"alert-definitions.html#Alert.identifier\"><b>identifier</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>0..*</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#Identifier\">Identifier</a></span> <span style=\"color: navy\">Business identifier</span><span style=\"color: Gray\"> --></span></identifier>\r\n <<a title=\"Allows an alert to be divided into different categories like clinical, administrative etc.\" class=\"dict\" href=\"alert-definitions.html#Alert.category\"><b>category</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"datatypes.html#CodeableConcept\">CodeableConcept</a></span> <span style=\"color: navy\">Clinical, administrative, etc.</span><span style=\"color: Gray\"> --></span></category>\r\n <<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]"/><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\"><a style=\"color: navy\" href=\"alert-status.html\">active | inactive | entered in error</a></span><span style=\"color: Gray\"> --></span>\r\n <<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"patient.html#Patient\">Patient</a>)</span> <span style=\"color: navy\">Who is alert about?</span><span style=\"color: Gray\"> --></span></subject>\r\n <<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>0..1</b></span> <span style=\"color: darkgreen\"><a href=\"references.html#Resource\">Resource</a>(<a href=\"practitioner.html#Practitioner\">Practitioner</a>|<a href=\"patient.html#Patient\">Patient</a>|<a href=\"device.html#Device\">Device</a>)</span> <span style=\"color: navy\">Alert creator</span><span style=\"color: Gray\"> --></span></author>\r\n <<a title=\"The textual component of the alert to display to the user.\" class=\"dict\" href=\"alert-definitions.html#Alert.note\"><b>note</b></a> value="[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]"/><span style=\"color: Gray\"><!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --></span>\r\n</Alert>\r\n</pre></div>"
|
||||
},
|
||||
"name": "alert",
|
||||
"publisher": "FHIR Project",
|
||||
"description": "Basic Profile. Prospective warnings of potential issues when providing care to the patient.",
|
||||
"status": "draft",
|
||||
"date": "2014-05-09",
|
||||
"requirements": "Scope and Usage The Alert resource provides a single interface for managing clinical and administrative facts that need to be brought to the attention of users of clinical systems. Examples can include many things. Patient's posing particular risks (falls, physical violence), patient's needing special accomodations (hard of hearing, use easy-open caps), administrative concerns (verify postal address, pre-payment required) or any other situation that needs to be brought to attention within the context of a particular workflow. (The workflow relevant to the issue can be identified by the category element.) \r\n\r\nUsually, resources specific to particular types of issues (health conditions, allergies, active medications will be used to communicate those issues. However, in some cases, particularly important information (a latex or severe food allergy) migt be highlighted as an Alert as well as the more typical resource.",
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"uri": "http://hl7.org/v3",
|
||||
"name": "RIM"
|
||||
}
|
||||
],
|
||||
"structure": [
|
||||
{
|
||||
"type": "Alert",
|
||||
"publish": true,
|
||||
"element": [
|
||||
{
|
||||
"path": "Alert",
|
||||
"definition": {
|
||||
"short": "Key information to flag to healthcare providers",
|
||||
"formal": "Prospective warnings of potential issues when providing care to the patient.",
|
||||
"min": 1,
|
||||
"max": "1",
|
||||
"type": [
|
||||
{
|
||||
"code": "Resource"
|
||||
}
|
||||
],
|
||||
"isModifier": false,
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"map": "Observation[classCode=ISSUE, moodCode=EVN]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.extension",
|
||||
"definition": {
|
||||
"short": "Additional Content defined by implementations",
|
||||
"formal": "May be used to represent additional information that is not part of the basic definition of the resource. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.",
|
||||
"comments": "there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone.",
|
||||
"synonym": [
|
||||
"extensions",
|
||||
"user content"
|
||||
],
|
||||
"min": 0,
|
||||
"max": "*",
|
||||
"type": [
|
||||
{
|
||||
"code": "Extension"
|
||||
}
|
||||
],
|
||||
"isModifier": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.modifierExtension",
|
||||
"definition": {
|
||||
"short": "Extensions that cannot be ignored",
|
||||
"formal": "May be used to represent additional information that is not part of the basic definition of the resource, and that modifies the understanding of the element that contains it. Usually modifier elements provide negation or qualification. In order to make the use of extensions safe and manageable, there is a strict governance applied to the definition and use of extensions. Though any implementer is allowed to define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension. Applications processing a resource are required to check for modifier extensions.",
|
||||
"comments": "there can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions. The use of extensions is what allows the FHIR specification to retain a core simplicity for everyone.",
|
||||
"synonym": [
|
||||
"extensions",
|
||||
"user content"
|
||||
],
|
||||
"min": 0,
|
||||
"max": "*",
|
||||
"type": [
|
||||
{
|
||||
"code": "Extension"
|
||||
}
|
||||
],
|
||||
"isModifier": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.text",
|
||||
"definition": {
|
||||
"short": "Text summary of the resource, for human interpretation",
|
||||
"formal": "A human-readable narrative that contains a summary of the resource, and may be used to represent the content of the resource to a human. The narrative need not encode all the structured data, but is required to contain sufficient detail to make it \"clinically safe\" for a human to just read the narrative. Resource definitions may define what content should be represented in the narrative to ensure clinical safety.",
|
||||
"comments": "Contained resources do not have narrative. Resources that are not contained SHOULD have a narrative.",
|
||||
"synonym": [
|
||||
"narrative",
|
||||
"html",
|
||||
"xhtml",
|
||||
"display"
|
||||
],
|
||||
"min": 0,
|
||||
"max": "1",
|
||||
"type": [
|
||||
{
|
||||
"code": "Narrative"
|
||||
}
|
||||
],
|
||||
"isModifier": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.contained",
|
||||
"definition": {
|
||||
"short": "Contained, inline Resources",
|
||||
"formal": "These resources do not have an independent existence apart from the resource that contains them - they cannot be identified independently, and nor can they have their own independent transaction scope.",
|
||||
"comments": "This should never be done when the content can be identified properly, as once identification is lost, it is extremely difficult (and context dependent) to restore it again.",
|
||||
"synonym": [
|
||||
"inline resources",
|
||||
"anonymous resources",
|
||||
"contained resources"
|
||||
],
|
||||
"min": 0,
|
||||
"max": "*",
|
||||
"type": [
|
||||
{
|
||||
"code": "Resource"
|
||||
}
|
||||
],
|
||||
"isModifier": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.identifier",
|
||||
"definition": {
|
||||
"short": "Business identifier",
|
||||
"formal": "Identifier assigned to the alert for external use (outside the FHIR environment).",
|
||||
"min": 0,
|
||||
"max": "*",
|
||||
"type": [
|
||||
{
|
||||
"code": "Identifier"
|
||||
}
|
||||
],
|
||||
"isModifier": false,
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"map": ".id"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.category",
|
||||
"definition": {
|
||||
"short": "Clinical, administrative, etc.",
|
||||
"formal": "Allows an alert to be divided into different categories like clinical, administrative etc.",
|
||||
"min": 0,
|
||||
"max": "1",
|
||||
"type": [
|
||||
{
|
||||
"code": "CodeableConcept"
|
||||
}
|
||||
],
|
||||
"isModifier": false,
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"map": ".code"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.status",
|
||||
"definition": {
|
||||
"short": "active | inactive | entered in error",
|
||||
"formal": "Supports basic workflow.",
|
||||
"min": 1,
|
||||
"max": "1",
|
||||
"type": [
|
||||
{
|
||||
"code": "code"
|
||||
}
|
||||
],
|
||||
"isModifier": false,
|
||||
"binding": {
|
||||
"name": "AlertStatus",
|
||||
"isExtensible": false,
|
||||
"conformance": "required",
|
||||
"referenceResource": {
|
||||
"reference": "http://hl7.org/fhir/vs/alert-status"
|
||||
}
|
||||
},
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"map": ".status"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.subject",
|
||||
"definition": {
|
||||
"short": "Who is alert about?",
|
||||
"formal": "The person who this alert concerns.",
|
||||
"min": 1,
|
||||
"max": "1",
|
||||
"type": [
|
||||
{
|
||||
"code": "ResourceReference",
|
||||
"profile": "http://hl7.org/fhir/profiles/Patient"
|
||||
}
|
||||
],
|
||||
"isModifier": false,
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"map": ".participation[typeCode=SBJ].role[classCode=PAT]"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.author",
|
||||
"definition": {
|
||||
"short": "Alert creator",
|
||||
"formal": "The person or device that created the alert.",
|
||||
"min": 0,
|
||||
"max": "1",
|
||||
"type": [
|
||||
{
|
||||
"code": "ResourceReference",
|
||||
"profile": "http://hl7.org/fhir/profiles/Practitioner"
|
||||
},
|
||||
{
|
||||
"code": "ResourceReference",
|
||||
"profile": "http://hl7.org/fhir/profiles/Patient"
|
||||
},
|
||||
{
|
||||
"code": "ResourceReference",
|
||||
"profile": "http://hl7.org/fhir/profiles/Device"
|
||||
}
|
||||
],
|
||||
"isModifier": false,
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"map": ".participation[typeCode=AUT].role"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "Alert.note",
|
||||
"definition": {
|
||||
"short": "Text of alert",
|
||||
"formal": "The textual component of the alert to display to the user.",
|
||||
"min": 1,
|
||||
"max": "1",
|
||||
"type": [
|
||||
{
|
||||
"code": "string"
|
||||
}
|
||||
],
|
||||
"isModifier": false,
|
||||
"mapping": [
|
||||
{
|
||||
"identity": "rim",
|
||||
"map": ".value"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"searchParam": [
|
||||
{
|
||||
"name": "_id",
|
||||
"type": "token",
|
||||
"documentation": "The logical resource id associated with the resource (must be supported by all servers)"
|
||||
},
|
||||
{
|
||||
"name": "_language",
|
||||
"type": "token",
|
||||
"documentation": "The language of the resource"
|
||||
},
|
||||
{
|
||||
"name": "subject",
|
||||
"type": "reference",
|
||||
"documentation": "The identity of a subject to list alerts for",
|
||||
"xpath": "f:Alert/f:subject"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -10,6 +10,9 @@
|
|||
<logger name="org.eclipse" additivity="false" level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
<logger name="org.apache" additivity="false" level="info">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</logger>
|
||||
|
||||
<!--
|
||||
<logger name="ca.uhn.fhir.rest.client" additivity="false" level="trace">
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<?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 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"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>hapi-fhir-mitreid-integration</name>
|
||||
<name>hapi-fhir-base-examples</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
|
@ -0,0 +1,2 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
|
@ -0,0 +1,289 @@
|
|||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=true
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=80
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=3
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=160
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=space
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=3
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
|
@ -0,0 +1,3 @@
|
|||
eclipse.preferences.version=1
|
||||
formatter_profile=_examples-format
|
||||
formatter_settings_version=12
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue