More work on documentation
This commit is contained in:
parent
8b6f00bb58
commit
360db1d296
|
@ -29,4 +29,15 @@
|
|||
|
||||
* Support extensions (declared and undeclared) in primitives, narratives, etc.
|
||||
|
||||
* Create a Maven archetype for a server project and a client project
|
||||
* Create a Maven archetype for a server project and a client project
|
||||
|
||||
* Support "Binary" resource, which is a special resource type
|
||||
|
||||
---------
|
||||
Issues:
|
||||
* Need to be able to bind Identifier.system to a set of allowable values in a profile. Graeme
|
||||
has suggested making value[x] repeatable in the profile definition
|
||||
|
||||
* CarePlan.Activity has a type of "xmlIdRef" which is a weird datatype. The example here:
|
||||
http://www.hl7.org/implement/standards/fhir/careplan-example-integrated.xml.html
|
||||
seems to use an extension to model that element instead of the goal type too.
|
|
@ -54,9 +54,11 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
for (Class<? extends IElement> next : myChoiceTypes) {
|
||||
|
||||
String elementName;
|
||||
String alternateElementName=null;
|
||||
BaseRuntimeElementDefinition<?> nextDef;
|
||||
if (IResource.class.isAssignableFrom(next)) {
|
||||
elementName = getElementName() + StringUtils.capitalize(next.getSimpleName());
|
||||
alternateElementName = getElementName() + "Resource";
|
||||
List<Class<? extends IResource>> types = new ArrayList<Class<? extends IResource>>();
|
||||
types.add((Class<? extends IResource>)next);
|
||||
nextDef = new RuntimeResourceReferenceDefinition(elementName, types);
|
||||
|
@ -67,6 +69,9 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
}
|
||||
|
||||
myNameToChildDefinition.put(elementName, nextDef);
|
||||
if (alternateElementName!=null) {
|
||||
myNameToChildDefinition.put(alternateElementName, nextDef);
|
||||
}
|
||||
myDatatypeToElementDefinition.put(next, nextDef);
|
||||
myDatatypeToElementName.put(next, elementName);
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package ca.uhn.fhir.context;
|
|||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
@ -16,6 +17,7 @@ public class RuntimeChildResourceDefinition extends BaseRuntimeDeclaredChildDefi
|
|||
|
||||
private BaseRuntimeElementDefinition<?> myRuntimeDef;
|
||||
private List<Class<? extends IResource>> myResourceTypes;
|
||||
private Set<String> myValidChildNames;
|
||||
|
||||
public RuntimeChildResourceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IResource>> theResourceTypes) {
|
||||
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
||||
|
@ -44,7 +46,7 @@ public class RuntimeChildResourceDefinition extends BaseRuntimeDeclaredChildDefi
|
|||
|
||||
@Override
|
||||
public Set<String> getValidChildNames() {
|
||||
return Collections.singleton(getElementName());
|
||||
return myValidChildNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,5 +58,16 @@ public class RuntimeChildResourceDefinition extends BaseRuntimeDeclaredChildDefi
|
|||
void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||
myRuntimeDef = new RuntimeResourceReferenceDefinition(getElementName(), myResourceTypes);
|
||||
myRuntimeDef.sealAndInitialize(theClassToElementDefinitions);
|
||||
|
||||
myValidChildNames = new HashSet<String>();
|
||||
myValidChildNames.add(getElementName());
|
||||
myValidChildNames.add(getElementName() + "Resource");
|
||||
|
||||
for (Class<? extends IResource> next : myResourceTypes) {
|
||||
RuntimeResourceDefinition nextDef = (RuntimeResourceDefinition) theClassToElementDefinitions.get(next);
|
||||
myValidChildNames.add(getElementName() + nextDef.getName());
|
||||
}
|
||||
|
||||
myValidChildNames = Collections.unmodifiableSet(myValidChildNames);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import java.io.IOException;
|
|||
import java.io.Reader;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
|
@ -14,46 +14,56 @@ import ca.uhn.fhir.parser.IParser;
|
|||
import ca.uhn.fhir.rest.client.ClientInvocationHandler;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
|
||||
|
||||
|
||||
public abstract class BaseResourceReference extends BaseElement {
|
||||
|
||||
private IResource myResource;
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseResourceReference.class);
|
||||
|
||||
/**
|
||||
* Gets the value(s) for <b>reference</b> (Relative, internal or absolute URL reference).
|
||||
* creating it if it does
|
||||
* not exist. Will not return <code>null</code>.
|
||||
*
|
||||
* <p>
|
||||
* <b>Definition:</b>
|
||||
* A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be version specific. Internal fragment references (start with '#') refer to contained resources
|
||||
* </p>
|
||||
*/
|
||||
* Gets the value(s) for <b>reference</b> (Relative, internal or absolute URL reference). creating it if it does not exist. Will not return <code>null</code>.
|
||||
*
|
||||
* <p>
|
||||
* <b>Definition:</b> A reference to a location at which the other resource is found. The reference may a relative reference, in which case it is relative to the service base URL, or an absolute
|
||||
* URL that resolves to the location where the resource is found. The reference may be version specific or not. If the reference is not to a FHIR RESTful server, then it should be assumed to be
|
||||
* version specific. Internal fragment references (start with '#') refer to contained resources
|
||||
* </p>
|
||||
*/
|
||||
public abstract StringDt getReference();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the referenced resource, fetching it <b>if it has not already been loaded</b>. This method invokes the HTTP client to retrieve the resource unless it has already been loaded, or was a
|
||||
* contained resource in which case it is simply returned.
|
||||
*/
|
||||
public IResource loadResource(IRestfulClient theClient) throws IOException {
|
||||
if (myResource != null) {
|
||||
return myResource;
|
||||
}
|
||||
|
||||
ourLog.debug("Loading resource at URL: {}", getReference().getValue());
|
||||
|
||||
|
||||
ourLog.debug("Loading resource at URL: {}", getResourceUrl());
|
||||
|
||||
HttpClient httpClient = theClient.getHttpClient();
|
||||
FhirContext context = theClient.getFhirContext();
|
||||
|
||||
HttpGet get = new HttpGet(getReference().getValue());
|
||||
|
||||
HttpGet get = new HttpGet(getResourceUrl());
|
||||
HttpResponse response = httpClient.execute(get);
|
||||
|
||||
// TODO: choose appropriate parser based on response CT
|
||||
IParser parser = context.newXmlParser();
|
||||
|
||||
Reader responseReader = ClientInvocationHandler.createReaderFromResponse(response);
|
||||
myResource = parser.parseResource(responseReader);
|
||||
|
||||
try {
|
||||
// TODO: choose appropriate parser based on response CT
|
||||
IParser parser = context.newXmlParser();
|
||||
|
||||
Reader responseReader = ClientInvocationHandler.createReaderFromResponse(response);
|
||||
myResource = parser.parseResource(responseReader);
|
||||
|
||||
} finally {
|
||||
if (response instanceof CloseableHttpResponse) {
|
||||
((CloseableHttpResponse) response).close();
|
||||
}
|
||||
}
|
||||
|
||||
return myResource;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getResourceUrl() {
|
||||
return getReference().getValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
package ca.uhn.fhir.model.dstu.composite;
|
||||
|
||||
public class DurationDt extends QuantityDt {
|
||||
|
||||
// TODO: implement restricions
|
||||
|
||||
// There SHALL be a code if there is a value and it SHALL be an expression of length. If system is present, it SHALL be UCUM.
|
||||
// (f:code or not(f:value)) and (not(exists(f:system)) or f:system/@value='http://unitsofmeasure.org')
|
||||
|
||||
}
|
|
@ -26,6 +26,13 @@ public class IdDt extends BasePrimitive<String> {
|
|||
public IdDt() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ID using a long
|
||||
*/
|
||||
public IdDt(long theId) {
|
||||
setValue(Long.toString(theId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new ID
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package ca.uhn.fhir.rest.server.operations;
|
||||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
|
@ -1,4 +1,4 @@
|
|||
package ca.uhn.fhir.rest.server.operations;
|
||||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
|
@ -1,4 +1,4 @@
|
|||
package ca.uhn.fhir.rest.server.parameters;
|
||||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
|
@ -1,4 +1,4 @@
|
|||
package ca.uhn.fhir.rest.server.operations;
|
||||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
|
@ -1,4 +1,4 @@
|
|||
package ca.uhn.fhir.rest.server.operations;
|
||||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
|
@ -1,4 +1,4 @@
|
|||
package ca.uhn.fhir.rest.server.parameters;
|
||||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
|
@ -1,4 +1,4 @@
|
|||
package ca.uhn.fhir.rest.server.operations;
|
||||
package ca.uhn.fhir.rest.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
|
@ -14,6 +14,7 @@ import java.util.Map;
|
|||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.entity.ContentType;
|
||||
|
||||
|
@ -68,6 +69,7 @@ public class ClientInvocationHandler implements InvocationHandler {
|
|||
GetClientInvocation clientInvocation = binding.invokeClient(theArgs);
|
||||
HttpRequestBase httpRequest = clientInvocation.asHttpRequest(myUrlBase);
|
||||
HttpResponse response = myClient.execute(httpRequest);
|
||||
try {
|
||||
|
||||
Reader reader = createReaderFromResponse(response);
|
||||
|
||||
|
@ -124,6 +126,11 @@ public class ClientInvocationHandler implements InvocationHandler {
|
|||
}
|
||||
|
||||
throw new IllegalStateException("Should not get here!");
|
||||
} finally {
|
||||
if (response instanceof CloseableHttpResponse) {
|
||||
((CloseableHttpResponse) response).close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Reader createReaderFromResponse(HttpResponse theResponse) throws IllegalStateException, IOException {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
package ca.uhn.fhir.rest.client.api;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.rest.server.operations.Metadata;
|
||||
import ca.uhn.fhir.rest.annotation.Metadata;
|
||||
|
||||
/**
|
||||
* Base interface for a client supporting the mandatory operations as defined by
|
||||
* the FHIR specification.
|
||||
*/
|
||||
public interface IMetadataClient extends IRestfulClient {
|
||||
public interface IBasicClient extends IRestfulClient {
|
||||
|
||||
/**
|
||||
* Returns the server conformance statement
|
|
@ -12,13 +12,13 @@ import ca.uhn.fhir.model.api.Bundle;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.annotation.ResourceDef;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.Metadata;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.client.GetClientInvocation;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.operations.Metadata;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
|
||||
public abstract class BaseMethodBinding {
|
||||
|
||||
|
|
|
@ -9,9 +9,9 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.rest.annotation.Optional;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.server.parameters.Optional;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Required;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
|
|
@ -11,8 +11,8 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.dstu.resource.Profile;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
|
||||
public class ProfileProvider implements IResourceProvider {
|
||||
|
||||
|
|
|
@ -6,15 +6,15 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.client.api.IRestfulClient;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
|
||||
//START SNIPPET: provider
|
||||
/**
|
||||
* All RESTful clients must be an interface which extends IRestfulClient
|
||||
* All RESTful clients must be an interface which extends IBasicClient
|
||||
*/
|
||||
public interface RestfulClientImpl extends IRestfulClient {
|
||||
public interface RestfulClientImpl extends IBasicClient {
|
||||
|
||||
/**
|
||||
* The "@Read" annotation indicates that this method supports the
|
||||
|
|
|
@ -10,9 +10,9 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
|
||||
//START SNIPPET: provider
|
||||
/**
|
||||
|
|
|
@ -10,9 +10,9 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
|
||||
//START SNIPPET: provider
|
||||
/**
|
||||
|
|
|
@ -9,11 +9,11 @@ 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.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.Optional;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.server.IResourceProvider;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Optional;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class RestfulPatientResourceProviderMore implements IResourceProvider {
|
||||
|
|
|
@ -43,16 +43,16 @@ public class ClientTest {
|
|||
public void before() {
|
||||
ctx = new FhirContext(Patient.class, Conformance.class);
|
||||
clientFactory = ctx.newRestfulClientFactory();
|
||||
|
||||
|
||||
httpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
clientFactory.setHttpClient(httpClient);
|
||||
|
||||
|
||||
httpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRead() throws Exception {
|
||||
|
||||
|
||||
//@formatter:off
|
||||
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
|
||||
|
@ -64,26 +64,25 @@ public class ClientTest {
|
|||
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
|
||||
+ "</Patient>";
|
||||
//@formatter:on
|
||||
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), 200, "OK"));
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
|
||||
ITestClient client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
// Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
|
||||
// Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
|
||||
Patient response = client.getPatientById(new IdDt("111"));
|
||||
|
||||
|
||||
assertEquals("http://foo/Patient/111", capt.getValue().getURI().toString());
|
||||
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testVRead() throws Exception {
|
||||
|
||||
|
||||
//@formatter:off
|
||||
String msg = "<Patient xmlns=\"http://hl7.org/fhir\">"
|
||||
+ "<text><status value=\"generated\" /><div xmlns=\"http://www.w3.org/1999/xhtml\">John Cardinal: 444333333 </div></text>"
|
||||
|
@ -95,73 +94,74 @@ public class ClientTest {
|
|||
+ "<address><use value=\"home\" /><line value=\"2222 Home Street\" /></address><active value=\"true\" />"
|
||||
+ "</Patient>";
|
||||
//@formatter:on
|
||||
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), 200, "OK"));
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
|
||||
ITestClient client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
// Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
|
||||
// Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
|
||||
Patient response = client.getPatientByVersionId(new IdDt("111"), new IdDt("999"));
|
||||
|
||||
|
||||
assertEquals("http://foo/Patient/111/_history/999", capt.getValue().getURI().toString());
|
||||
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearchByToken() throws Exception {
|
||||
|
||||
|
||||
String msg = getPatientFeedWithOneResult();
|
||||
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), 200, "OK"));
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
|
||||
ITestClient client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
Patient response = client.findPatientByMrn(new IdentifierDt("urn:foo", "123"));
|
||||
|
||||
|
||||
assertEquals("http://foo/Patient?identifier=urn%3Afoo%7C123", capt.getValue().getURI().toString());
|
||||
assertEquals("PRP1660", response.getIdentifier().get(0).getValue().getValue());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetConformance() throws Exception {
|
||||
|
||||
|
||||
String msg = IOUtils.toString(ClientTest.class.getResourceAsStream("/example-metadata.xml"));
|
||||
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), 200, "OK"));
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
|
||||
ITestClient client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
Conformance response = client.getServerConformanceStatement();
|
||||
|
||||
|
||||
assertEquals("http://foo/metadata", capt.getValue().getURI().toString());
|
||||
assertEquals("Health Intersections", response.getPublisher().getValue());
|
||||
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchWithOptionalParam() throws Exception {
|
||||
|
||||
|
||||
String msg = getPatientFeedWithOneResult();
|
||||
|
||||
|
||||
ArgumentCaptor<HttpUriRequest> capt = ArgumentCaptor.forClass(HttpUriRequest.class);
|
||||
when(httpClient.execute(capt.capture())).thenReturn(httpResponse);
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), 200, "OK"));
|
||||
when(httpResponse.getStatusLine()).thenReturn(new BasicStatusLine(new ProtocolVersion("HTTP", 1, 1), 200, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML + "; charset=UTF-8"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
|
||||
|
||||
ITestClient client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
Bundle response = client.findPatientByName(new StringDt("AAA"), null);
|
||||
|
||||
|
||||
assertEquals("http://foo/Patient?family=AAA", capt.getValue().getURI().toString());
|
||||
Patient resource = (Patient) response.getEntries().get(0).getResource();
|
||||
assertEquals("PRP1660", resource.getIdentifier().get(0).getValue().getValue());
|
||||
|
@ -169,15 +169,15 @@ public class ClientTest {
|
|||
/*
|
||||
* Now with a first name
|
||||
*/
|
||||
|
||||
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ReaderInputStream(new StringReader(msg), Charset.forName("UTF-8")));
|
||||
client = clientFactory.newClient(ITestClient.class, "http://foo");
|
||||
response = client.findPatientByName(new StringDt("AAA"), new StringDt("BBB"));
|
||||
|
||||
|
||||
assertEquals("http://foo/Patient?family=AAA&given=BBB", capt.getValue().getURI().toString());
|
||||
resource = (Patient) response.getEntries().get(0).getResource();
|
||||
assertEquals("PRP1660", resource.getIdentifier().get(0).getValue().getValue());
|
||||
|
||||
|
||||
}
|
||||
|
||||
private String getPatientFeedWithOneResult() {
|
||||
|
|
|
@ -5,13 +5,13 @@ import ca.uhn.fhir.model.dstu.composite.IdentifierDt;
|
|||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.annotation.Optional;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.client.api.IMetadataClient;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Optional;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
|
||||
public interface ITestClient extends IMetadataClient {
|
||||
public interface ITestClient extends IBasicClient {
|
||||
|
||||
@Read(type=Patient.class)
|
||||
Patient getPatientById(@Read.IdParam IdDt theId);
|
||||
|
|
|
@ -13,10 +13,10 @@ import ca.uhn.fhir.model.dstu.valueset.IdentifierUseEnum;
|
|||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.annotation.Optional;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.server.operations.Search;
|
||||
import ca.uhn.fhir.rest.server.parameters.Optional;
|
||||
import ca.uhn.fhir.rest.server.parameters.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Required;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
|
||||
/**
|
||||
* Created by dsotnikov on 2/25/2014.
|
||||
|
|
|
@ -0,0 +1,302 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?><CarePlan xmlns="http://hl7.org/fhir" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://hl7.org/fhir ./fhir-single.xsd">
|
||||
<text>
|
||||
<status value="generated"/>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml">
|
||||
<p>Patient family is not ready to commit to goal setting at this time. Goal setting will be addressed in the future</p>
|
||||
</div>
|
||||
</text>
|
||||
<contained>
|
||||
<!-- Conditions could be further encoded and detailed.
|
||||
Could also be handled as references to external resources.
|
||||
And not essential to have them captured at all.
|
||||
For purposes of example, will represent this way. -->
|
||||
<Condition id="p1">
|
||||
<subject>
|
||||
<reference value="Patient/1"/>
|
||||
<display value="Eve Everywoman"/>
|
||||
</subject>
|
||||
<code>
|
||||
<text value="GERDS"/>
|
||||
</code>
|
||||
<status value="confirmed"/>
|
||||
</Condition>
|
||||
</contained>
|
||||
<contained>
|
||||
<Condition id="p2">
|
||||
<subject>
|
||||
<reference value="Patient/1"/>
|
||||
<display value="Eve Everywoman"/>
|
||||
</subject>
|
||||
<code>
|
||||
<text value="Obesity"/>
|
||||
</code>
|
||||
<status value="confirmed"/>
|
||||
</Condition>
|
||||
</contained>
|
||||
<contained>
|
||||
<Condition id="p3">
|
||||
<subject>
|
||||
<reference value="Patient/1"/>
|
||||
<display value="Eve Everywoman"/>
|
||||
</subject>
|
||||
<code>
|
||||
<text value="Psoriasis"/>
|
||||
</code>
|
||||
<status value="confirmed"/>
|
||||
</Condition>
|
||||
</contained>
|
||||
<patient>
|
||||
<reference value="Patient/1"/>
|
||||
<display value="Eve Everywoman"/>
|
||||
</patient>
|
||||
<status value="active"/>
|
||||
<modified value="2012-09-10"/>
|
||||
<concern>
|
||||
<reference value="#p1"/> <!-- Local reference -->
|
||||
<display value="GERDS"/>
|
||||
</concern>
|
||||
<concern>
|
||||
<reference value="#p2"/> <!-- Local reference -->
|
||||
<display value="Obesity"/>
|
||||
</concern>
|
||||
<concern>
|
||||
<reference value="#p3"/> <!-- Local reference -->
|
||||
<display value="Psoriasis"/>
|
||||
</concern>
|
||||
<goal id="g1">
|
||||
<description value="Eve will lose weight and reduce her GERDS symptoms by improving her diet"/>
|
||||
<status value="in progress"/>
|
||||
</goal>
|
||||
<goal id="g2">
|
||||
<description value="Eve will improve her GERDS symptoms"/>
|
||||
<status value="in progress"/>
|
||||
</goal>
|
||||
<goal id="g3">
|
||||
<description value="Eve will increase her energy by being more active"/>
|
||||
<status value="in progress"/>
|
||||
</goal>
|
||||
<goal id="g4">
|
||||
<description value="Eve will set up her medications and take as prescribed"/>
|
||||
<status value="in progress"/>
|
||||
</goal>
|
||||
<goal id="g5">
|
||||
<description value="Eve will restart her light treatments"/>
|
||||
<status value="in progress"/>
|
||||
</goal>
|
||||
<activity>
|
||||
<goal>g1</goal>
|
||||
<status value="not started"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="9/10/12 Eve eats one meal a day with her parents"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g1"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-09-10"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-09-10"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will review photos of high and low density foods and share with her parents"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="not started"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="9/10/12 Eve will sleep in her bed more often than the couch"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g1"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-09-10"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-09-10"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will ask her dad to asist her to put the head of her bed on blocks"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="in progress"/>
|
||||
<prohibited value="false"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g2"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-09-10"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-09-10"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will reduce her intake of coffee and chocolate"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="in progress"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="8/27/12 Eve would like to try for 5 days a week. 9/10/12 Eve is still walking the dogs."/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g3"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-09-10"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-08-27"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will walk her friend's dog up and down a big hill 15-30 minutes 3 days a week"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="in progress"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="8/13/12 Eve walked 4 times the last week. 9/10/12 Eve did not walk to her parents the last week, but has plans to start again"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g3"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-09-10"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-23"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will walk 3 blocks to her parents house twice a week"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="in progress"/>
|
||||
<prohibited value="false"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g4"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-08-13"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-23"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will us a calendar to check off after medications are taken"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="in progress"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="8/13/12 After restarting the vinegar soaks the psoriasis is improved and Eve plans to treat the remainder with light treatments. She plans to start this week. 8/27/12 Since her skin is improved Eve has not been using the light treatment as often, maybe once a week. She would like to increase to 3 times a week again"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g5"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-08-27"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-23"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will use her lights MWF after her shower for 3 minutes"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="in progress"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="7/23/12 Eve created a chart as a reminer to take the medications that do not fit in her pill box"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g4"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-09-10"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-10"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will use a calendar of a chart to help her remember when to take her medications"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="on hold"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="7/30/12 will be able to esume exercise. 8/13/12 Eve prefers to focus on walking at this time"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g3"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-08-23"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-23"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will start using stretch bands and one step 2 days a week Mon/Wed 6-7am and maybe Friday afternoon"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="completed"/>
|
||||
<prohibited value="false"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g4"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-07-23"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-10"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will match a printed medication worksheet with the medication bottles at home"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="completed"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="7/16/12 Eve now has some of her medications set up in pill packs by her pharmacist"/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g4"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-07-16"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-10"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will get a medication box to sort her pills. She will have one for scheduled medications and one for as needed"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<activity>
|
||||
<status value="cancelled"/>
|
||||
<prohibited value="false"/>
|
||||
<notes value="7/30/12 Eve will be able to resume exercise on 7/30/12. 8/13/12 -hold until "less busy""/>
|
||||
<simple>
|
||||
<extension url="http://example.org/DoNotUse/EnhancedCarePlan/ActivityGoalLink">
|
||||
<valueUri value="#g3"/>
|
||||
</extension>
|
||||
<extension url="http://example.org/DoNotUse/General/RevisionDate">
|
||||
<valueDate value="2012-08-13"/>
|
||||
</extension>
|
||||
<category value="other"/>
|
||||
<timingPeriod>
|
||||
<start value="2012-07-23"/>
|
||||
</timingPeriod>
|
||||
<details value="Eve will open "The Firm" DVD workout package and listen to it"/>
|
||||
</simple>
|
||||
</activity>
|
||||
<notes value="Patient family is not ready to commit to goal setting at this time. Goal setting will be addressed in the future"/>
|
||||
</CarePlan>
|
|
@ -1,8 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry excluding="**/*.java" kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry kind="src" path="target/gen"/>
|
||||
<classpathentry including="**/*.java" kind="src" path="src/main/java"/>
|
||||
<classpathentry excluding="**/*.java" kind="src" path="src/main/resources"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/hapi-fhir-base"/>
|
||||
<classpathentry kind="var" path="M2_REPO/javax/enterprise/cdi-api/1.0/cdi-api-1.0.jar" sourcepath="M2_REPO/javax/enterprise/cdi-api/1.0/cdi-api-1.0-sources.jar">
|
||||
<attributes>
|
||||
<attribute name="javadoc_location" value="jar:file:/Users/james/.m2/repository/javax/enterprise/cdi-api/1.0/cdi-api-1.0-javadoc.jar!/"/>
|
||||
|
|
|
@ -72,6 +72,9 @@ public class ProfileParser extends BaseStructureParser {
|
|||
if (elemIdx == 0) {
|
||||
Resource resource = new Resource();
|
||||
resource.setProfile(theProfile.getIdentifier().getValue());
|
||||
if (resource.getProfile() == null) {
|
||||
resource.setProfile(theUrlTOThisProfile);
|
||||
}
|
||||
|
||||
for (StructureSearchParam nextParam : nextStructure.getSearchParam()) {
|
||||
SearchParameter param = new SearchParameter();
|
||||
|
|
|
@ -1,60 +1,171 @@
|
|||
package ca.uhn.fhir.tinder;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import static org.apache.commons.lang.StringUtils.defaultString;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.ParseException;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
|
||||
import ch.qos.logback.core.util.FileUtil;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance.Rest;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Profile;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulConformanceModeEnum;
|
||||
import ca.uhn.fhir.rest.client.IRestfulClientFactory;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.tinder.model.Extension;
|
||||
import ca.uhn.fhir.tinder.model.Resource;
|
||||
import ca.uhn.fhir.tinder.model.RestResourceTm;
|
||||
|
||||
@Mojo(name = "generate-client", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
|
||||
public class TinderClientMojo extends AbstractMojo {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(TinderClientMojo.class);
|
||||
|
||||
@Parameter(alias = "clientClassName", required = true)
|
||||
private String myClientClassName;
|
||||
|
||||
@Parameter(alias = "targetDirectory", required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
|
||||
private File myTargetDirectory;
|
||||
|
||||
private List<RestResourceTm> myResources = new ArrayList<RestResourceTm>();
|
||||
|
||||
private String myPackageBase;
|
||||
|
||||
private File myDirectoryBase;
|
||||
|
||||
private String myClientClassSimpleName;
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoExecutionException, MojoFailureException {
|
||||
determinePaths();
|
||||
|
||||
}
|
||||
FhirContext ctx = new FhirContext(Conformance.class);
|
||||
IRestfulClientFactory cFact = ctx.newRestfulClientFactory();
|
||||
IBasicClient client = cFact.newClient(IBasicClient.class, "http://fhir.healthintersections.com.au/open");
|
||||
|
||||
Conformance conformance = client.getServerConformanceStatement();
|
||||
|
||||
public static void main(String[] args) throws ParseException, IOException, MojoFailureException {
|
||||
|
||||
// PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
// HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
// builder.setConnectionManager(connectionManager);
|
||||
// CloseableHttpClient client = builder.build();
|
||||
//
|
||||
// HttpGet get = new HttpGet("http://fhir.healthintersections.com.au/open/metadata");
|
||||
// CloseableHttpResponse response = client.execute(get);
|
||||
//
|
||||
// String metadataString = EntityUtils.toString(response.getEntity());
|
||||
//
|
||||
// ourLog.info("Metadata String: {}", metadataString);
|
||||
|
||||
String metadataString = IOUtils.toString(new FileInputStream("src/test/resources/healthintersections-metadata.xml"));
|
||||
Conformance conformance = new FhirContext(Conformance.class).newXmlParser().parseResource(Conformance.class, metadataString);
|
||||
|
||||
if (conformance.getRest().size() != 1) {
|
||||
throw new MojoFailureException("Found "+conformance.getRest().size()+" rest definitions in Conformance resource. Need exactly 1.");
|
||||
throw new MojoFailureException("Found " + conformance.getRest().size() + " rest definitions in Conformance resource. Need exactly 1.");
|
||||
}
|
||||
|
||||
Rest rest = conformance.getRest().get(0);
|
||||
if (rest.getMode().getValueAsEnum() != RestfulConformanceModeEnum.SERVER) {
|
||||
throw new MojoFailureException("Conformance mode is not server, found: " + rest.getMode().getValue());
|
||||
}
|
||||
|
||||
for (RestResource nextResource : rest.getResource()) {
|
||||
RestResourceTm nextTmResource = new RestResourceTm(nextResource);
|
||||
myResources.add(nextTmResource);
|
||||
|
||||
Profile profile;
|
||||
try {
|
||||
ourLog.info("Loading Profile: {}", nextResource.getProfile().getResourceUrl());
|
||||
profile = (Profile)nextResource.getProfile().loadResource(client);
|
||||
} catch (IOException e) {
|
||||
throw new MojoFailureException("Failed to load resource profile: "+nextResource.getProfile().getReference().getValue(),e);
|
||||
}
|
||||
|
||||
ProfileParser pp = new ProfileParser();
|
||||
try {
|
||||
pp.parseSingleProfile(profile, nextResource.getProfile().getResourceUrl());
|
||||
File resourceDir = new File(myDirectoryBase, "resource");
|
||||
resourceDir.mkdirs();
|
||||
pp.writeAll(resourceDir, myPackageBase);
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to load resource profile: "+nextResource.getProfile().getReference().getValue(),e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
try {
|
||||
write();
|
||||
} catch (IOException e) {
|
||||
throw new MojoFailureException("Failed to write", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void determinePaths() {
|
||||
myPackageBase = "";
|
||||
myDirectoryBase = myTargetDirectory;
|
||||
myClientClassSimpleName = myClientClassName;
|
||||
if (myClientClassName.lastIndexOf('.') > -1) {
|
||||
myPackageBase = myClientClassName.substring(0, myClientClassName.lastIndexOf('.'));
|
||||
myDirectoryBase = new File(myDirectoryBase, myPackageBase.replace(".", File.separatorChar+""));
|
||||
myClientClassSimpleName = myClientClassName.substring(myClientClassName.lastIndexOf('.')+1);
|
||||
}
|
||||
|
||||
|
||||
myDirectoryBase.mkdirs();
|
||||
}
|
||||
|
||||
private void write() throws IOException {
|
||||
File file = new File(myDirectoryBase, myClientClassSimpleName + ".java");
|
||||
FileWriter w = new FileWriter(file, false);
|
||||
|
||||
ourLog.info("Writing file: {}", file.getAbsolutePath());
|
||||
|
||||
VelocityContext ctx = new VelocityContext();
|
||||
ctx.put("packageBase", myPackageBase);
|
||||
ctx.put("className", myClientClassSimpleName);
|
||||
ctx.put("resources", myResources);
|
||||
|
||||
VelocityEngine v = new VelocityEngine();
|
||||
v.setProperty("resource.loader", "cp");
|
||||
v.setProperty("cp.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
||||
v.setProperty("runtime.references.strict", Boolean.TRUE);
|
||||
|
||||
InputStream templateIs = ResourceGeneratorUsingSpreadsheet.class.getResourceAsStream("/vm/client.vm");
|
||||
InputStreamReader templateReader = new InputStreamReader(templateIs);
|
||||
v.evaluate(ctx, w, "", templateReader);
|
||||
|
||||
w.close();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ParseException, IOException, MojoFailureException, MojoExecutionException {
|
||||
|
||||
// PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(5000, TimeUnit.MILLISECONDS);
|
||||
// HttpClientBuilder builder = HttpClientBuilder.create();
|
||||
// builder.setConnectionManager(connectionManager);
|
||||
// CloseableHttpClient client = builder.build();
|
||||
//
|
||||
// HttpGet get = new HttpGet("http://fhir.healthintersections.com.au/open/metadata");
|
||||
// CloseableHttpResponse response = client.execute(get);
|
||||
//
|
||||
// String metadataString = EntityUtils.toString(response.getEntity());
|
||||
//
|
||||
// ourLog.info("Metadata String: {}", metadataString);
|
||||
|
||||
// String metadataString = IOUtils.toString(new FileInputStream("src/test/resources/healthintersections-metadata.xml"));
|
||||
// Conformance conformance = new FhirContext(Conformance.class).newXmlParser().parseResource(Conformance.class, metadataString);
|
||||
|
||||
TinderClientMojo mojo = new TinderClientMojo();
|
||||
mojo.myClientClassName = "ca.uhn.test.ClientClass";
|
||||
mojo.myTargetDirectory = new File("target/gen");
|
||||
mojo.execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -82,14 +82,14 @@ public class Child extends BaseElement {
|
|||
}
|
||||
|
||||
if (this.isRepeatable()) {
|
||||
retVal = ("List<" + retVal + ">");
|
||||
retVal = ("java.util.List<" + retVal + ">");
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
public String getReferenceTypeForConstructor() {
|
||||
return getReferenceType().replaceAll("^List<", "ArrayList<");
|
||||
return getReferenceType().replaceAll("^java.util.List<", "java.util.ArrayList<");
|
||||
}
|
||||
|
||||
public List<String> getReferenceTypesForMultiple() {
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
package ca.uhn.fhir.tinder.model;
|
||||
|
||||
public class RestResource {
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package ca.uhn.fhir.tinder.model;
|
||||
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.apache.commons.lang.WordUtils;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResourceOperation;
|
||||
|
||||
public class RestResourceOperationTm {
|
||||
|
||||
private String myName;
|
||||
private String myDocumentation;
|
||||
|
||||
public RestResourceOperationTm(RestResourceOperation theOp) {
|
||||
myName = theOp.getCode().getValue();
|
||||
myDocumentation = theOp.getDocumentation().getValue();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
public boolean isHasDocumentation() {
|
||||
return StringUtils.isNotBlank(myDocumentation);
|
||||
}
|
||||
|
||||
public String getNameCapitalized() {
|
||||
return WordUtils.capitalize(myName);
|
||||
}
|
||||
|
||||
public String getDocumentation() {
|
||||
return myDocumentation;
|
||||
}
|
||||
|
||||
public void setName(String theName) {
|
||||
myName = theName;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package ca.uhn.fhir.tinder.model;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance.RestResourceOperation;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||
|
||||
public class RestResourceTm {
|
||||
|
||||
private String myResourceType;
|
||||
private Map<RestfulOperationTypeEnum, RestResourceOperationTm> mySupportedOperations = new HashMap<RestfulOperationTypeEnum, RestResourceOperationTm>();
|
||||
|
||||
public RestResourceTm(RestResource theResource) {
|
||||
myResourceType = theResource.getType().getValue();
|
||||
Validate.notNull(myResourceType, "Found a resource definition in Conformance resource with no type (or an invalid type) specified: " + theResource.getType().getValue());
|
||||
|
||||
for (RestResourceOperation next : theResource.getOperation()) {
|
||||
mySupportedOperations.put(next.getCode().getValueAsEnum(), new RestResourceOperationTm(next));
|
||||
}
|
||||
}
|
||||
|
||||
public RestResourceOperationTm getReadOperation() {
|
||||
return mySupportedOperations.get(RestfulOperationTypeEnum.READ);
|
||||
}
|
||||
|
||||
public RestResourceOperationTm getVReadOperation() {
|
||||
return mySupportedOperations.get(RestfulOperationTypeEnum.VREAD);
|
||||
}
|
||||
|
||||
public RestResourceOperationTm getSearchOperation() {
|
||||
return mySupportedOperations.get(RestfulOperationTypeEnum.SEARCH_TYPE);
|
||||
}
|
||||
|
||||
public boolean isHasReadOperation() {
|
||||
return mySupportedOperations.containsKey(RestfulOperationTypeEnum.READ);
|
||||
}
|
||||
|
||||
public boolean isHasVReadOperation() {
|
||||
return mySupportedOperations.containsKey(RestfulOperationTypeEnum.VREAD);
|
||||
}
|
||||
|
||||
public boolean isHasSearchOperation() {
|
||||
return mySupportedOperations.containsKey(RestfulOperationTypeEnum.SEARCH_TYPE);
|
||||
}
|
||||
|
||||
public String getResourceType() {
|
||||
return myResourceType;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
package ${packageBase};
|
||||
|
||||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.dstu.composite.*;
|
||||
import ca.uhn.fhir.model.primitive.*;
|
||||
import ca.uhn.fhir.rest.annotation.*;
|
||||
import ca.uhn.fhir.rest.client.api.*;
|
||||
import ${packageBase}.resource.*;
|
||||
|
||||
/**
|
||||
* Restful Client Definition Class
|
||||
*/
|
||||
public interface ${className} extends IMetadataClient {
|
||||
|
||||
#foreach ( $resource in ${resources} )
|
||||
#if ( ${resource.hasReadOperation} )
|
||||
/**
|
||||
* Retrieves a single ${resource.resourceType} resource by
|
||||
* its ID.
|
||||
#if ( ${resource.readOperation.hasDocumentation} )
|
||||
* <p>
|
||||
* Documentation: ${resource.readOperation.documentation}
|
||||
* </p>
|
||||
#end
|
||||
* @param theId The ID to use.
|
||||
* @see See {@link IdDt} for examples of how to use the ID datatype
|
||||
* @see See the FHIR <a href="http://www.hl7.org/implement/standards/fhir/http.html#read">read operation</a> definition.
|
||||
*/
|
||||
@Read
|
||||
${resource.resourceType} get${resource.resourceType}ById(@Read.IdParam IdDt theId);
|
||||
|
||||
#end
|
||||
#if ( ${resource.hasVReadOperation} )
|
||||
/**
|
||||
* Retrieves a single ${resource.resourceType} resource by
|
||||
* its ID and version ID.
|
||||
#if ( ${resource.readOperation.hasDocumentation} )
|
||||
* <p>
|
||||
* Documentation: ${resource.readOperation.documentation}
|
||||
* </p>
|
||||
#end
|
||||
* @param theId The ID to use.
|
||||
* @param theVersionId The ID to use.
|
||||
* @see See {@link IdDt} for examples of how to use the ID datatype
|
||||
* @see See the FHIR <a href="http://www.hl7.org/implement/standards/fhir/http.html#read">read operation</a> definition.
|
||||
*/
|
||||
@Read
|
||||
${resource.resourceType} get${resource.resourceType}ById(@Read.IdParam IdDt theId, @Read.VersionIdParam IdDt theVersionId);
|
||||
|
||||
#end
|
||||
#end
|
||||
|
||||
}
|
|
@ -6,8 +6,9 @@ import java.util.*;
|
|||
import ca.uhn.fhir.model.api.*;
|
||||
import ca.uhn.fhir.model.api.annotation.*;
|
||||
import ca.uhn.fhir.model.primitive.*;
|
||||
import ${packageBase}.composite.*;
|
||||
import ${packageBase}.valueset.*;
|
||||
import ca.uhn.fhir.model.dstu.composite.*;
|
||||
|
||||
//import ${packageBase}.valueset.*;
|
||||
|
||||
/**
|
||||
* HAPI/FHIR <b>${className}</b> Resource
|
||||
|
|
Loading…
Reference in New Issue