Merge branch 'master' of github.com:jamesagnew/hapi-fhir

Conflicts:
	hapi-fhir-base/src/changes/changes.xml
This commit is contained in:
jamesagnew 2014-09-17 08:33:52 -04:00
commit 594b04d838
29 changed files with 1240 additions and 67 deletions

View File

@ -225,6 +225,13 @@
<version>9.1.1.v20140108</version> <version>9.1.1.v20140108</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>9.1.1.v20140108</version>
<scope>test</scope>
</dependency>
<!-- UNIT TEST DEPENDENCIES --> <!-- UNIT TEST DEPENDENCIES -->
<dependency> <dependency>

View File

@ -20,6 +20,14 @@
a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of a primitive type child. Thanks to Jeffrey Ting and Bill De Beaubien of
Systems Made Simple for their help in figuring out this issue! Systems Made Simple for their help in figuring out this issue!
</action> </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. &lt; or &quot;) will now always have those characters
escaped properly in encoded messages.
</action>
</release> </release>
<release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!"> <release version="0.6" date="2014-Sep-08" description="This release brings a number of new features and bug fixes!">
<!-- <!--

View File

@ -20,8 +20,12 @@ package ca.uhn.fhir.model.primitive;
* #L% * #L%
*/ */
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader; import java.io.StringReader;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -33,6 +37,10 @@ import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.XMLEvent; 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.context.ConfigurationException;
import ca.uhn.fhir.model.api.BasePrimitive; import ca.uhn.fhir.model.api.BasePrimitive;
import ca.uhn.fhir.model.api.annotation.DatatypeDef; import ca.uhn.fhir.model.api.annotation.DatatypeDef;
@ -50,7 +58,7 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
public XhtmlDt() { public XhtmlDt() {
// nothing // nothing
} }
/** /**
* Constructor which accepts a string code * 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. * Accepts a textual DIV and parses it into XHTML events which are stored internally.
* <p> * <p>
* <b>Formatting note:</b> The text will be trimmed {@link String#trim()}. If the text does not start with * <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
* an HTML tag (generally this would be a div tag), a div tag will be automatically * surrounding the text.
* placed surrounding the text.
* </p> * </p>
*/ */
@Override @Override
@ -75,7 +82,7 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
myValue = null; myValue = null;
return; return;
} }
String val = theValue.trim(); String val = theValue.trim();
if (!val.startsWith("<")) { if (!val.startsWith("<")) {
val = "<div>" + val + "</div>"; val = "<div>" + val + "</div>";
@ -84,7 +91,7 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
myValue = null; myValue = null;
return; return;
} }
try { try {
ArrayList<XMLEvent> value = new ArrayList<XMLEvent>(); ArrayList<XMLEvent> value = new ArrayList<XMLEvent>();
XMLEventReader er = XMLInputFactory.newInstance().createXMLEventReader(new StringReader(val)); XMLEventReader er = XMLInputFactory.newInstance().createXMLEventReader(new StringReader(val));
@ -101,9 +108,9 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
} }
} }
setValue(value); setValue(value);
} catch (XMLStreamException e) { } 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) { } catch (FactoryConfigurationError e) {
throw new ConfigurationException(e); throw new ConfigurationException(e);
} }
@ -116,9 +123,17 @@ public class XhtmlDt extends BasePrimitive<List<XMLEvent>> {
} }
try { try {
StringWriter w = new StringWriter(); 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) { for (XMLEvent next : myValue) {
ew.add(next); if (next.isCharacters()) {
ew.add(next);
} else {
ew.add(next);
}
} }
ew.close(); ew.close();
return w.toString(); 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 @Override
public List<XMLEvent> getValue() { public List<XMLEvent> getValue() {
return myValue; return myValue;

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server;
* #L% * #L%
*/ */
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
@ -30,16 +31,11 @@ public class HardcodedServerAddressStrategy implements IServerAddressStrategy {
private String myValue; private String myValue;
public HardcodedServerAddressStrategy() { public HardcodedServerAddressStrategy() {
//nothing // nothing
}
public HardcodedServerAddressStrategy(String theValue) {
myValue=theValue;
} }
@Override public HardcodedServerAddressStrategy(String theValue) {
public String determineServerBase(HttpServletRequest theRequest) { myValue = theValue;
return myValue;
} }
public String getValue() { public String getValue() {
@ -50,4 +46,9 @@ public class HardcodedServerAddressStrategy implements IServerAddressStrategy {
myValue = theValue; myValue = theValue;
} }
@Override
public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
return myValue;
}
} }

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server;
* #L% * #L%
*/ */
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
@ -31,6 +32,6 @@ public interface IServerAddressStrategy {
/** /**
* Determine the server base for a given request * Determine the server base for a given request
*/ */
public String determineServerBase(HttpServletRequest theRequest); String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest);
} }

View File

@ -20,6 +20,7 @@ package ca.uhn.fhir.rest.server;
* #L% * #L%
*/ */
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -30,13 +31,13 @@ import org.apache.commons.lang3.StringUtils;
public class IncomingRequestAddressStrategy implements IServerAddressStrategy { public class IncomingRequestAddressStrategy implements IServerAddressStrategy {
@Override @Override
public String determineServerBase(HttpServletRequest theRequest) { public String determineServerBase(ServletContext theServletContext, HttpServletRequest theRequest) {
String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI()); String requestFullPath = StringUtils.defaultString(theRequest.getRequestURI());
String servletPath = StringUtils.defaultString(theRequest.getServletPath()); String servletPath = StringUtils.defaultString(theRequest.getServletPath());
StringBuffer requestUrl = theRequest.getRequestURL(); StringBuffer requestUrl = theRequest.getRequestURL();
String servletContextPath = ""; String servletContextPath = "";
if (theRequest.getServletContext() != null) { if (theServletContext != null) {
servletContextPath = StringUtils.defaultString(theRequest.getServletContext().getContextPath()); servletContextPath = StringUtils.defaultString(theServletContext.getContextPath());
// } else { // } else {
// servletContextPath = servletPath; // servletContextPath = servletPath;
} }

View File

@ -454,12 +454,14 @@ public class RestfulServer extends HttpServlet {
String servletPath = StringUtils.defaultString(theRequest.getServletPath()); String servletPath = StringUtils.defaultString(theRequest.getServletPath());
StringBuffer requestUrl = theRequest.getRequestURL(); StringBuffer requestUrl = theRequest.getRequestURL();
String servletContextPath = ""; 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()) { if (ourLog.isTraceEnabled()) {
ourLog.trace("Request FullPath: {}", requestFullPath); ourLog.trace("Request FullPath: {}", requestFullPath);
ourLog.trace("Servlet Path: {}", servletPath); ourLog.trace("Servlet Path: {}", servletPath);
@ -476,7 +478,7 @@ public class RestfulServer extends HttpServlet {
requestPath = requestPath.substring(1); requestPath = requestPath.substring(1);
} }
fhirServerBase = myServerAddressStrategy.determineServerBase(theRequest); fhirServerBase = myServerAddressStrategy.determineServerBase(getServletContext(), theRequest);
if (fhirServerBase.endsWith("/")) { if (fhirServerBase.endsWith("/")) {
fhirServerBase = fhirServerBase.substring(0, fhirServerBase.length() - 1); fhirServerBase = fhirServerBase.substring(0, fhirServerBase.length() - 1);

View File

@ -26,14 +26,15 @@ import java.util.List;
import org.apache.commons.lang3.Validate; import org.apache.commons.lang3.Validate;
import com.phloc.schematron.ISchematronResource;
import ca.uhn.fhir.context.FhirContext; import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle; import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource; import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome; import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
/** /**
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, * Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, etc.)
* etc.)
* *
* <p> * <p>
* To obtain a resource validator, call {@link FhirContext#newValidator()} * 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 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 FhirContext myContext;
private List<IValidator> myValidators = new ArrayList<IValidator>(); 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 * Constructor (this should not be called directly, but rather {@link FhirContext#newValidator()} should be called to obtain an instance of {@link FhirValidator})
* to obtain an instance of {@link FhirValidator})
*/ */
public FhirValidator(FhirContext theFhirContext) { public FhirValidator(FhirContext theFhirContext) {
myContext = theFhirContext; myContext = theFhirContext;
setValidateAgainstStandardSchema(true); 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) { 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 * Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
* distribution itself)
*/ */
public boolean isValidateAgainstStandardSchema() { public boolean isValidateAgainstStandardSchema() {
return haveValidatorOfType(SchemaBaseValidator.class); return haveValidatorOfType(SchemaBaseValidator.class);
} }
/** /**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR * Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
* distribution itself)
*/ */
public boolean isValidateAgainstStandardSchematron() { public boolean isValidateAgainstStandardSchematron() {
return haveValidatorOfType(SchematronBaseValidator.class); return haveValidatorOfType(SchematronBaseValidator.class);
} }
/** /**
* Should the validator validate the resource against the base schema (the schema provided with the FHIR * Should the validator validate the resource against the base schema (the schema provided with the FHIR distribution itself)
* distribution itself)
*/ */
public void setValidateAgainstStandardSchema(boolean theValidateAgainstStandardSchema) { public void setValidateAgainstStandardSchema(boolean theValidateAgainstStandardSchema) {
addOrRemoveValidator(theValidateAgainstStandardSchema, SchemaBaseValidator.class, new SchemaBaseValidator()); addOrRemoveValidator(theValidateAgainstStandardSchema, SchemaBaseValidator.class, new SchemaBaseValidator());
} }
/** /**
* Should the validator validate the resource against the base schematron (the schematron provided with the FHIR * Should the validator validate the resource against the base schematron (the schematron provided with the FHIR distribution itself)
* distribution itself)
*/ */
public void setValidateAgainstStandardSchematron(boolean theValidateAgainstStandardSchematron) { 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()); addOrRemoveValidator(theValidateAgainstStandardSchematron, SchematronBaseValidator.class, new SchematronBaseValidator());
} }
/** /**
* Validates a bundle instance, throwing a {@link ValidationFailureException} if the validation fails. This * Validates a bundle instance, throwing a {@link ValidationFailureException} if the validation fails. This validation includes validation of all resources in the bundle.
* validation includes validation of all resources in the bundle.
* *
* @param theResource The resource to validate * @param theResource
* @throws ValidationFailureException If the validation fails * The resource to validate
* @throws ValidationFailureException
* If the validation fails
*/ */
public void validate(Bundle theBundle) { public void validate(Bundle theBundle) {
Validate.notNull(theBundle, "theBundle must not be null"); 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 * Validates a resource instance, throwing a {@link ValidationFailureException} if the validation fails
* *
* @param theResource The resource to validate * @param theResource
* @throws ValidationFailureException If the validation fails * The resource to validate
* @throws ValidationFailureException
* If the validation fails
*/ */
public void validate(IResource theResource) throws ValidationFailureException { public void validate(IResource theResource) throws ValidationFailureException {
Validate.notNull(theResource, "theResource must not be null"); Validate.notNull(theResource, "theResource must not be null");

View File

@ -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.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.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

View File

@ -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=&quot;http://hl7.org/fhir&quot;</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&lt;<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=&quot;http://hl7.org/fhir&quot;&gt; <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n &lt;!-- 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> --&gt;\r\n &lt;<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>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/identifier&gt;\r\n &lt;<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>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/category&gt;\r\n &lt;<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>\r\n &lt;<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/subject&gt;\r\n &lt;<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/author&gt;\r\n &lt;<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=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --&gt;</span>\r\n&lt;/Alert&gt;\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);
}
}

View File

@ -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.Observation;
import ca.uhn.fhir.model.dstu.resource.Organization; import ca.uhn.fhir.model.dstu.resource.Organization;
import ca.uhn.fhir.model.dstu.resource.Patient; 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.Query;
import ca.uhn.fhir.model.dstu.resource.Specimen; import ca.uhn.fhir.model.dstu.resource.Specimen;
import ca.uhn.fhir.model.dstu.resource.ValueSet; import ca.uhn.fhir.model.dstu.resource.ValueSet;
@ -442,6 +443,31 @@ public class JsonParserTest {
ourLog.info(encoded); 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 @Test
@ -926,9 +952,13 @@ public class JsonParserTest {
JSON expected = JSONSerializer.toJSON(jsonString); JSON expected = JSONSerializer.toJSON(jsonString);
JSON actual = JSONSerializer.toJSON(encoded.trim()); JSON actual = JSONSerializer.toJSON(encoded.trim());
ourLog.info("Expected: {}", expected); // The encoded escapes quote marks using XML escaping instead of JSON escaping, which is probably nicer anyhow...
ourLog.info("Actual : {}", actual); String exp = expected.toString().replace("\\\"Jim\\\"", "&quot;Jim&quot;");
assertEquals(expected.toString(), actual.toString()); 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 expected = JSONSerializer.toJSON(jsonString);
JSON actual = JSONSerializer.toJSON(encoded.trim()); JSON actual = JSONSerializer.toJSON(encoded.trim());
ourLog.info("Expected: {}", expected); // The encoded escapes quote marks using XML escaping instead of JSON escaping, which is probably nicer anyhow...
ourLog.info("Actual : {}", actual); String exp = expected.toString().replace("\\\"Jim\\\"", "&quot;Jim&quot;");
assertEquals(expected.toString(), actual.toString()); String act = actual.toString();
ourLog.info("Expected: {}", exp);
ourLog.info("Actual : {}", act);
assertEquals(exp, act);
} }

View File

@ -920,7 +920,11 @@ public class XmlParserTest {
ValueSet resource = (ValueSet) entry.getResource(); ValueSet resource = (ValueSet) entry.getResource();
assertEquals("LOINC Codes for Cholesterol", resource.getName().getValue()); assertEquals("LOINC Codes for Cholesterol", resource.getName().getValue());
assertEquals(summaryText.trim(), entry.getSummary().getValueAsString().trim());
String exp = summaryText.trim();
exp = exp.replace("\"LOINC", "&quot;LOINC");
exp = exp.replace("terol\"", "terol&quot;");
assertEquals(exp, entry.getSummary().getValueAsString().trim());
TagList tl = (TagList) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST); TagList tl = (TagList) resource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
assertEquals(1, tl.size()); assertEquals(1, tl.size());

View File

@ -9,6 +9,10 @@ import org.junit.Test;
public class IncomingRequestAddressStrategyTest { public class IncomingRequestAddressStrategyTest {
/**
* This is an incoming request from an instance of Tomcat on AWS, provided by
* Simon Ling of Systems Made Simple
*/
@Test @Test
public void testAwsUrl() { public void testAwsUrl() {
@ -19,18 +23,8 @@ public class IncomingRequestAddressStrategyTest {
when(req.getContextPath()).thenReturn("/FhirStorm"); when(req.getContextPath()).thenReturn("/FhirStorm");
IncomingRequestAddressStrategy incomingRequestAddressStrategy = new IncomingRequestAddressStrategy(); IncomingRequestAddressStrategy incomingRequestAddressStrategy = new IncomingRequestAddressStrategy();
String actual = incomingRequestAddressStrategy.determineServerBase(req); String actual = incomingRequestAddressStrategy.determineServerBase(null,req);
assertEquals("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir", actual); assertEquals("http://fhirstorm.dyndns.org:8080/FhirStorm/fhir", actual);
} }
/*
IncomingRequestAddressStrategy15:29:02.876 [http-bio-8080-exec-3] TRACE c.uhn.fhir.rest.server.RestfulServer -
Request FullPath: /FhirStorm/fhir/Patient/_search
15:29:02.876 [http-bio-8080-exec-3] TRACE c.uhn.fhir.rest.server.RestfulServer -
Servlet Path: /fhir
15:29:02.876 [http-bio-8080-exec-3] TRACE c.uhn.fhir.rest.server.RestfulServer -
Request Url: http://fhirstorm.dyndns.org:8080/FhirStorm/fhir/Patient/_search
15:29:02.876 [http-bio-8080-exec-3] TRACE c.uhn.fhir.rest.server.RestfulServer -
Context Path: /FhirStorm
*/
} }

View File

@ -69,6 +69,7 @@ import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.param.CodingListParam; import ca.uhn.fhir.rest.param.CodingListParam;
import ca.uhn.fhir.rest.param.DateParam; import ca.uhn.fhir.rest.param.DateParam;
import ca.uhn.fhir.rest.param.DateRangeParam; 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.ResourceNotFoundException;
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException; import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
import ca.uhn.fhir.rest.server.provider.ServerProfileProvider; import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
@ -1303,6 +1304,10 @@ public class ResfulServerMethodTest {
@Read(version=true) @Read(version=true)
public Patient vread(@IdParam IdDt theId) { public Patient vread(@IdParam IdDt theId) {
Patient retVal = getIdToPatient().get(theId.getIdPart()); 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(); List<HumanNameDt> name = retVal.getName();
HumanNameDt nameDt = name.get(0); HumanNameDt nameDt = name.get(0);
String value = theId.getVersionIdPart(); String value = theId.getVersionIdPart();

View File

@ -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());
}
}

View File

@ -0,0 +1,294 @@
{
"resourceType": "Profile",
"text": {
"status": "generated",
"div": "<div><pre>\r\n&lt;<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=&quot;http://hl7.org/fhir&quot;&gt; <span style=\"float: right\"><a title=\"Documentation for this format\" href=\"formats.html\"><img alt=\"doco\" src=\"help.png\"/></a></span>\r\n &lt;!-- 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> --&gt;\r\n &lt;<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>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/identifier&gt;\r\n &lt;<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>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/category&gt;\r\n &lt;<a title=\"Supports basic workflow.\" class=\"dict\" href=\"alert-definitions.html#Alert.status\"><b>status</b></a> value=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#code\">code</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>\r\n &lt;<a title=\"The person who this alert concerns.\" class=\"dict\" href=\"alert-definitions.html#Alert.subject\"><b>subject</b></a>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/subject&gt;\r\n &lt;<a title=\"The person or device that created the alert.\" class=\"dict\" href=\"alert-definitions.html#Alert.author\"><b>author</b></a>&gt;<span style=\"color: Gray\">&lt;!--</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\"> --&gt;</span>&lt;/author&gt;\r\n &lt;<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=&quot;[<span style=\"color: darkgreen\"><a href=\"datatypes.html#string\">string</a></span>]&quot;/&gt;<span style=\"color: Gray\">&lt;!--</span> <span style=\"color: brown\"><b>1..1</b></span> <span style=\"color: navy\">Text of alert</span><span style=\"color: Gray\"> --&gt;</span>\r\n&lt;/Alert&gt;\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"
}
]
}
]
}

View File

@ -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
hapi-fhir-base/testmindeps/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target/

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>hapi-fhir-base-examples</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
eclipse.preferences.version=1
encoding/<project>=UTF-8

View File

@ -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

View File

@ -0,0 +1,3 @@
eclipse.preferences.version=1
formatter_profile=_examples-format
formatter_settings_version=12

View File

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

View File

@ -0,0 +1,61 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir</artifactId>
<version>0.7-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<artifactId>hapi-fhir-base-testmindeps</artifactId>
<packaging>jar</packaging>
<name>HAPI FHIR - Minimal Dependency Test</name>
<dependencies>
<dependency>
<groupId>jetty</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5-6.0.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit_version}</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId>
<version>0.7-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

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

View File

@ -0,0 +1,187 @@
package ca.uhn.fhir.testmindeps;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.concurrent.TimeUnit;
import org.apache.commons.io.IOUtils;
import org.apache.http.Header;
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.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.servlet.ServletHandler;
import org.mortbay.jetty.servlet.ServletHolder;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
import ca.uhn.fhir.model.dstu.resource.Binary;
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.rest.server.Constants;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class ReadTest {
private static CloseableHttpClient ourClient;
private static int ourPort;
private static Server ourServer;
private static FhirContext ourCtx;
@Test
public void testRead() throws Exception {
{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
IdentifierDt dt = ourCtx.newXmlParser().parseResource(Patient.class,responseContent).getIdentifierFirstRep();
assertEquals("1", dt.getSystem().getValueAsString());
assertEquals(null, dt.getValue().getValueAsString());
Header cl = status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION_LC);
assertNotNull(cl);
assertEquals("http://localhost:" + ourPort + "/Patient/1/_history/1", cl.getValue());
}
}
@Test
public void testBinaryRead() throws Exception {
{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary/1");
HttpResponse status = ourClient.execute(httpGet);
byte[] responseContent = IOUtils.toByteArray(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
assertEquals("application/x-foo", status.getEntity().getContentType().getValue());
Header cl = status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION_LC);
assertNotNull(cl);
assertEquals("http://localhost:" + ourPort + "/Binary/1/_history/1", cl.getValue());
Header cd = status.getFirstHeader("content-disposition");
assertNotNull(cd);
assertEquals("Attachment;", cd.getValue());
assertEquals(4,responseContent.length);
for (int i = 0; i < 4; i++) {
assertEquals(i+1, responseContent[i]); // should be 1,2,3,4
}
}
}
@Test
public void testVRead() throws Exception {
{
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/1/_history/2");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
assertEquals(200, status.getStatusLine().getStatusCode());
IdentifierDt dt = ourCtx.newXmlParser().parseResource(Patient.class,responseContent).getIdentifierFirstRep();
assertEquals("1", dt.getSystem().getValueAsString());
assertEquals("2", dt.getValue().getValueAsString());
Header cl = status.getFirstHeader(Constants.HEADER_CONTENT_LOCATION_LC);
assertNotNull(cl);
assertEquals("http://localhost:" + ourPort + "/Patient/1/_history/1", cl.getValue());
}
}
@AfterClass
public static void afterClass() throws Exception {
ourServer.stop();
}
@BeforeClass
public static void beforeClass() throws Exception {
ourPort = PortUtil.findFreePort();
ourServer = new Server(ourPort);
DummyProvider patientProvider = new DummyProvider();
ServletHandler proxyHandler = new ServletHandler();
RestfulServer servlet = new RestfulServer();
ourCtx = servlet.getFhirContext();
servlet.setResourceProviders(patientProvider, new DummyBinaryProvider());
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 DummyProvider implements IResourceProvider {
@Read(version = true)
public Patient findPatient(@IdParam IdDt theId) {
Patient patient = new Patient();
patient.addIdentifier(theId.getIdPart(), theId.getVersionIdPart());
patient.setId("Patient/1/_history/1");
return patient;
}
@Override
public Class<? extends IResource> getResourceType() {
return Patient.class;
}
}
/**
* Created by dsotnikov on 2/25/2014.
*/
public static class DummyBinaryProvider implements IResourceProvider {
@Read(version = true)
public Binary findPatient(@IdParam IdDt theId) {
Binary bin = new Binary();
bin.setContentType("application/x-foo");
bin.setContent(new byte[] {1,2,3,4});
bin.setId("Binary/1/_history/1");
return bin;
}
@Override
public Class<? extends IResource> getResourceType() {
return Binary.class;
}
}
}

View File

@ -0,0 +1,30 @@
package ca.uhn.fhir.testmindeps;
import static org.junit.Assert.*;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.validation.FhirValidator;
public class ValidatorTest {
@Test
public void testValidator() {
FhirContext ctx = new FhirContext();
FhirValidator val = ctx.newValidator();
// Phloc is not onthe classpath
assertTrue(val.isValidateAgainstStandardSchema());
assertFalse(val.isValidateAgainstStandardSchematron());
try { val.setValidateAgainstStandardSchematron(true);
fail();
} catch (IllegalArgumentException e) {
assertEquals("Phloc-schematron library not found on classpath, can not enable perform schematron validation", e.getMessage());
}
}
}

View File

@ -17,7 +17,7 @@
<dependency> <dependency>
<groupId>ca.uhn.hapi.fhir</groupId> <groupId>ca.uhn.hapi.fhir</groupId>
<artifactId>hapi-fhir-base</artifactId> <artifactId>hapi-fhir-base</artifactId>
<version>0.6-SNAPSHOT</version> <version>0.7-SNAPSHOT</version>
</dependency> </dependency>
<!-- Only required for OpenID Connect Support --> <!-- Only required for OpenID Connect Support -->

View File

@ -75,6 +75,7 @@
<module>hapi-fhir-base</module> <module>hapi-fhir-base</module>
<module>hapi-fhir-oauth2</module> <module>hapi-fhir-oauth2</module>
<module>hapi-fhir-base/examples</module> <module>hapi-fhir-base/examples</module>
<module>hapi-fhir-base/testmindeps</module>
<module>hapi-tinder-plugin</module> <module>hapi-tinder-plugin</module>
<module>hapi-tinder-test</module> <module>hapi-tinder-test</module>
<module>hapi-fhir-structures-dstu</module> <module>hapi-fhir-structures-dstu</module>