Lots more JPA improvementsa
This commit is contained in:
parent
adde115c53
commit
2720e7d273
|
@ -149,8 +149,8 @@
|
|||
<version>9.1.1.v20140108</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
|
@ -290,7 +290,7 @@
|
|||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-linkcheck-plugin</artifactId>
|
||||
<version>1.1</version>
|
||||
</plugin>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</reporting>
|
||||
|
||||
|
@ -303,35 +303,14 @@
|
|||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-site-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
<skipDeploy>false</skipDeploy>
|
||||
</configuration>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
<skipDeploy>false</skipDeploy>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>first</id>
|
||||
<goals>
|
||||
<goal>update-file-header</goal>
|
||||
</goals>
|
||||
<phase>process-sources</phase>
|
||||
<configuration>
|
||||
<licenseName>apache_v2</licenseName>
|
||||
<canUpdateDescription>true</canUpdateDescription>
|
||||
<canUpdateCopyright>true</canUpdateCopyright>
|
||||
<roots>
|
||||
<root>src/main/java</root>
|
||||
</roots>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
|
@ -461,57 +440,6 @@
|
|||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<minmemory>128m</minmemory>
|
||||
<maxmemory>1g</maxmemory>
|
||||
<linksource>true</linksource>
|
||||
<verbose>false</verbose>
|
||||
<debug>false</debug>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<attach>false</attach>
|
||||
<descriptors>
|
||||
<descriptor>${project.basedir}/src/assembly/hapi-fhir-all.xml</descriptor>
|
||||
<!-- <descriptor>src/assembly/hapi-jdk14.xml</descriptor> -->
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<resources>
|
||||
<resource>
|
||||
|
@ -521,4 +449,86 @@
|
|||
</resources>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>DIST</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<minmemory>128m</minmemory>
|
||||
<maxmemory>1g</maxmemory>
|
||||
<linksource>true</linksource>
|
||||
<verbose>false</verbose>
|
||||
<debug>false</debug>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar-no-fork</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<version>2.4</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<attach>false</attach>
|
||||
<descriptors>
|
||||
<descriptor>${project.basedir}/src/assembly/hapi-fhir-all.xml</descriptor>
|
||||
<!-- <descriptor>src/assembly/hapi-jdk14.xml</descriptor> -->
|
||||
</descriptors>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>license-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>first</id>
|
||||
<goals>
|
||||
<goal>update-file-header</goal>
|
||||
</goals>
|
||||
<phase>process-sources</phase>
|
||||
<configuration>
|
||||
<licenseName>apache_v2</licenseName>
|
||||
<canUpdateDescription>true</canUpdateDescription>
|
||||
<canUpdateCopyright>true</canUpdateCopyright>
|
||||
<roots>
|
||||
<root>src/main/java</root>
|
||||
</roots>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
<action type="add">
|
||||
Transaction method now supported in servers
|
||||
</action>
|
||||
<action type="add">
|
||||
Support for Binary resources added (in servers, clients, parsers, etc.)
|
||||
</action>
|
||||
<action type="fix">
|
||||
Support for Query resources fixed (in parser)
|
||||
</action>
|
||||
</release>
|
||||
</body>
|
||||
</document>
|
||||
|
|
|
@ -42,6 +42,7 @@ import java.util.TreeSet;
|
|||
|
||||
import ca.uhn.fhir.model.api.BaseResourceReference;
|
||||
import ca.uhn.fhir.model.api.CodeableConceptElement;
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.api.ICodeEnum;
|
||||
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||
import ca.uhn.fhir.model.api.ICompositeElement;
|
||||
|
@ -164,10 +165,10 @@ class ModelScanner {
|
|||
@SuppressWarnings("unchecked")
|
||||
Class<? extends IElement> nextClass = (Class<? extends IElement>) Class.forName((String) nextValue);
|
||||
if (!IElement.class.isAssignableFrom(nextClass)) {
|
||||
ourLog.warn("Class is not assignable from " + IElement.class.getSimpleName()+": " + nextValue);
|
||||
ourLog.warn("Class is not assignable from " + IElement.class.getSimpleName() + ": " + nextValue);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
toScan.add(nextClass);
|
||||
} catch (ClassNotFoundException e) {
|
||||
ourLog.warn("Unknown class exception: " + nextValue, e);
|
||||
|
@ -182,7 +183,7 @@ class ModelScanner {
|
|||
// toScan.add(DecimalDt.class);
|
||||
// toScan.add(AttachmentDt.class);
|
||||
// toScan.add(ResourceReferenceDt.class);
|
||||
// toScan.add(QuantityDt.class);
|
||||
// toScan.add(QuantityDt.class);
|
||||
|
||||
do {
|
||||
for (Class<? extends IElement> nextClass : toScan) {
|
||||
|
@ -289,7 +290,12 @@ class ModelScanner {
|
|||
private void scanCompositeDatatype(Class<? extends ICompositeDatatype> theClass, DatatypeDef theDatatypeDefinition) {
|
||||
ourLog.debug("Scanning resource class: {}", theClass.getName());
|
||||
|
||||
RuntimeCompositeDatatypeDefinition resourceDef = new RuntimeCompositeDatatypeDefinition(theDatatypeDefinition, theClass);
|
||||
RuntimeCompositeDatatypeDefinition resourceDef;
|
||||
if (theClass.equals(ExtensionDt.class)) {
|
||||
resourceDef = new RuntimeExtensionDtDefinition(theDatatypeDefinition, theClass);
|
||||
} else {
|
||||
resourceDef = new RuntimeCompositeDatatypeDefinition(theDatatypeDefinition, theClass);
|
||||
}
|
||||
myClassToElementDefinitions.put(theClass, resourceDef);
|
||||
scanCompositeElementForChildren(theClass, resourceDef);
|
||||
}
|
||||
|
@ -376,9 +382,8 @@ class ModelScanner {
|
|||
}
|
||||
|
||||
/*
|
||||
* Anything that's marked as unknown is given a new ID that is <0 so
|
||||
* that it doesn't conflict wityh any given IDs and can be figured
|
||||
* out later
|
||||
* Anything that's marked as unknown is given a new ID that is <0 so that it doesn't conflict wityh any
|
||||
* given IDs and can be figured out later
|
||||
*/
|
||||
while (order == Child.ORDER_UNKNOWN && orderMap.containsKey(order)) {
|
||||
order--;
|
||||
|
@ -416,6 +421,14 @@ class ModelScanner {
|
|||
RuntimeChildChoiceDefinition def = new RuntimeChildChoiceDefinition(next, elementName, childAnnotation, descriptionAnnotation, choiceTypes);
|
||||
orderMap.put(order, def);
|
||||
|
||||
} else if (next.getType().equals(ExtensionDt.class)) {
|
||||
|
||||
RuntimeChildExtensionDt def = new RuntimeChildExtensionDt(next, elementName, childAnnotation, descriptionAnnotation);
|
||||
orderMap.put(order, def);
|
||||
if (IElement.class.isAssignableFrom(nextElementType)) {
|
||||
addScanAlso((Class<? extends IElement>) nextElementType);
|
||||
}
|
||||
|
||||
} else if (extensionAttr != null) {
|
||||
/*
|
||||
* Child is an extension
|
||||
|
@ -443,8 +456,8 @@ class ModelScanner {
|
|||
|
||||
} else if (IResourceBlock.class.isAssignableFrom(nextElementType)) {
|
||||
/*
|
||||
* Child is a resource block (i.e. a sub-tag within a resource)
|
||||
* TODO: do these have a better name according to HL7?
|
||||
* Child is a resource block (i.e. a sub-tag within a resource) TODO: do these have a better name
|
||||
* according to HL7?
|
||||
*/
|
||||
|
||||
Class<? extends IResourceBlock> blockDef = (Class<? extends IResourceBlock>) nextElementType;
|
||||
|
@ -452,7 +465,7 @@ class ModelScanner {
|
|||
RuntimeChildResourceBlockDefinition def = new RuntimeChildResourceBlockDefinition(next, childAnnotation, descriptionAnnotation, elementName, blockDef);
|
||||
orderMap.put(order, def);
|
||||
|
||||
} else if (IDatatype.class.equals(nextElementType)) {
|
||||
} else if (IDatatype.class.equals(nextElementType) || IElement.class.equals(nextElementType)) {
|
||||
|
||||
RuntimeChildAny def = new RuntimeChildAny(next, elementName, childAnnotation, descriptionAnnotation);
|
||||
orderMap.put(order, def);
|
||||
|
@ -575,8 +588,8 @@ class ModelScanner {
|
|||
SearchParamDefinition searchParam = nextField.getAnnotation(SearchParamDefinition.class);
|
||||
if (searchParam != null) {
|
||||
SearchParamTypeEnum paramType = SearchParamTypeEnum.valueOf(searchParam.type().toUpperCase());
|
||||
if (paramType ==null) {
|
||||
throw new ConfigurationException("Searc param "+searchParam.name()+" has an invalid type: "+searchParam.type());
|
||||
if (paramType == null) {
|
||||
throw new ConfigurationException("Searc param " + searchParam.name() + " has an invalid type: " + searchParam.type());
|
||||
}
|
||||
RuntimeSearchParam param = new RuntimeSearchParam(searchParam.name(), searchParam.description(), searchParam.path(), paramType);
|
||||
theResourceDef.addSearchParam(param);
|
||||
|
|
|
@ -44,8 +44,8 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
|
||||
public RuntimeChildChoiceDefinition(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation, List<Class<? extends IElement>> theChoiceTypes) {
|
||||
super(theField, theChildAnnotation, theDescriptionAnnotation, theElementName);
|
||||
|
||||
myChoiceTypes= Collections.unmodifiableList(theChoiceTypes);
|
||||
|
||||
myChoiceTypes = Collections.unmodifiableList(theChoiceTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -71,7 +71,7 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
@Override
|
||||
public BaseRuntimeElementDefinition<?> getChildByName(String theName) {
|
||||
assert myNameToChildDefinition.containsKey(theName);
|
||||
|
||||
|
||||
return myNameToChildDefinition.get(theName);
|
||||
}
|
||||
|
||||
|
@ -80,37 +80,37 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||
myNameToChildDefinition = new HashMap<String, BaseRuntimeElementDefinition<?>>();
|
||||
myDatatypeToElementName = new HashMap<Class<? extends IElement>, String>();
|
||||
myDatatypeToElementDefinition =new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>();
|
||||
|
||||
myDatatypeToElementDefinition = new HashMap<Class<? extends IElement>, BaseRuntimeElementDefinition<?>>();
|
||||
|
||||
for (Class<? extends IElement> next : myChoiceTypes) {
|
||||
|
||||
|
||||
String elementName;
|
||||
String alternateElementName=null;
|
||||
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);
|
||||
types.add((Class<? extends IResource>) next);
|
||||
nextDef = new RuntimeResourceReferenceDefinition(elementName, types);
|
||||
nextDef.sealAndInitialize(theClassToElementDefinitions);
|
||||
} else {
|
||||
nextDef = theClassToElementDefinitions.get(next);
|
||||
elementName = getElementName() + StringUtils.capitalize(nextDef.getName());
|
||||
}
|
||||
|
||||
|
||||
myNameToChildDefinition.put(elementName, nextDef);
|
||||
if (alternateElementName!=null) {
|
||||
if (alternateElementName != null) {
|
||||
myNameToChildDefinition.put(alternateElementName, nextDef);
|
||||
}
|
||||
myDatatypeToElementDefinition.put(next, nextDef);
|
||||
myDatatypeToElementName.put(next, elementName);
|
||||
}
|
||||
|
||||
|
||||
myNameToChildDefinition = Collections.unmodifiableMap(myNameToChildDefinition);
|
||||
myDatatypeToElementName=Collections.unmodifiableMap(myDatatypeToElementName);
|
||||
myDatatypeToElementDefinition=Collections.unmodifiableMap(myDatatypeToElementDefinition);
|
||||
|
||||
myDatatypeToElementName = Collections.unmodifiableMap(myDatatypeToElementName);
|
||||
myDatatypeToElementDefinition = Collections.unmodifiableMap(myDatatypeToElementDefinition);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -127,5 +127,4 @@ public class RuntimeChildChoiceDefinition extends BaseRuntimeDeclaredChildDefini
|
|||
return Collections.unmodifiableSet((myDatatypeToElementDefinition.keySet()));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package ca.uhn.fhir.context;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import ca.uhn.fhir.model.api.ExtensionDt;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
import ca.uhn.fhir.model.api.annotation.Description;
|
||||
|
||||
public class RuntimeChildExtensionDt extends RuntimeChildAny {
|
||||
|
||||
public RuntimeChildExtensionDt(Field theField, String theElementName, Child theChildAnnotation, Description theDescriptionAnnotation) {
|
||||
super(theField, theElementName, theChildAnnotation, theDescriptionAnnotation);
|
||||
}
|
||||
|
||||
public IElement newInstance() {
|
||||
return new ExtensionDt();
|
||||
}
|
||||
|
||||
}
|
|
@ -41,6 +41,7 @@ public class RuntimeCompositeDatatypeDefinition extends BaseRuntimeElementCompos
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecialization() {
|
||||
return mySpecialization;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
package ca.uhn.fhir.context;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.model.api.ICompositeDatatype;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
|
||||
public class RuntimeExtensionDtDefinition extends RuntimeCompositeDatatypeDefinition {
|
||||
|
||||
private List<BaseRuntimeChildDefinition> myChildren;
|
||||
|
||||
public RuntimeExtensionDtDefinition(DatatypeDef theDef, Class<? extends ICompositeDatatype> theImplementingClass) {
|
||||
super(theDef, theImplementingClass);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BaseRuntimeChildDefinition> getChildren() {
|
||||
return myChildren;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sealAndInitialize(Map<Class<? extends IElement>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {
|
||||
super.sealAndInitialize(theClassToElementDefinitions);
|
||||
|
||||
/*
|
||||
* The "url" child is a weird child because it is not parsed and encoded in the normal way,
|
||||
* so we exclude it here
|
||||
*/
|
||||
|
||||
List<BaseRuntimeChildDefinition> superChildren = super.getChildren();
|
||||
ArrayList<BaseRuntimeChildDefinition> children = new ArrayList<BaseRuntimeChildDefinition>();
|
||||
for (BaseRuntimeChildDefinition baseRuntimeChildDefinition : superChildren) {
|
||||
if (baseRuntimeChildDefinition.getValidChildNames().contains("url")) {
|
||||
continue;
|
||||
}
|
||||
children.add(baseRuntimeChildDefinition);
|
||||
}
|
||||
|
||||
myChildren = Collections.unmodifiableList(children);
|
||||
}
|
||||
|
||||
}
|
|
@ -57,10 +57,12 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini
|
|||
private Profile myProfileDef;
|
||||
private String myResourceProfile;
|
||||
private List<RuntimeSearchParam> mySearchParams;
|
||||
private String myId;
|
||||
|
||||
public RuntimeResourceDefinition(Class<? extends IResource> theClass, ResourceDef theResourceAnnotation) {
|
||||
super(theResourceAnnotation.name(), theClass);
|
||||
myResourceProfile = theResourceAnnotation.profile();
|
||||
myId = theResourceAnnotation.id();
|
||||
}
|
||||
|
||||
public void addSearchParam(RuntimeSearchParam theParam) {
|
||||
|
@ -313,8 +315,15 @@ public class RuntimeResourceDefinition extends BaseRuntimeElementCompositeDefini
|
|||
}
|
||||
|
||||
Profile retVal = new Profile();
|
||||
|
||||
RuntimeResourceDefinition def = this;
|
||||
|
||||
if (StringUtils.isNotBlank(myId)) {
|
||||
retVal.setId(myId);
|
||||
}else {
|
||||
throw new ConfigurationException("Resource class " + getImplementingClass().getCanonicalName() + " has no ID specified");
|
||||
}
|
||||
|
||||
// Scan for extensions
|
||||
scanForExtensions(retVal, def);
|
||||
Collections.sort(retVal.getExtensionDefn(), new Comparator<ExtensionDefn>() {
|
||||
|
|
|
@ -116,6 +116,11 @@ public abstract class BaseElement implements IIdentifiableElement, ISupportsUnde
|
|||
myId = theId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String theId) {
|
||||
myId = new IdDt(theId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Intended to be called by extending classes {@link #isEmpty()}
|
||||
* implementations, returns <code>true</code> if all content in this
|
||||
|
|
|
@ -20,16 +20,26 @@ package ca.uhn.fhir.model.api;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.model.primitive.IntegerDt;
|
||||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.util.ElementUtil;
|
||||
|
||||
public class Bundle extends BaseBundle /*implements IElement*/ {
|
||||
|
||||
public class Bundle extends BaseBundle /* implements IElement */{
|
||||
|
||||
//@formatter:off
|
||||
/* ****************************************************
|
||||
* NB: add any new fields to the isEmpty() method!!!
|
||||
|
@ -73,6 +83,14 @@ public class Bundle extends BaseBundle /*implements IElement*/ {
|
|||
return myEntries;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
b.append(getEntries().size() + " entries");
|
||||
b.append("id", getId());
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public StringDt getBundleId() {
|
||||
if (myBundleId == null) {
|
||||
myBundleId = new StringDt();
|
||||
|
@ -179,7 +197,7 @@ public class Bundle extends BaseBundle /*implements IElement*/ {
|
|||
public <T extends IResource> List<T> getResources(Class<T> theClass) {
|
||||
ArrayList<T> retVal = new ArrayList<T>();
|
||||
for (BundleEntry next : getEntries()) {
|
||||
if (next.getResource()!=null && theClass.isAssignableFrom(next.getResource().getClass())) {
|
||||
if (next.getResource() != null && theClass.isAssignableFrom(next.getResource().getClass())) {
|
||||
@SuppressWarnings("unchecked")
|
||||
T resource = (T) next.getResource();
|
||||
retVal.add(resource);
|
||||
|
@ -188,4 +206,90 @@ public class Bundle extends BaseBundle /*implements IElement*/ {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new entry using the given resource and populates it accordingly
|
||||
*
|
||||
* @param theResource
|
||||
* The resource to add
|
||||
*/
|
||||
public void addResource(IResource theResource, FhirContext theContext, String theServerBase) {
|
||||
BundleEntry entry = addEntry();
|
||||
entry.setResource(theResource);
|
||||
|
||||
entry.setResource(theResource);
|
||||
TagList list = (TagList) theResource.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
|
||||
if (list != null) {
|
||||
for (Tag tag : list) {
|
||||
if (StringUtils.isNotBlank(tag.getTerm())) {
|
||||
entry.addCategory().setTerm(tag.getTerm()).setLabel(tag.getLabel()).setScheme(tag.getScheme());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition def = theContext.getResourceDefinition(theResource);
|
||||
|
||||
if (theResource.getId() != null && StringUtils.isNotBlank(theResource.getId().getValue())) {
|
||||
entry.getTitle().setValue(def.getName() + " " + theResource.getId().getValue());
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(theServerBase);
|
||||
if (b.length() > 0 && b.charAt(b.length() - 1) != '/') {
|
||||
b.append('/');
|
||||
}
|
||||
b.append(def.getName());
|
||||
b.append('/');
|
||||
String resId = theResource.getId().getUnqualifiedId();
|
||||
b.append(resId);
|
||||
|
||||
entry.getId().setValue(b.toString());
|
||||
|
||||
if (isNotBlank(theResource.getId().getUnqualifiedVersionId())) {
|
||||
b.append('/');
|
||||
b.append(Constants.PARAM_HISTORY);
|
||||
b.append('/');
|
||||
b.append(theResource.getId().getUnqualifiedVersionId());
|
||||
} else {
|
||||
IdDt versionId = (IdDt) ResourceMetadataKeyEnum.VERSION_ID.get(theResource);
|
||||
if (versionId != null) {
|
||||
b.append('/');
|
||||
b.append(Constants.PARAM_HISTORY);
|
||||
b.append('/');
|
||||
b.append(versionId.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
entry.getLinkSelf().setValue(b.toString());
|
||||
}
|
||||
|
||||
InstantDt published = (InstantDt) ResourceMetadataKeyEnum.PUBLISHED.get(theResource);
|
||||
if (published == null) {
|
||||
entry.getPublished().setToCurrentTimeInLocalTimeZone();
|
||||
} else {
|
||||
entry.setPublished(published);
|
||||
}
|
||||
|
||||
InstantDt updated = (InstantDt) ResourceMetadataKeyEnum.UPDATED.get(theResource);
|
||||
if (updated != null) {
|
||||
entry.setUpdated(updated);
|
||||
}
|
||||
|
||||
InstantDt deleted = (InstantDt) ResourceMetadataKeyEnum.DELETED_AT.get(theResource);
|
||||
if (deleted != null) {
|
||||
entry.setDeleted(deleted);
|
||||
}
|
||||
|
||||
IdDt previous = (IdDt) ResourceMetadataKeyEnum.PREVIOUS_ID.get(theResource);
|
||||
if (previous != null) {
|
||||
entry.getLinkAlternate().setValue(previous.toQualifiedUrl(theServerBase, def.getName()));
|
||||
}
|
||||
|
||||
TagList tagList = (TagList) ResourceMetadataKeyEnum.TAG_LIST.get(theResource);
|
||||
if (tagList != null) {
|
||||
for (Tag nextTag : tagList) {
|
||||
entry.addCategory(nextTag);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ package ca.uhn.fhir.model.api;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
|
@ -50,6 +52,18 @@ public class BundleEntry extends BaseBundle {
|
|||
return retVal;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
ToStringBuilder b = new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE);
|
||||
if (getResource() != null) {
|
||||
b.append("type", getResource().getClass().getSimpleName());
|
||||
} else {
|
||||
b.append("No resource");
|
||||
}
|
||||
b.append("id", getId());
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public void addCategory(Tag theTag) {
|
||||
getCategories().add(theTag);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,9 @@ package ca.uhn.fhir.model.api;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.model.api.annotation.Child;
|
||||
|
@ -27,11 +30,11 @@ import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
|||
import ca.uhn.fhir.model.primitive.StringDt;
|
||||
|
||||
@DatatypeDef(name="Extension")
|
||||
public class ExtensionDt extends BaseElement {
|
||||
public class ExtensionDt extends BaseElement implements ICompositeDatatype {
|
||||
|
||||
private boolean myModifier;
|
||||
|
||||
@Child(name="use", type=StringDt.class, order=0, min=1, max=1)
|
||||
@Child(name="url", type=StringDt.class, order=0, min=1, max=1)
|
||||
private StringDt myUrl;
|
||||
|
||||
@Child(name="value", type=IDatatype.class, order=1, min=0, max=1)
|
||||
|
@ -68,7 +71,7 @@ public class ExtensionDt extends BaseElement {
|
|||
}
|
||||
|
||||
public String getUrlAsString() {
|
||||
return myUrl.getValue();
|
||||
return getUrl().getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,16 +113,23 @@ public class ExtensionDt extends BaseElement {
|
|||
myModifier = theModifier;
|
||||
}
|
||||
|
||||
public void setUrl(String theUrl) {
|
||||
public ExtensionDt setUrl(String theUrl) {
|
||||
myUrl = new StringDt(theUrl);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setUrl(StringDt theUrl) {
|
||||
public ExtensionDt setUrl(StringDt theUrl) {
|
||||
myUrl = theUrl;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setValue(IElement theValue) {
|
||||
myValue = theValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
|
||||
return new ArrayList<T>();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ package ca.uhn.fhir.model.api;
|
|||
public interface IElement {
|
||||
|
||||
boolean isEmpty();
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -24,9 +24,16 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
|
||||
public interface IIdentifiableElement extends IElement {
|
||||
|
||||
public void setId(IdDt theId);
|
||||
void setId(IdDt theId);
|
||||
|
||||
IdDt getId();
|
||||
|
||||
/**
|
||||
* Convenience method for {@link #setId(IdDt)} which creates a new IdDt and provides the
|
||||
* given string as the ID.
|
||||
*
|
||||
* @param theId The ID string. Can be a complete URL, a partial URL or even a simple identifier.
|
||||
*/
|
||||
void setId(String theId);
|
||||
|
||||
public IdDt getId();
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -20,11 +20,18 @@ package ca.uhn.fhir.model.api;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.model.primitive.InstantDt;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
|
||||
public enum ResourceMetadataKeyEnum {
|
||||
|
||||
|
||||
/**
|
||||
* If present and populated with a date/time (as an instance of {@link InstantDt}),
|
||||
* this value is an indication that the resource is in the deleted state. This key
|
||||
|
@ -34,7 +41,12 @@ public enum ResourceMetadataKeyEnum {
|
|||
* Values for this key are of type <b>{@link InstantDt}</b>
|
||||
* </p>
|
||||
*/
|
||||
DELETED_AT,
|
||||
DELETED_AT {
|
||||
@Override
|
||||
public InstantDt get(IResource theResource) {
|
||||
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), DELETED_AT);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The value for this key represents a previous ID used to identify
|
||||
|
@ -44,7 +56,12 @@ public enum ResourceMetadataKeyEnum {
|
|||
* Values for this key are of type <b>{@link IdDt}</b>
|
||||
* </p>
|
||||
*/
|
||||
PREVIOUS_ID,
|
||||
PREVIOUS_ID {
|
||||
@Override
|
||||
public IdDt get(IResource theResource) {
|
||||
return getIdFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PREVIOUS_ID);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The value for this key is the bundle entry <b>Published</b> time. This is
|
||||
|
@ -61,8 +78,14 @@ public enum ResourceMetadataKeyEnum {
|
|||
*
|
||||
* @see InstantDt
|
||||
*/
|
||||
PUBLISHED,
|
||||
PUBLISHED {
|
||||
@Override
|
||||
public InstantDt get(IResource theResource) {
|
||||
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PUBLISHED);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* The value for this key is the list of tags associated with this resource
|
||||
* <p>
|
||||
|
@ -71,7 +94,22 @@ public enum ResourceMetadataKeyEnum {
|
|||
*
|
||||
* @see TagList
|
||||
*/
|
||||
TAG_LIST,
|
||||
TAG_LIST {
|
||||
@Override
|
||||
public TagList get(IResource theResource) {
|
||||
Object retValObj = theResource.getResourceMetadata().get(TAG_LIST);
|
||||
if (retValObj == null) {
|
||||
return null;
|
||||
} else if (retValObj instanceof TagList) {
|
||||
if (((TagList) retValObj).isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return (TagList) retValObj;
|
||||
}
|
||||
}
|
||||
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + TAG_LIST.name() + " - Expected " + TagList.class.getCanonicalName());
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
|
@ -85,7 +123,12 @@ public enum ResourceMetadataKeyEnum {
|
|||
*
|
||||
* @see InstantDt
|
||||
*/
|
||||
UPDATED,
|
||||
UPDATED {
|
||||
@Override
|
||||
public InstantDt get(IResource theResource) {
|
||||
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), UPDATED);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The value for this key is the version ID of the resource object.
|
||||
|
@ -96,6 +139,49 @@ public enum ResourceMetadataKeyEnum {
|
|||
* @deprecated The {@link IResource#getId()} resource ID will now be populated with the version ID via the {@link IdDt#getUnqualifiedVersionId()} method
|
||||
*/
|
||||
@Deprecated
|
||||
VERSION_ID;
|
||||
VERSION_ID {
|
||||
@Override
|
||||
public IdDt get(IResource theResource) {
|
||||
return getIdFromMetadataOrNullIfNone(theResource.getResourceMetadata(), VERSION_ID);
|
||||
}
|
||||
};
|
||||
|
||||
public abstract Object get(IResource theResource);
|
||||
|
||||
private static IdDt getIdFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum, Object> theResourceMetadata, ResourceMetadataKeyEnum theKey) {
|
||||
Object retValObj = theResourceMetadata.get(theKey);
|
||||
if (retValObj == null) {
|
||||
return null;
|
||||
} else if (retValObj instanceof String) {
|
||||
if (isNotBlank((String) retValObj)) {
|
||||
return new IdDt((String) retValObj);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (retValObj instanceof IdDt) {
|
||||
if (((IdDt) retValObj).isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return (IdDt) retValObj;
|
||||
}
|
||||
}
|
||||
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + IdDt.class.getCanonicalName());
|
||||
}
|
||||
|
||||
private static InstantDt getInstantFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum, Object> theResourceMetadata, ResourceMetadataKeyEnum theKey) {
|
||||
Object retValObj = theResourceMetadata.get(theKey);
|
||||
if (retValObj == null) {
|
||||
return null;
|
||||
} else if (retValObj instanceof Date) {
|
||||
return new InstantDt((Date) retValObj);
|
||||
} else if (retValObj instanceof InstantDt) {
|
||||
if (((InstantDt) retValObj).isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return (InstantDt) retValObj;
|
||||
}
|
||||
}
|
||||
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + InstantDt.class.getCanonicalName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -60,4 +60,9 @@ public class ContainedDt implements IDatatype {
|
|||
public IdDt getId() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String theId) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,26 @@ public class Binary extends BaseResource implements IResource {
|
|||
private Base64BinaryDt myContent = new Base64BinaryDt();
|
||||
private String myContentType;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public Binary() {
|
||||
// nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param theContentType
|
||||
* The content type
|
||||
* @param theContent
|
||||
* The binary contents
|
||||
*/
|
||||
public Binary(String theContentType, byte[] theContent) {
|
||||
setContentType(theContentType);
|
||||
setContent(theContent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends IElement> List<T> getAllPopulatedChildElementsOfType(Class<T> theType) {
|
||||
return Collections.emptyList();
|
||||
|
|
|
@ -22,8 +22,10 @@ package ca.uhn.fhir.model.primitive;
|
|||
|
||||
import ca.uhn.fhir.model.api.BasePrimitive;
|
||||
import ca.uhn.fhir.model.api.IElement;
|
||||
import ca.uhn.fhir.model.api.annotation.DatatypeDef;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
||||
@DatatypeDef(name = "idref")
|
||||
public class IdrefDt extends BasePrimitive<String> {
|
||||
|
||||
private IElement myTarget;
|
||||
|
|
|
@ -263,6 +263,9 @@ public class JsonParser extends BaseParser implements IParser {
|
|||
} else {
|
||||
theWriter.writeStartObject();
|
||||
}
|
||||
if (theValue instanceof ExtensionDt) {
|
||||
theWriter.write("url", ((ExtensionDt) theValue).getUrlAsString());
|
||||
}
|
||||
encodeCompositeElementToStreamWriter(theResDef, theResource, theValue, theWriter, childCompositeDef);
|
||||
theWriter.writeEnd();
|
||||
break;
|
||||
|
|
|
@ -862,6 +862,8 @@ class ParserState<T> {
|
|||
public void attributeValue(String theName, String theValue) throws DataFormatException {
|
||||
if ("id".equals(theName)) {
|
||||
myInstance.setId(new IdDt(theValue));
|
||||
} else if ("url".equals(theName) && myInstance instanceof ExtensionDt) {
|
||||
((ExtensionDt)myInstance).setUrl(theValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -476,8 +476,13 @@ public class XmlParser extends BaseParser implements IParser {
|
|||
if (childDef == null) {
|
||||
super.throwExceptionForUnknownChildType(nextChild, type);
|
||||
}
|
||||
|
||||
if (extensionUrl != null && childName.equals("extension") == false) {
|
||||
|
||||
if (nextValue instanceof ExtensionDt) {
|
||||
|
||||
extensionUrl = ((ExtensionDt) nextValue).getUrlAsString();
|
||||
encodeChildElementToStreamWriter(theResDef, theResource, theEventWriter, nextValue, childName, childDef, extensionUrl, theIncludedResource);
|
||||
|
||||
} else if (extensionUrl != null && childName.equals("extension") == false) {
|
||||
RuntimeChildDeclaredExtensionDefinition extDef = (RuntimeChildDeclaredExtensionDefinition) nextChild;
|
||||
if (extDef.isModifier()) {
|
||||
theEventWriter.writeStartElement("modifierExtension");
|
||||
|
|
|
@ -20,7 +20,9 @@ package ca.uhn.fhir.rest.client;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.io.StringReader;
|
||||
|
@ -45,6 +47,7 @@ import org.apache.http.entity.ContentType;
|
|||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.rest.client.exceptions.FhirClientConnectionException;
|
||||
import ca.uhn.fhir.rest.method.IClientResponseHandler;
|
||||
import ca.uhn.fhir.rest.method.IClientResponseHandlerHandlesBinary;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.EncodingEnum;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
|
@ -125,28 +128,6 @@ public abstract class BaseClient {
|
|||
}
|
||||
|
||||
try {
|
||||
|
||||
Reader reader = createReaderFromResponse(response);
|
||||
|
||||
if (ourLog.isTraceEnabled() || myKeepResponses || theLogRequestAndResponse) {
|
||||
String responseString = IOUtils.toString(reader);
|
||||
if (myKeepResponses) {
|
||||
myLastResponse = response;
|
||||
myLastResponseBody = responseString;
|
||||
}
|
||||
if (theLogRequestAndResponse) {
|
||||
String message = "HTTP " + response.getStatusLine().getStatusCode()+" " +response.getStatusLine().getReasonPhrase();
|
||||
if (StringUtils.isNotBlank(responseString)) {
|
||||
ourLog.info("Client response: {}\n{}", message, responseString);
|
||||
}else {
|
||||
ourLog.info("Client response: {}", message, responseString);
|
||||
}
|
||||
}else {
|
||||
ourLog.trace("FHIR response:\n{}\n{}", response, responseString);
|
||||
}
|
||||
reader = new StringReader(responseString);
|
||||
}
|
||||
|
||||
ContentType ct = ContentType.get(response.getEntity());
|
||||
String mimeType = ct != null ? ct.getMimeType() : null;
|
||||
|
||||
|
@ -165,7 +146,9 @@ public abstract class BaseClient {
|
|||
|
||||
if (response.getStatusLine().getStatusCode() < 200 || response.getStatusLine().getStatusCode() > 299) {
|
||||
String body=null;
|
||||
Reader reader=null;
|
||||
try {
|
||||
reader = createReaderFromResponse(response);
|
||||
body = IOUtils.toString(reader);
|
||||
} catch (Exception e) {
|
||||
ourLog.debug("Failed to read input stream", e);
|
||||
|
@ -186,6 +169,54 @@ public abstract class BaseClient {
|
|||
|
||||
throw exception;
|
||||
}
|
||||
if (binding instanceof IClientResponseHandlerHandlesBinary) {
|
||||
IClientResponseHandlerHandlesBinary<T> handlesBinary = (IClientResponseHandlerHandlesBinary<T>) binding;
|
||||
if (handlesBinary.isBinary()) {
|
||||
InputStream reader = response.getEntity().getContent();
|
||||
try {
|
||||
|
||||
if (ourLog.isTraceEnabled() || myKeepResponses || theLogRequestAndResponse) {
|
||||
byte[] responseBytes = IOUtils.toByteArray(reader);
|
||||
if (myKeepResponses) {
|
||||
myLastResponse = response;
|
||||
myLastResponseBody = null;
|
||||
}
|
||||
String message = "HTTP " + response.getStatusLine().getStatusCode()+" " +response.getStatusLine().getReasonPhrase();
|
||||
if (theLogRequestAndResponse) {
|
||||
ourLog.info("Client response: {} - {} bytes", message, responseBytes.length);
|
||||
}else {
|
||||
ourLog.trace("Client response: {} - {} bytes", message, responseBytes.length);
|
||||
}
|
||||
reader = new ByteArrayInputStream(responseBytes);
|
||||
}
|
||||
|
||||
return handlesBinary.invokeClient(mimeType, reader, response.getStatusLine().getStatusCode(), headers);
|
||||
} finally {
|
||||
IOUtils.closeQuietly(reader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reader reader = createReaderFromResponse(response);
|
||||
|
||||
if (ourLog.isTraceEnabled() || myKeepResponses || theLogRequestAndResponse) {
|
||||
String responseString = IOUtils.toString(reader);
|
||||
if (myKeepResponses) {
|
||||
myLastResponse = response;
|
||||
myLastResponseBody = responseString;
|
||||
}
|
||||
if (theLogRequestAndResponse) {
|
||||
String message = "HTTP " + response.getStatusLine().getStatusCode()+" " +response.getStatusLine().getReasonPhrase();
|
||||
if (StringUtils.isNotBlank(responseString)) {
|
||||
ourLog.info("Client response: {}\n{}", message, responseString);
|
||||
}else {
|
||||
ourLog.info("Client response: {}", message, responseString);
|
||||
}
|
||||
}else {
|
||||
ourLog.trace("FHIR response:\n{}\n{}", response, responseString);
|
||||
}
|
||||
reader = new StringReader(responseString);
|
||||
}
|
||||
|
||||
try {
|
||||
return binding.invokeClient(mimeType, reader, response.getStatusLine().getStatusCode(), headers);
|
||||
|
|
|
@ -59,6 +59,7 @@ import ca.uhn.fhir.rest.method.HttpGetClientInvocation;
|
|||
import ca.uhn.fhir.rest.method.IClientResponseHandler;
|
||||
import ca.uhn.fhir.rest.method.ReadMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.SearchMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.TransactionMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.UpdateMethodBinding;
|
||||
import ca.uhn.fhir.rest.method.ValidateMethodBinding;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
@ -216,6 +217,18 @@ public class GenericClient extends BaseClient implements IGenericClient {
|
|||
return myContext.getResourceDefinition(theType).getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<IResource> transaction(List<IResource> theResources) {
|
||||
BaseHttpClientInvocation invocation = TransactionMethodBinding.createTransactionInvocation(theResources, myContext);
|
||||
if (isKeepResponses()) {
|
||||
myLastRequest = invocation.asHttpRequest(getServerBase(), createExtraParams(), getEncoding());
|
||||
}
|
||||
|
||||
Bundle resp = invokeClient(new BundleResponseHandler(null), invocation, myLogRequestAndResponse);
|
||||
|
||||
return resp.toListOfResources();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodOutcome update(IdDt theIdDt, IResource theResource) {
|
||||
BaseHttpClientInvocation invocation = UpdateMethodBinding.createUpdateInvocation(theResource, theIdDt, null, myContext);
|
||||
|
|
|
@ -47,6 +47,16 @@ public interface IGenericClient {
|
|||
*/
|
||||
MethodOutcome create(IResource theResource);
|
||||
|
||||
|
||||
/**
|
||||
* Implementation of the "transaction" method.
|
||||
*
|
||||
* @param theResources
|
||||
* The resources to create/update in a single transaction
|
||||
* @return A list of resource stubs (<b>these will not be fully populated</b>) containing IDs and other {@link IResource#getResourceMetadata() metadata}
|
||||
*/
|
||||
List<IResource> transaction(List<IResource> theResources);
|
||||
|
||||
/**
|
||||
* Implementation of the "delete instance" method.
|
||||
*
|
||||
|
|
|
@ -168,7 +168,7 @@ public abstract class BaseAddOrDeleteTagsMethodBinding extends BaseMethodBinding
|
|||
}
|
||||
|
||||
IParser parser = createAppropriateParserForParsingServerRequest(theRequest);
|
||||
Reader reader = theRequest.getInputReader();
|
||||
Reader reader = theRequest.getServletRequest().getReader();
|
||||
try {
|
||||
TagList tagList = parser.parseTagList(reader);
|
||||
params[myTagListParamIndex] = tagList;
|
||||
|
|
|
@ -25,6 +25,8 @@ import java.util.Map;
|
|||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.entity.AbstractHttpEntity;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
|
||||
|
@ -32,6 +34,7 @@ import ca.uhn.fhir.context.FhirContext;
|
|||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
import ca.uhn.fhir.parser.IParser;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
|
@ -88,7 +91,15 @@ public abstract class BaseHttpClientInvocationWithContents extends BaseHttpClien
|
|||
b.append(StringUtils.defaultString(myUrlExtension));
|
||||
|
||||
appendExtraParamsWithQuestionMark(theExtraParams, b, true);
|
||||
String url = b.toString();
|
||||
|
||||
if (myResource != null && Binary.class.isAssignableFrom(myResource.getClass())) {
|
||||
Binary binary = (Binary)myResource;
|
||||
ByteArrayEntity entity = new ByteArrayEntity(binary.getContent(), ContentType.parse(binary.getContentType()));
|
||||
HttpRequestBase retVal = createRequest(url, entity);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
IParser parser;
|
||||
String contentType;
|
||||
if (theEncoding == EncodingEnum.JSON) {
|
||||
|
@ -111,11 +122,11 @@ public abstract class BaseHttpClientInvocationWithContents extends BaseHttpClien
|
|||
|
||||
StringEntity entity = new StringEntity(contents, ContentType.create(contentType, "UTF-8"));
|
||||
|
||||
HttpRequestBase retVal = createRequest(b.toString(), entity);
|
||||
HttpRequestBase retVal = createRequest(url, entity);
|
||||
super.addHeadersToRequest(retVal);
|
||||
return retVal;
|
||||
}
|
||||
|
||||
protected abstract HttpRequestBase createRequest(String url, StringEntity theEntity);
|
||||
protected abstract HttpRequestBase createRequest(String url, AbstractHttpEntity theEntity);
|
||||
|
||||
}
|
||||
|
|
|
@ -191,11 +191,13 @@ public abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBindin
|
|||
// getMethod().in
|
||||
}
|
||||
|
||||
private IResource parseIncomingServerResource(Request theRequest) {
|
||||
IResource resource;
|
||||
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest);
|
||||
/**
|
||||
* @throws IOException
|
||||
*/
|
||||
protected IResource parseIncomingServerResource(Request theRequest) throws IOException {
|
||||
EncodingEnum encoding = RestfulServer.determineRequestEncoding(theRequest);
|
||||
IParser parser = encoding.newParser(getContext());
|
||||
resource = parser.parseResource(theRequest.getInputReader());
|
||||
IResource resource = parser.parseResource(theRequest.getServletRequest().getReader());
|
||||
return resource;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,10 @@ package ca.uhn.fhir.rest.method;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
|
@ -30,6 +32,9 @@ import ca.uhn.fhir.model.api.IResource;
|
|||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
|
||||
import ca.uhn.fhir.model.api.Tag;
|
||||
import ca.uhn.fhir.model.api.TagList;
|
||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
|
||||
import ca.uhn.fhir.rest.param.IParameter;
|
||||
|
@ -41,6 +46,7 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||
abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOutcomeReturningMethodBinding {
|
||||
private int myResourceParameterIndex;
|
||||
private String myResourceName;
|
||||
private boolean myBinary;
|
||||
|
||||
public BaseOutcomeReturningMethodBindingWithResourceParam(Method theMethod, FhirContext theContext, Class<?> theMethodAnnotation, Object theProvider) {
|
||||
super(theMethod, theContext, theMethodAnnotation, theProvider);
|
||||
|
@ -57,6 +63,10 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
|
|||
resourceType=((IResourceProvider) theProvider).getResourceType();
|
||||
}
|
||||
|
||||
if (resourceType.isAssignableFrom(Binary.class)) {
|
||||
myBinary = true;
|
||||
}
|
||||
|
||||
myResourceName = theContext.getResourceDefinition(resourceType).getName();
|
||||
|
||||
myResourceParameterIndex = index;
|
||||
|
@ -70,6 +80,29 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
|
|||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected IResource parseIncomingServerResource(Request theRequest) throws IOException {
|
||||
if (myBinary) {
|
||||
String ct = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_TYPE);
|
||||
byte[] contents = IOUtils.toByteArray(theRequest.getServletRequest().getInputStream());
|
||||
return new Binary(ct, contents);
|
||||
}else {
|
||||
return super.parseIncomingServerResource(theRequest);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestfulOperationTypeEnum getResourceOperationType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RestfulOperationSystemEnum getSystemOperationType() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For subclasses to override
|
||||
*/
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.util.UUID;
|
|||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.client.utils.DateUtils;
|
||||
|
||||
|
@ -255,6 +256,12 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
NarrativeModeEnum theNarrativeMode) throws IOException {
|
||||
assert !theServerBase.endsWith("/");
|
||||
|
||||
for (IResource next : theResult) {
|
||||
if (next.getId() == null || next.getId().isEmpty()) {
|
||||
throw new InternalErrorException("Server method returned resource of type[" + next.getClass().getSimpleName() + "] with no ID specified (IResource#setId(IdDt) must be called)");
|
||||
}
|
||||
}
|
||||
|
||||
theHttpResponse.setStatus(200);
|
||||
|
||||
if (theRequestIsBrowser && theServer.isUseBrowserFriendlyContentTypes()) {
|
||||
|
@ -318,7 +325,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
|
||||
theServer.addHeadersToResponse(theHttpResponse);
|
||||
|
||||
InstantDt lastUpdated = getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), ResourceMetadataKeyEnum.UPDATED);
|
||||
InstantDt lastUpdated = (InstantDt) ResourceMetadataKeyEnum.UPDATED.get(theResource);
|
||||
if (lastUpdated != null) {
|
||||
theHttpResponse.addHeader(Constants.HEADER_LAST_MODIFIED, lastUpdated.getValueAsString());
|
||||
}
|
||||
|
@ -348,7 +355,7 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
/**
|
||||
* Subclasses may override
|
||||
*/
|
||||
protected Object parseRequestObject(@SuppressWarnings("unused") Request theRequest) {
|
||||
protected Object parseRequestObject(@SuppressWarnings("unused") Request theRequest) throws IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -361,154 +368,14 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
|
|||
bundle.getLinkSelf().setValue(theCompleteUrl);
|
||||
|
||||
for (IResource next : theResult) {
|
||||
BundleEntry entry = new BundleEntry();
|
||||
bundle.getEntries().add(entry);
|
||||
|
||||
entry.setResource(next);
|
||||
TagList list = (TagList) next.getResourceMetadata().get(ResourceMetadataKeyEnum.TAG_LIST);
|
||||
if (list != null) {
|
||||
for (Tag tag : list) {
|
||||
if (StringUtils.isNotBlank(tag.getTerm())) {
|
||||
entry.addCategory().setTerm(tag.getTerm()).setLabel(tag.getLabel()).setScheme(tag.getScheme());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition def = theContext.getResourceDefinition(next);
|
||||
|
||||
if (next.getId() != null && StringUtils.isNotBlank(next.getId().getValue())) {
|
||||
entry.getTitle().setValue(def.getName() + " " + next.getId().getValue());
|
||||
|
||||
StringBuilder b = new StringBuilder();
|
||||
b.append(theServerBase);
|
||||
if (b.length() > 0 && b.charAt(b.length() - 1) != '/') {
|
||||
b.append('/');
|
||||
}
|
||||
b.append(def.getName());
|
||||
b.append('/');
|
||||
String resId = next.getId().getUnqualifiedId();
|
||||
b.append(resId);
|
||||
|
||||
entry.getId().setValue(b.toString());
|
||||
|
||||
if (isNotBlank(next.getId().getUnqualifiedVersionId())) {
|
||||
b.append('/');
|
||||
b.append(Constants.PARAM_HISTORY);
|
||||
b.append('/');
|
||||
b.append(next.getId().getUnqualifiedVersionId());
|
||||
} else {
|
||||
IdDt versionId = getIdFromMetadataOrNullIfNone(next.getResourceMetadata(), ResourceMetadataKeyEnum.VERSION_ID);
|
||||
if (versionId != null) {
|
||||
b.append('/');
|
||||
b.append(Constants.PARAM_HISTORY);
|
||||
b.append('/');
|
||||
b.append(versionId.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
InstantDt published = getInstantFromMetadataOrNullIfNone(next.getResourceMetadata(), ResourceMetadataKeyEnum.PUBLISHED);
|
||||
if (published == null) {
|
||||
entry.getPublished().setToCurrentTimeInLocalTimeZone();
|
||||
} else {
|
||||
entry.setPublished(published);
|
||||
}
|
||||
|
||||
InstantDt updated = getInstantFromMetadataOrNullIfNone(next.getResourceMetadata(), ResourceMetadataKeyEnum.UPDATED);
|
||||
if (updated != null) {
|
||||
entry.setUpdated(updated);
|
||||
}
|
||||
|
||||
InstantDt deleted = getInstantFromMetadataOrNullIfNone(next.getResourceMetadata(), ResourceMetadataKeyEnum.DELETED_AT);
|
||||
if (deleted != null) {
|
||||
entry.setDeleted(deleted);
|
||||
}
|
||||
|
||||
IdDt previous = getIdFromMetadataOrNullIfNone(next.getResourceMetadata(), ResourceMetadataKeyEnum.PREVIOUS_ID);
|
||||
if (previous != null) {
|
||||
entry.getLinkAlternate().setValue(previous.toQualifiedUrl(theServerBase, def.getName()));
|
||||
}
|
||||
|
||||
TagList tagList = getTagListFromMetadataOrNullIfNone(next.getResourceMetadata(), ResourceMetadataKeyEnum.TAG_LIST);
|
||||
if (tagList != null) {
|
||||
for (Tag nextTag : tagList) {
|
||||
entry.addCategory(nextTag);
|
||||
}
|
||||
}
|
||||
|
||||
// boolean haveQ = false;
|
||||
// if (thePrettyPrint) {
|
||||
// b.append('?').append(Constants.PARAM_PRETTY).append("=true");
|
||||
// haveQ = true;
|
||||
// }
|
||||
// if (theResponseEncoding == EncodingEnum.JSON) {
|
||||
// if (!haveQ) {
|
||||
// b.append('?');
|
||||
// haveQ = true;
|
||||
// } else {
|
||||
// b.append('&');
|
||||
// }
|
||||
// b.append(Constants.PARAM_FORMAT).append("=json");
|
||||
// }
|
||||
// if (theNarrativeMode != NarrativeModeEnum.NORMAL) {
|
||||
// b.append(Constants.PARAM_NARRATIVE).append("=").append(theNarrativeMode.name().toLowerCase());
|
||||
// }
|
||||
entry.getLinkSelf().setValue(b.toString());
|
||||
}
|
||||
bundle.addResource(next, theContext, theServerBase);
|
||||
}
|
||||
|
||||
bundle.getTotalResults().setValue(theResult.size());
|
||||
return bundle;
|
||||
}
|
||||
|
||||
private static InstantDt getInstantFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum, Object> theResourceMetadata, ResourceMetadataKeyEnum theKey) {
|
||||
Object retValObj = theResourceMetadata.get(theKey);
|
||||
if (retValObj == null) {
|
||||
return null;
|
||||
} else if (retValObj instanceof Date) {
|
||||
return new InstantDt((Date) retValObj);
|
||||
} else if (retValObj instanceof InstantDt) {
|
||||
if (((InstantDt) retValObj).isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return (InstantDt) retValObj;
|
||||
}
|
||||
}
|
||||
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + InstantDt.class.getCanonicalName());
|
||||
}
|
||||
|
||||
private static TagList getTagListFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum, Object> theResourceMetadata, ResourceMetadataKeyEnum theKey) {
|
||||
Object retValObj = theResourceMetadata.get(theKey);
|
||||
if (retValObj == null) {
|
||||
return null;
|
||||
} else if (retValObj instanceof TagList) {
|
||||
if (((TagList) retValObj).isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return (TagList) retValObj;
|
||||
}
|
||||
}
|
||||
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + TagList.class.getCanonicalName());
|
||||
}
|
||||
|
||||
protected static IdDt getIdFromMetadataOrNullIfNone(Map<ResourceMetadataKeyEnum, Object> theResourceMetadata, ResourceMetadataKeyEnum theKey) {
|
||||
Object retValObj = theResourceMetadata.get(theKey);
|
||||
if (retValObj == null) {
|
||||
return null;
|
||||
} else if (retValObj instanceof String) {
|
||||
if (isNotBlank((String) retValObj)) {
|
||||
return new IdDt((String) retValObj);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else if (retValObj instanceof IdDt) {
|
||||
if (((IdDt) retValObj).isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return (IdDt) retValObj;
|
||||
}
|
||||
}
|
||||
throw new InternalErrorException("Found an object of type '" + retValObj.getClass().getCanonicalName() + "' in resource metadata for key " + theKey.name() + " - Expected " + IdDt.class.getCanonicalName());
|
||||
}
|
||||
|
||||
public enum MethodReturnTypeEnum {
|
||||
BUNDLE, LIST_OF_RESOURCES, RESOURCE
|
||||
|
|
|
@ -155,7 +155,7 @@ public class HistoryMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
if (nextResource.getId() == null || nextResource.getId().isEmpty()) {
|
||||
throw new InternalErrorException("Server provided resource at index " + index + " with no ID set (using IResource#setId(IdDt))");
|
||||
}
|
||||
IdDt versionId = getIdFromMetadataOrNullIfNone(nextResource.getResourceMetadata(),ResourceMetadataKeyEnum.VERSION_ID);
|
||||
IdDt versionId = (IdDt) ResourceMetadataKeyEnum.VERSION_ID.get(nextResource);
|
||||
if (versionId == null||versionId.isEmpty()) {
|
||||
throw new InternalErrorException("Server provided resource at index " + index + " with no Version ID set (using IResource#Resource.getResourceMetadata().put(ResourceMetadataKeyEnum.VERSION_ID, Object))");
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ package ca.uhn.fhir.rest.method;
|
|||
import java.util.List;
|
||||
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.entity.AbstractHttpEntity;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -47,7 +47,7 @@ public class HttpPostClientInvocation extends BaseHttpClientInvocationWithConten
|
|||
|
||||
|
||||
@Override
|
||||
protected HttpPost createRequest(String url, StringEntity theEntity) {
|
||||
protected HttpPost createRequest(String url, AbstractHttpEntity theEntity) {
|
||||
HttpPost retVal = new HttpPost(url);
|
||||
retVal.setEntity(theEntity);
|
||||
return retVal;
|
||||
|
|
|
@ -22,7 +22,7 @@ package ca.uhn.fhir.rest.method;
|
|||
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpRequestBase;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.entity.AbstractHttpEntity;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
|
@ -34,7 +34,7 @@ public class HttpPutClientInvocation extends BaseHttpClientInvocationWithContent
|
|||
}
|
||||
|
||||
@Override
|
||||
protected HttpRequestBase createRequest(String url, StringEntity theEntity) {
|
||||
protected HttpRequestBase createRequest(String url, AbstractHttpEntity theEntity) {
|
||||
HttpPut retVal = new HttpPut(url);
|
||||
retVal.setEntity(theEntity);
|
||||
return retVal;
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package ca.uhn.fhir.rest.method;
|
||||
|
||||
/*
|
||||
* #%L
|
||||
* HAPI FHIR Library
|
||||
* %%
|
||||
* Copyright (C) 2014 University Health Network
|
||||
* %%
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
|
||||
public interface IClientResponseHandlerHandlesBinary<T> extends IClientResponseHandler<T> {
|
||||
|
||||
/**
|
||||
* If this method returns true, {@link #invokeClient(String, InputStream, int, Map)} should be invoked instead of {@link #invokeClient(String, Reader, int, Map)}
|
||||
*/
|
||||
boolean isBinary();
|
||||
|
||||
T invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException;
|
||||
|
||||
}
|
|
@ -20,15 +20,22 @@ package ca.uhn.fhir.rest.method;
|
|||
* #L%
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import ca.uhn.fhir.context.ConfigurationException;
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
|
||||
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
|
@ -36,10 +43,11 @@ import ca.uhn.fhir.rest.method.SearchMethodBinding.RequestType;
|
|||
import ca.uhn.fhir.rest.param.IParameter;
|
||||
import ca.uhn.fhir.rest.param.ParameterUtil;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
||||
public class ReadMethodBinding extends BaseResourceReturningMethodBinding implements IClientResponseHandlerHandlesBinary<Object> {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ReadMethodBinding.class);
|
||||
|
||||
private Integer myIdIndex;
|
||||
|
@ -156,4 +164,26 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding {
|
|||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBinary() {
|
||||
return "Binary".equals(getResourceName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
|
||||
byte[] contents = IOUtils.toByteArray(theResponseReader);
|
||||
Binary resource = new Binary(theResponseMimeType, contents);
|
||||
|
||||
switch (getMethodReturnType()) {
|
||||
case BUNDLE:
|
||||
return Bundle.withSingleResource(resource);
|
||||
case LIST_OF_RESOURCES:
|
||||
return Collections.singletonList(resource);
|
||||
case RESOURCE:
|
||||
return resource;
|
||||
}
|
||||
|
||||
throw new IllegalStateException(""+getMethodReturnType()); // should not happen
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -39,7 +39,6 @@ public class Request {
|
|||
private String myCompleteUrl;
|
||||
private String myFhirServerBase;
|
||||
private IdDt myId;
|
||||
private Reader myInputReader;
|
||||
private String myOperation;
|
||||
private Map<String, String[]> myParameters;
|
||||
private RequestType myRequestType;
|
||||
|
@ -62,10 +61,6 @@ public class Request {
|
|||
return myId;
|
||||
}
|
||||
|
||||
public Reader getInputReader() {
|
||||
return myInputReader;
|
||||
}
|
||||
|
||||
public String getOperation() {
|
||||
return myOperation;
|
||||
}
|
||||
|
@ -111,10 +106,6 @@ public class Request {
|
|||
myId = theId;
|
||||
}
|
||||
|
||||
public void setInputReader(Reader theReader) {
|
||||
myInputReader = theReader;
|
||||
}
|
||||
|
||||
public void setOperation(String theOperation) {
|
||||
myOperation = theOperation;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ package ca.uhn.fhir.rest.method;
|
|||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
@ -125,10 +126,10 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Object parseRequestObject(Request theRequest) {
|
||||
protected Object parseRequestObject(Request theRequest) throws IOException {
|
||||
EncodingEnum encoding = RestfulServer.determineResponseEncoding(theRequest);
|
||||
IParser parser = encoding.newParser(getContext());
|
||||
Bundle bundle = parser.parseBundle(theRequest.getInputReader());
|
||||
Bundle bundle = parser.parseBundle(theRequest.getServletRequest().getReader());
|
||||
return bundle;
|
||||
}
|
||||
|
||||
|
@ -139,10 +140,15 @@ public class TransactionMethodBinding extends BaseResourceReturningMethodBinding
|
|||
|
||||
@Override
|
||||
public BaseHttpClientInvocation invokeClient(Object[] theArgs) throws InternalErrorException {
|
||||
@SuppressWarnings("unchecked")
|
||||
List<IResource> resources = (List<IResource>) theArgs[myTransactionParamIndex];
|
||||
FhirContext context = getContext();
|
||||
|
||||
return new HttpPostClientInvocation(context, resources);
|
||||
return createTransactionInvocation(resources, context);
|
||||
}
|
||||
|
||||
public static BaseHttpClientInvocation createTransactionInvocation(List<IResource> resources, FhirContext theContext) {
|
||||
return new HttpPostClientInvocation(theContext, resources);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -78,6 +78,13 @@ public class UpdateMethodBinding extends BaseOutcomeReturningMethodBindingWithRe
|
|||
* we allow it in the PUT URL as well..
|
||||
*/
|
||||
String locationHeader = theRequest.getServletRequest().getHeader(Constants.HEADER_CONTENT_LOCATION);
|
||||
IdDt id = new IdDt(locationHeader);
|
||||
if (isNotBlank(id.getResourceType())) {
|
||||
if (!getResourceName().equals(id.getResourceType())) {
|
||||
throw new InvalidRequestException("Attempting to update '"+getResourceName()+ "' but content-location header specifies different resource type '"+id.getResourceType()+"' - header value: " + locationHeader);
|
||||
}
|
||||
}
|
||||
|
||||
if (isNotBlank(locationHeader)) {
|
||||
MethodOutcome mo = new MethodOutcome();
|
||||
parseContentLocation(mo, getResourceName(), locationHeader);
|
||||
|
|
|
@ -77,6 +77,7 @@ public class Constants {
|
|||
public static final int STATUS_HTTP_422_UNPROCESSABLE_ENTITY = 422;
|
||||
public static final int STATUS_HTTP_500_INTERNAL_ERROR = 500;
|
||||
public static final String URL_TOKEN_HISTORY = "_history";
|
||||
public static final String HEADER_CONTENT_TYPE = "Content-Type";
|
||||
|
||||
static {
|
||||
Map<String, EncodingEnum> valToEncoding = new HashMap<String, EncodingEnum>();
|
||||
|
|
|
@ -606,11 +606,6 @@ public class RestfulServer extends HttpServlet {
|
|||
r.setSecondaryOperation(secondaryOperation);
|
||||
r.setParameters(params);
|
||||
r.setRequestType(theRequestType);
|
||||
if ("application/x-www-form-urlencoded".equals(theRequest.getContentType())) {
|
||||
r.setInputReader(new StringReader(""));
|
||||
} else {
|
||||
r.setInputReader(theRequest.getReader());
|
||||
}
|
||||
r.setFhirServerBase(fhirServerBase);
|
||||
r.setCompleteUrl(completeUrl);
|
||||
r.setServletRequest(theRequest);
|
||||
|
@ -723,6 +718,32 @@ public class RestfulServer extends HttpServlet {
|
|||
return EncodingEnum.XML;
|
||||
}
|
||||
|
||||
public static EncodingEnum determineRequestEncoding(Request theReq) {
|
||||
Enumeration<String> acceptValues = theReq.getServletRequest().getHeaders(Constants.HEADER_CONTENT_TYPE);
|
||||
if (acceptValues != null) {
|
||||
while (acceptValues.hasMoreElements()) {
|
||||
String nextAcceptHeaderValue = acceptValues.nextElement();
|
||||
if (nextAcceptHeaderValue != null && isNotBlank(nextAcceptHeaderValue)) {
|
||||
for (String nextPart : nextAcceptHeaderValue.split(",")) {
|
||||
int scIdx = nextPart.indexOf(';');
|
||||
if (scIdx == 0) {
|
||||
continue;
|
||||
}
|
||||
if (scIdx != -1) {
|
||||
nextPart = nextPart.substring(0, scIdx);
|
||||
}
|
||||
nextPart = nextPart.trim();
|
||||
EncodingEnum retVal = Constants.FORMAT_VAL_TO_ENCODING.get(nextPart);
|
||||
if (retVal != null) {
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return EncodingEnum.XML;
|
||||
}
|
||||
|
||||
public enum NarrativeModeEnum {
|
||||
NORMAL, ONLY, SUPPRESS;
|
||||
|
||||
|
|
|
@ -176,7 +176,8 @@ public class RestfulServerTesterServlet extends HttpServlet {
|
|||
GenericClient client = (GenericClient) myCtx.newRestfulGenericClient(myServerBase);
|
||||
client.setKeepResponses(true);
|
||||
boolean returnsResource;
|
||||
|
||||
long latency=0;
|
||||
|
||||
try {
|
||||
String method = theReq.getParameter("method");
|
||||
|
||||
|
@ -190,127 +191,129 @@ public class RestfulServerTesterServlet extends HttpServlet {
|
|||
client.setEncoding(EncodingEnum.JSON);
|
||||
}
|
||||
|
||||
if ("conformance".equals(method)) {
|
||||
returnsResource = true;
|
||||
client.conformance();
|
||||
} else if ("read".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
returnsResource = true;
|
||||
long start = System.currentTimeMillis();
|
||||
if ("conformance".equals(method)) {
|
||||
returnsResource = true;
|
||||
client.conformance();
|
||||
} else if ("read".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
returnsResource = true;
|
||||
|
||||
client.read(def.getImplementingClass(), new IdDt(id));
|
||||
client.read(def.getImplementingClass(), new IdDt(id));
|
||||
|
||||
} else if ("vread".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
String versionId = StringUtils.defaultString(theReq.getParameter("versionid"));
|
||||
if (StringUtils.isBlank(versionId)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No Version ID specified");
|
||||
}
|
||||
returnsResource = true;
|
||||
|
||||
client.vread(def.getImplementingClass(), new IdDt(id), new IdDt(versionId));
|
||||
|
||||
} else if ("delete".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
returnsResource = false;
|
||||
|
||||
client.delete(def.getImplementingClass(), new IdDt(id));
|
||||
|
||||
} else if ("history-instance".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
returnsResource = false;
|
||||
|
||||
client.history(def.getImplementingClass(), new IdDt(id));
|
||||
|
||||
} else if ("create".equals(method)) {
|
||||
IResource resource = parseIncomingResource(theReq, theResp, client);
|
||||
returnsResource = false;
|
||||
|
||||
client.create(resource);
|
||||
|
||||
} else if ("validate".equals(method)) {
|
||||
IResource resource = parseIncomingResource(theReq, theResp, client);
|
||||
returnsResource = false;
|
||||
|
||||
client.validate(resource);
|
||||
|
||||
} else if ("update".equals(method)) {
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
IResource resource = parseIncomingResource(theReq, theResp, client);
|
||||
returnsResource = false;
|
||||
|
||||
client.update(new IdDt(id), resource);
|
||||
|
||||
} else if ("searchType".equals(method)) {
|
||||
Map<String, List<IQueryParameterType>> params = new HashMap<String, List<IQueryParameterType>>();
|
||||
|
||||
HashSet<String> hashSet = new HashSet<String>(theReq.getParameterMap().keySet());
|
||||
String paramName = null;
|
||||
IQueryParameterType paramValue = null;
|
||||
while (hashSet.isEmpty() == false) {
|
||||
|
||||
String nextKey = hashSet.iterator().next();
|
||||
String nextValue = theReq.getParameter(nextKey);
|
||||
paramName = null;
|
||||
paramValue = null;
|
||||
|
||||
if (nextKey.startsWith("param.token.")) {
|
||||
int prefixLength = "param.token.".length();
|
||||
paramName = nextKey.substring(prefixLength + 2);
|
||||
String systemKey = "param.token." + "1." + paramName;
|
||||
String valueKey = "param.token." + "2." + paramName;
|
||||
String system = theReq.getParameter(systemKey);
|
||||
String value = theReq.getParameter(valueKey);
|
||||
paramValue = new IdentifierDt(system, value);
|
||||
hashSet.remove(systemKey);
|
||||
hashSet.remove(valueKey);
|
||||
} else if (nextKey.startsWith("param.string.")) {
|
||||
paramName = nextKey.substring("param.string.".length());
|
||||
paramValue = new StringDt(nextValue);
|
||||
}
|
||||
|
||||
if (paramName != null) {
|
||||
if (params.containsKey(paramName) == false) {
|
||||
params.put(paramName, new ArrayList<IQueryParameterType>());
|
||||
}
|
||||
params.get(paramName).add(paramValue);
|
||||
}
|
||||
|
||||
hashSet.remove(nextKey);
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
|
||||
returnsResource = false;
|
||||
client.search(def.getImplementingClass(), params);
|
||||
|
||||
} else {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "Invalid method: " + method);
|
||||
return;
|
||||
} else if ("vread".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
String versionId = StringUtils.defaultString(theReq.getParameter("versionid"));
|
||||
if (StringUtils.isBlank(versionId)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No Version ID specified");
|
||||
}
|
||||
returnsResource = true;
|
||||
|
||||
client.vread(def.getImplementingClass(), new IdDt(id), new IdDt(versionId));
|
||||
|
||||
} else if ("delete".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
returnsResource = false;
|
||||
|
||||
client.delete(def.getImplementingClass(), new IdDt(id));
|
||||
|
||||
} else if ("history-instance".equals(method)) {
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
returnsResource = false;
|
||||
|
||||
client.history(def.getImplementingClass(), new IdDt(id));
|
||||
|
||||
} else if ("create".equals(method)) {
|
||||
IResource resource = parseIncomingResource(theReq, theResp, client);
|
||||
returnsResource = false;
|
||||
|
||||
client.create(resource);
|
||||
|
||||
} else if ("validate".equals(method)) {
|
||||
IResource resource = parseIncomingResource(theReq, theResp, client);
|
||||
returnsResource = false;
|
||||
|
||||
client.validate(resource);
|
||||
|
||||
} else if ("update".equals(method)) {
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "No ID specified");
|
||||
}
|
||||
|
||||
IResource resource = parseIncomingResource(theReq, theResp, client);
|
||||
returnsResource = false;
|
||||
|
||||
client.update(new IdDt(id), resource);
|
||||
|
||||
} else if ("searchType".equals(method)) {
|
||||
Map<String, List<IQueryParameterType>> params = new HashMap<String, List<IQueryParameterType>>();
|
||||
|
||||
HashSet<String> hashSet = new HashSet<String>(theReq.getParameterMap().keySet());
|
||||
String paramName = null;
|
||||
IQueryParameterType paramValue = null;
|
||||
while (hashSet.isEmpty() == false) {
|
||||
|
||||
String nextKey = hashSet.iterator().next();
|
||||
String nextValue = theReq.getParameter(nextKey);
|
||||
paramName = null;
|
||||
paramValue = null;
|
||||
|
||||
if (nextKey.startsWith("param.token.")) {
|
||||
int prefixLength = "param.token.".length();
|
||||
paramName = nextKey.substring(prefixLength + 2);
|
||||
String systemKey = "param.token." + "1." + paramName;
|
||||
String valueKey = "param.token." + "2." + paramName;
|
||||
String system = theReq.getParameter(systemKey);
|
||||
String value = theReq.getParameter(valueKey);
|
||||
paramValue = new IdentifierDt(system, value);
|
||||
hashSet.remove(systemKey);
|
||||
hashSet.remove(valueKey);
|
||||
} else if (nextKey.startsWith("param.string.")) {
|
||||
paramName = nextKey.substring("param.string.".length());
|
||||
paramValue = new StringDt(nextValue);
|
||||
}
|
||||
|
||||
if (paramName != null) {
|
||||
if (params.containsKey(paramName) == false) {
|
||||
params.put(paramName, new ArrayList<IQueryParameterType>());
|
||||
}
|
||||
params.get(paramName).add(paramValue);
|
||||
}
|
||||
|
||||
hashSet.remove(nextKey);
|
||||
}
|
||||
|
||||
RuntimeResourceDefinition def = getResourceType(theReq);
|
||||
|
||||
returnsResource = false;
|
||||
client.search(def.getImplementingClass(), params);
|
||||
|
||||
} else {
|
||||
theResp.sendError(Constants.STATUS_HTTP_400_BAD_REQUEST, "Invalid method: " + method);
|
||||
return;
|
||||
}
|
||||
|
||||
latency = System.currentTimeMillis() - start;
|
||||
} catch (DataFormatException e) {
|
||||
ourLog.error("Failed to invoke method", e);
|
||||
returnsResource = false;
|
||||
|
@ -350,13 +353,13 @@ public class RestfulServerTesterServlet extends HttpServlet {
|
|||
}
|
||||
}
|
||||
String resultSyntaxHighlighterClass;
|
||||
String requestUrl = lastRequest!=null?lastRequest.getURI().toASCIIString():null;
|
||||
String action = client.getLastRequest()!=null?client.getLastRequest().getMethod():null;
|
||||
String resultStatus = client.getLastResponse()!=null?client.getLastResponse().getStatusLine().toString():null;
|
||||
String requestUrl = lastRequest != null ? lastRequest.getURI().toASCIIString() : null;
|
||||
String action = client.getLastRequest() != null ? client.getLastRequest().getMethod() : null;
|
||||
String resultStatus = client.getLastResponse() != null ? client.getLastResponse().getStatusLine().toString() : null;
|
||||
String resultBody = client.getLastResponseBody();
|
||||
|
||||
HttpResponse lastResponse = client.getLastResponse();
|
||||
ContentType ct = lastResponse!=null?ContentType.get(lastResponse.getEntity()):null;
|
||||
ContentType ct = lastResponse != null ? ContentType.get(lastResponse.getEntity()) : null;
|
||||
String mimeType = ct != null ? ct.getMimeType() : null;
|
||||
EncodingEnum ctEnum = EncodingEnum.forContentType(mimeType);
|
||||
String narrativeString = "";
|
||||
|
@ -381,8 +384,8 @@ public class RestfulServerTesterServlet extends HttpServlet {
|
|||
}
|
||||
}
|
||||
|
||||
Header[] requestHeaders = lastRequest!=null?applyHeaderFilters(lastRequest.getAllHeaders()): new Header[0];
|
||||
Header[] responseHeaders = lastResponse!=null?applyHeaderFilters(lastResponse.getAllHeaders()):new Header[0];
|
||||
Header[] requestHeaders = lastRequest != null ? applyHeaderFilters(lastRequest.getAllHeaders()) : new Header[0];
|
||||
Header[] responseHeaders = lastResponse != null ? applyHeaderFilters(lastResponse.getAllHeaders()) : new Header[0];
|
||||
|
||||
WebContext ctx = new WebContext(theReq, theResp, theReq.getServletContext(), theReq.getLocale());
|
||||
ctx.setVariable("base", myServerBase);
|
||||
|
@ -396,6 +399,7 @@ public class RestfulServerTesterServlet extends HttpServlet {
|
|||
ctx.setVariable("requestHeaders", requestHeaders);
|
||||
ctx.setVariable("responseHeaders", responseHeaders);
|
||||
ctx.setVariable("narrative", narrativeString);
|
||||
ctx.setVariable("latencyMs", latency);
|
||||
|
||||
myTemplateEngine.process(PUBLIC_TESTER_RESULT_HTML, ctx, theResp.getWriter());
|
||||
} catch (Exception e) {
|
||||
|
@ -415,8 +419,8 @@ public class RestfulServerTesterServlet extends HttpServlet {
|
|||
if (theClient.getEncoding() == null) {
|
||||
if (resourceText.trim().startsWith("{")) {
|
||||
resource = myCtx.newJsonParser().parseResource(def.getImplementingClass(), resourceText);
|
||||
}else {
|
||||
resource = myCtx.newXmlParser().parseResource(def.getImplementingClass(), resourceText);
|
||||
} else {
|
||||
resource = myCtx.newXmlParser().parseResource(def.getImplementingClass(), resourceText);
|
||||
}
|
||||
} else if (theClient.getEncoding() == EncodingEnum.XML) {
|
||||
resource = myCtx.newXmlParser().parseResource(def.getImplementingClass(), resourceText);
|
||||
|
|
|
@ -55,4 +55,6 @@ TD.testerNameCell {
|
|||
|
||||
.syntaxhighlighter {
|
||||
font-size: 0.85em !important;
|
||||
min-height: 1.4em;
|
||||
max-width: 800px;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ This file is a Thymeleaf template for the
|
|||
</tr>
|
||||
</table>
|
||||
<div class="bodyHeaderBlock">
|
||||
Executed invocation against FHIR RESTful Server
|
||||
Executed invocation against FHIR RESTful Server in ${latencyMs}ms
|
||||
</div>
|
||||
|
||||
<table border="0" width="100%" cellpadding="0" cellspacing="0" style="margin-top: 4px;">
|
||||
|
|
|
@ -4,10 +4,18 @@ import static org.junit.Assert.*;
|
|||
|
||||
import org.junit.Test;
|
||||
|
||||
import ca.uhn.fhir.model.dstu.resource.CarePlan;
|
||||
import ca.uhn.fhir.parser.DataFormatException;
|
||||
|
||||
public class ModelScannerTest {
|
||||
|
||||
/** This failed at one point */
|
||||
@SuppressWarnings("unused")
|
||||
@Test
|
||||
public void testCarePlan() throws DataFormatException {
|
||||
new ModelScanner(CarePlan.class);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testScanExtensionTypes() throws DataFormatException {
|
||||
|
|
|
@ -190,6 +190,11 @@ public class ResourceWithExtensionsA extends BaseResource {
|
|||
return myId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setId(String theId) {
|
||||
myId=new IdDt(theId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
|||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.resource.Query;
|
||||
import ca.uhn.fhir.model.dstu.resource.Specimen;
|
||||
import ca.uhn.fhir.model.dstu.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.dstu.resource.ValueSet.Define;
|
||||
|
@ -82,6 +83,58 @@ public class JsonParserTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseQuery() {
|
||||
String msg = "{\n" +
|
||||
" \"resourceType\": \"Query\",\n" +
|
||||
" \"text\": {\n" +
|
||||
" \"status\": \"generated\",\n" +
|
||||
" \"div\": \"<div>[Put rendering here]</div>\"\n" +
|
||||
" },\n" +
|
||||
" \"identifier\": \"urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376\",\n" +
|
||||
" \"parameter\": [\n" +
|
||||
" {\n" +
|
||||
" \"url\": \"http://hl7.org/fhir/query#_query\",\n" +
|
||||
" \"valueString\": \"example\"\n" +
|
||||
" }\n" +
|
||||
" ]\n" +
|
||||
"}";
|
||||
Query query = ourCtx.newJsonParser().parseResource(Query.class, msg);
|
||||
|
||||
assertEquals("urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376", query.getIdentifier().getValueAsString());
|
||||
assertEquals("http://hl7.org/fhir/query#_query", query.getParameterFirstRep().getUrlAsString());
|
||||
assertEquals("example", query.getParameterFirstRep().getValueAsPrimitive().getValueAsString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeQuery() {
|
||||
Query q = new Query();
|
||||
ExtensionDt parameter = q.addParameter();
|
||||
parameter.setUrl("http://hl7.org/fhir/query#_query").setValue(new StringDt("example"));
|
||||
|
||||
|
||||
String val = new FhirContext().newJsonParser().encodeResourceToString(q);
|
||||
ourLog.info(val);
|
||||
|
||||
//@formatter:off
|
||||
String expected =
|
||||
"{" +
|
||||
"\"resourceType\":\"Query\"," +
|
||||
"\"parameter\":[" +
|
||||
"{" +
|
||||
"\"url\":\"http://hl7.org/fhir/query#_query\"," +
|
||||
"\"valueString\":\"example\"" +
|
||||
"}" +
|
||||
"]" +
|
||||
"}";
|
||||
//@formatter:on
|
||||
|
||||
ourLog.info("Expect: {}", expected);
|
||||
ourLog.info("Got : {}", val);
|
||||
assertEquals(expected, val);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testParseBinaryResource() {
|
||||
|
|
|
@ -44,6 +44,7 @@ import ca.uhn.fhir.model.dstu.resource.DiagnosticReport;
|
|||
import ca.uhn.fhir.model.dstu.resource.Observation;
|
||||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.dstu.resource.Query;
|
||||
import ca.uhn.fhir.model.dstu.resource.Specimen;
|
||||
import ca.uhn.fhir.model.dstu.resource.ValueSet;
|
||||
import ca.uhn.fhir.model.dstu.valueset.AddressUseEnum;
|
||||
|
@ -78,6 +79,45 @@ public class XmlParserTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParseQuery() {
|
||||
String msg = "<Query xmlns=\"http://hl7.org/fhir\">\n" +
|
||||
" <text>\n" +
|
||||
" <status value=\"generated\"/>\n" +
|
||||
" <div xmlns=\"http://www.w3.org/1999/xhtml\">[Put rendering here]</div>\n" +
|
||||
" </text>\n" +
|
||||
"\n" +
|
||||
" <!-- this is an extermely simple query - a request to execute the query 'example' on the\n" +
|
||||
" responder -->\n" +
|
||||
" <identifier value=\"urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376\"/>\n" +
|
||||
" <parameter url=\"http://hl7.org/fhir/query#_query\">\n" +
|
||||
" <valueString value=\"example\"/>\n" +
|
||||
" </parameter>\n" +
|
||||
"</Query>";
|
||||
Query query = ourCtx.newXmlParser().parseResource(Query.class, msg);
|
||||
|
||||
assertEquals("urn:uuid:42b253f5-fa17-40d0-8da5-44aeb4230376", query.getIdentifier().getValueAsString());
|
||||
assertEquals("http://hl7.org/fhir/query#_query", query.getParameterFirstRep().getUrlAsString());
|
||||
assertEquals("example", query.getParameterFirstRep().getValueAsPrimitive().getValueAsString());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeQuery() {
|
||||
Query q = new Query();
|
||||
ExtensionDt parameter = q.addParameter();
|
||||
parameter.setUrl("http://foo").setValue(new StringDt("bar"));
|
||||
|
||||
|
||||
String val = new FhirContext().newXmlParser().encodeResourceToString(q);
|
||||
ourLog.info(val);
|
||||
|
||||
assertEquals("<Query xmlns=\"http://hl7.org/fhir\"><parameter url=\"http://foo\"><valueString value=\"bar\"/></parameter></Query>", val);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testEncodeBinaryResource() {
|
||||
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
package ca.uhn.fhir.rest.client;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.ProtocolVersion;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
import org.apache.http.message.BasicStatusLine;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.internal.stubbing.defaultanswers.ReturnsDeepStubs;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
import ca.uhn.fhir.model.api.Bundle;
|
||||
import ca.uhn.fhir.model.dstu.resource.Binary;
|
||||
import ca.uhn.fhir.model.dstu.resource.Conformance;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.annotation.Create;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.ResourceParam;
|
||||
import ca.uhn.fhir.rest.api.MethodOutcome;
|
||||
import ca.uhn.fhir.rest.client.api.IBasicClient;
|
||||
import ca.uhn.fhir.rest.server.Constants;
|
||||
|
||||
public class BinaryClientTest {
|
||||
|
||||
private FhirContext ctx;
|
||||
private HttpClient httpClient;
|
||||
private HttpResponse httpResponse;
|
||||
|
||||
// atom-document-large.xml
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
ctx = new FhirContext(Patient.class, Conformance.class);
|
||||
|
||||
httpClient = mock(HttpClient.class, new ReturnsDeepStubs());
|
||||
ctx.getRestfulClientFactory().setHttpClient(httpClient);
|
||||
|
||||
httpResponse = mock(HttpResponse.class, new ReturnsDeepStubs());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRead() throws Exception {
|
||||
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.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", "foo/bar"));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] {1,2,3,4}));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
Binary resp = client.read(new IdDt("http://foo/Patient/123"));
|
||||
|
||||
assertEquals(HttpGet.class, capt.getValue().getClass());
|
||||
HttpGet get = (HttpGet) capt.getValue();
|
||||
assertEquals("http://foo/Binary/123", get.getURI().toString());
|
||||
|
||||
assertEquals("foo/bar", resp.getContentType());
|
||||
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, resp.getContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreate() throws Exception {
|
||||
Binary res = new Binary();
|
||||
res.setContent(new byte[] { 1, 2, 3, 4 });
|
||||
res.setContentType("text/plain");
|
||||
|
||||
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), 201, "OK"));
|
||||
when(httpResponse.getEntity().getContentType()).thenReturn(new BasicHeader("content-type", Constants.CT_FHIR_XML));
|
||||
when(httpResponse.getEntity().getContent()).thenReturn(new ByteArrayInputStream(new byte[] {}));
|
||||
|
||||
IClient client = ctx.newRestfulClient(IClient.class, "http://foo");
|
||||
MethodOutcome resp = client.create(res);
|
||||
|
||||
assertEquals(HttpPost.class, capt.getValue().getClass());
|
||||
HttpPost post = (HttpPost) capt.getValue();
|
||||
assertEquals("http://foo/Binary", post.getURI().toString());
|
||||
|
||||
assertEquals("text/plain", post.getEntity().getContentType().getValue());
|
||||
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, IOUtils.toByteArray(post.getEntity().getContent()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String createBundle() {
|
||||
return ctx.newXmlParser().encodeBundleToString(new Bundle());
|
||||
}
|
||||
|
||||
|
||||
private interface IClient extends IBasicClient {
|
||||
|
||||
@Read(type=Binary.class)
|
||||
public Binary read(@IdParam IdDt theBinary);
|
||||
|
||||
@Create(type=Binary.class)
|
||||
public MethodOutcome create(@ResourceParam Binary theBinary);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -100,6 +100,7 @@ public class ClientIntegrationTest {
|
|||
myAuthorizationHeader = theRequest.getHeader("authorization");
|
||||
|
||||
Patient retVal = new Patient();
|
||||
retVal.setId("1");
|
||||
retVal.addName().addFamily(theFooParam.getValue());
|
||||
return Collections.singletonList(retVal);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import org.apache.http.HttpResponse;
|
|||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.entity.ByteArrayEntity;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
|
@ -72,6 +73,18 @@ public class BinaryTest {
|
|||
|
||||
@Test
|
||||
public void testCreate() throws Exception {
|
||||
HttpPost http = new HttpPost("http://localhost:" + ourPort + "/Binary");
|
||||
http.setEntity(new ByteArrayEntity(new byte[] {1,2,3,4}, ContentType.create("foo/bar", "UTF-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(http);
|
||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||
|
||||
assertEquals("foo/bar; charset=UTF-8", ourLast.getContentType());
|
||||
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, ourLast.getContent());
|
||||
|
||||
}
|
||||
|
||||
public void testCreateWrongType() throws Exception {
|
||||
Binary res = new Binary();
|
||||
res.setContent(new byte[] { 1, 2, 3, 4 });
|
||||
res.setContentType("text/plain");
|
||||
|
@ -87,7 +100,7 @@ public class BinaryTest {
|
|||
assertArrayEquals(new byte[] { 1, 2, 3, 4 }, ourLast.getContent());
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSearch() throws Exception {
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Binary?");
|
||||
|
@ -150,6 +163,7 @@ public class BinaryTest {
|
|||
@Read
|
||||
public Binary read(@IdParam IdDt theId) {
|
||||
Binary retVal = new Binary();
|
||||
retVal.setId("1");
|
||||
retVal.setContent(new byte[] { 1, 2, 3, 4 });
|
||||
retVal.setContentType(theId.getUnqualifiedId());
|
||||
return retVal;
|
||||
|
@ -160,6 +174,7 @@ public class BinaryTest {
|
|||
@Search
|
||||
public List<Binary> search() {
|
||||
Binary retVal = new Binary();
|
||||
retVal.setId("1");
|
||||
retVal.setContent(new byte[] { 1, 2, 3, 4 });
|
||||
retVal.setContentType("text/plain");
|
||||
return Collections.singletonList(retVal);
|
||||
|
|
|
@ -239,6 +239,7 @@ public class PlainProviderTest {
|
|||
|
||||
private static Patient createPatient() {
|
||||
Patient patient = new Patient();
|
||||
patient.setId("1");
|
||||
patient.addIdentifier();
|
||||
patient.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
|
@ -252,6 +253,7 @@ public class PlainProviderTest {
|
|||
|
||||
private static Organization createOrganization() {
|
||||
Organization retVal = new Organization();
|
||||
retVal.setId("1");
|
||||
retVal.addIdentifier();
|
||||
retVal.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
||||
retVal.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
|
|
|
@ -144,6 +144,7 @@ public class ReferenceParameterTest {
|
|||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setId("1");
|
||||
p.addName().addFamily("0"+theParam.getValueAsQueryToken());
|
||||
p.addName().addFamily("1"+defaultString(theParam.getResourceType()));
|
||||
p.addName().addFamily("2"+defaultString(theParam.getChain()));
|
||||
|
|
|
@ -130,6 +130,27 @@ public class ResfulServerMethodTest {
|
|||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCreateJson() throws Exception {
|
||||
|
||||
Patient patient = new Patient();
|
||||
patient.addIdentifier().setValue("001");
|
||||
patient.addIdentifier().setValue("002");
|
||||
|
||||
HttpPost httpPost = new HttpPost("http://localhost:" + ourPort + "/Patient");
|
||||
httpPost.setEntity(new StringEntity(new FhirContext().newJsonParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_JSON, "UTF-8")));
|
||||
|
||||
HttpResponse status = ourClient.execute(httpPost);
|
||||
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(201, status.getStatusLine().getStatusCode());
|
||||
assertEquals("http://localhost:" + ourPort + "/Patient/001/_history/002", status.getFirstHeader("Location").getValue());
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateWithUnprocessableEntity() throws Exception {
|
||||
|
||||
|
@ -1033,10 +1054,10 @@ public class ResfulServerMethodTest {
|
|||
httpPut.setEntity(new StringEntity(new FhirContext().newXmlParser().encodeResourceToString(patient), ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
|
||||
|
||||
CloseableHttpResponse results = ourClient.execute(httpPut);
|
||||
assertEquals(400, results.getStatusLine().getStatusCode());
|
||||
String responseContent = IOUtils.toString(results.getEntity().getContent());
|
||||
ourLog.info("Response was:\n{}", responseContent);
|
||||
|
||||
assertEquals(400, results.getStatusLine().getStatusCode());
|
||||
}
|
||||
|
||||
public void testUpdateWrongResourceType() throws Exception {
|
||||
|
@ -1192,8 +1213,15 @@ public class ResfulServerMethodTest {
|
|||
@Search()
|
||||
public Collection<AdverseReaction> getAllResources() {
|
||||
ArrayList<AdverseReaction> retVal = new ArrayList<AdverseReaction>();
|
||||
retVal.add(new AdverseReaction());
|
||||
retVal.add(new AdverseReaction());
|
||||
|
||||
AdverseReaction ar1 = new AdverseReaction();
|
||||
ar1.setId("1");
|
||||
retVal.add(ar1);
|
||||
|
||||
AdverseReaction ar2 = new AdverseReaction();
|
||||
ar2.setId("2");
|
||||
retVal.add(ar2);
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,6 +134,7 @@ public class ResfulServerSelfReferenceTest {
|
|||
Map<String, Patient> idToPatient = new HashMap<String, Patient>();
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setId("1");
|
||||
patient.addIdentifier();
|
||||
patient.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
|
@ -146,6 +147,7 @@ public class ResfulServerSelfReferenceTest {
|
|||
}
|
||||
{
|
||||
Patient patient = new Patient();
|
||||
patient.setId("2");
|
||||
patient.getIdentifier().add(new IdentifierDt());
|
||||
patient.getIdentifier().get(0).setUse(IdentifierUseEnum.OFFICIAL);
|
||||
patient.getIdentifier().get(0).setSystem(new UriDt("urn:hapitest:mrns"));
|
||||
|
|
|
@ -80,6 +80,7 @@ public class ServerExtraParametersTest {
|
|||
myServerBase = theServerBase;
|
||||
|
||||
Patient retVal = new Patient();
|
||||
retVal.setId("1");
|
||||
retVal.addName().addFamily(theFooParam.getValue());
|
||||
return Collections.singletonList(retVal);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@ package ca.uhn.fhir.rest.server;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -30,6 +32,7 @@ import ca.uhn.fhir.model.primitive.IdDt;
|
|||
import ca.uhn.fhir.model.primitive.UriDt;
|
||||
import ca.uhn.fhir.rest.annotation.IdParam;
|
||||
import ca.uhn.fhir.rest.annotation.Read;
|
||||
import ca.uhn.fhir.rest.annotation.Search;
|
||||
import ca.uhn.fhir.testutil.RandomServerPortProvider;
|
||||
|
||||
/**
|
||||
|
@ -149,6 +152,19 @@ public class ServerFeaturesTest {
|
|||
assertThat(responseContent, StringContains.containsString("\",\n"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testInternalErrorIfNoId() throws Exception {
|
||||
|
||||
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient/?_query=findPatientsWithNoIdSpecified");
|
||||
httpGet.addHeader("Accept", Constants.CT_FHIR_XML+ "; pretty=true");
|
||||
CloseableHttpResponse status = ourClient.execute(httpGet);
|
||||
String responseContent = IOUtils.toString(status.getEntity().getContent());
|
||||
assertEquals(500, status.getStatusLine().getStatusCode());
|
||||
assertThat(responseContent, StringContains.containsString("ID"));
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
|
@ -215,6 +231,13 @@ public class ServerFeaturesTest {
|
|||
public Patient getResourceById(@IdParam IdDt theId) {
|
||||
return getIdToPatient().get(theId.getValue());
|
||||
}
|
||||
|
||||
@Search(queryName="findPatientsWithNoIdSpecified")
|
||||
public List<Patient> findPatientsWithNoIdSpecified() {
|
||||
Patient p = new Patient();
|
||||
p.addIdentifier().setSystem("foo");
|
||||
return Collections.singletonList(p);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Patient> getResourceType() {
|
||||
|
|
|
@ -155,6 +155,7 @@ public class SortTest {
|
|||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
Patient p = new Patient();
|
||||
p.setId("1");
|
||||
p.addName().addFamily().setValue(theName.getValue());
|
||||
SortSpec sort = theSort;
|
||||
while (sort != null) {
|
||||
|
|
|
@ -61,7 +61,7 @@ public class StringParameterTest {
|
|||
assertEquals(0, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testRawString() throws Exception {
|
||||
{
|
||||
|
@ -104,7 +104,7 @@ public class StringParameterTest {
|
|||
assertEquals(0, new FhirContext().newXmlParser().parseBundle(responseContent).getEntries().size());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() throws Exception {
|
||||
ourServer.stop();
|
||||
|
@ -142,27 +142,32 @@ public class StringParameterTest {
|
|||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
if (theParam.isExact() && theParam.getValue().equals("aaa")) {
|
||||
retVal.add(new Patient());
|
||||
Patient patient = new Patient();
|
||||
patient.setId("1");
|
||||
retVal.add(patient);
|
||||
}
|
||||
if (!theParam.isExact() && theParam.getValue().toLowerCase().equals("aaa")) {
|
||||
retVal.add(new Patient());
|
||||
Patient patient = new Patient();
|
||||
patient.setId("2");
|
||||
retVal.add(patient);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@Search
|
||||
public List<Patient> findPatient(@RequiredParam(name = "plain") String theParam) {
|
||||
ArrayList<Patient> retVal = new ArrayList<Patient>();
|
||||
|
||||
if (theParam.toLowerCase().equals("aaa")) {
|
||||
retVal.add(new Patient());
|
||||
Patient patient = new Patient();
|
||||
patient.setId("1");
|
||||
retVal.add(patient);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Class<? extends IResource> getResourceType() {
|
||||
return Patient.class;
|
||||
|
|
|
@ -194,7 +194,7 @@ public abstract class BaseFhirDao {
|
|||
valueOf = Long.valueOf(id);
|
||||
} catch (Exception e) {
|
||||
String resName = getContext().getResourceDefinition(type).getName();
|
||||
throw new InvalidRequestException("Resource ID " + resName + "/" + id + " is invalid (must be numeric), specified in path: " + nextPath);
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPath + " (this is an invalid ID, must be numeric on this server)");
|
||||
}
|
||||
ResourceTable target = myEntityManager.find(ResourceTable.class, valueOf);
|
||||
if (target == null) {
|
||||
|
|
|
@ -17,6 +17,7 @@ import ca.uhn.fhir.jpa.entity.ResourceTable;
|
|||
import ca.uhn.fhir.model.api.IResource;
|
||||
import ca.uhn.fhir.model.dstu.composite.ResourceReferenceDt;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.util.FhirTerser;
|
||||
|
||||
public class FhirSystemDao extends BaseFhirDao implements IFhirSystemDao {
|
||||
|
@ -66,7 +67,9 @@ public class FhirSystemDao extends BaseFhirDao implements IFhirSystemDao {
|
|||
myEntityManager.flush();
|
||||
}
|
||||
|
||||
idConversions.put(nextId, new IdDt(resourceName + '/' + entity.getId()));
|
||||
IdDt newId = new IdDt(resourceName + '/' + entity.getId());
|
||||
ourLog.info("Incoming ID[{}] has been assigned ID[{}]", nextId, newId);
|
||||
idConversions.put(nextId, newId);
|
||||
persistedResources.add(entity);
|
||||
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import ca.uhn.fhir.model.dstu.resource.Observation;
|
|||
import ca.uhn.fhir.model.dstu.resource.Organization;
|
||||
import ca.uhn.fhir.model.dstu.resource.Patient;
|
||||
import ca.uhn.fhir.model.primitive.IdDt;
|
||||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
|
||||
public class FhirSystemDaoTest {
|
||||
|
||||
|
@ -60,7 +61,7 @@ public class FhirSystemDaoTest {
|
|||
assertEquals(obsVersion, 1L);
|
||||
|
||||
// Try to search
|
||||
|
||||
|
||||
List<Observation> obsResults = ourObservationDao.search(Observation.SP_NAME, new IdentifierDt("urn:system", "testPersistWithSimpleLinkO01"));
|
||||
assertEquals(1, obsResults.size());
|
||||
|
||||
|
@ -72,7 +73,7 @@ public class FhirSystemDaoTest {
|
|||
assertEquals(foundPatientId.getUnqualifiedId(), subject.getResourceId().getUnqualifiedId());
|
||||
|
||||
// Update
|
||||
|
||||
|
||||
patient = patResults.get(0);
|
||||
obs = obsResults.get(0);
|
||||
patient.addIdentifier("urn:system", "testPersistWithSimpleLinkP02");
|
||||
|
@ -92,6 +93,30 @@ public class FhirSystemDaoTest {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPersistWithUnknownId() {
|
||||
Observation obs = new Observation();
|
||||
obs.getName().addCoding().setSystem("urn:system").setCode("testPersistWithSimpleLinkO01");
|
||||
obs.setSubject(new ResourceReferenceDt("Patient/999998888888"));
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(Arrays.asList((IResource) obs));
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Resource Patient/999998888888 not found, specified in path: Observation.subject"));
|
||||
}
|
||||
|
||||
obs = new Observation();
|
||||
obs.getName().addCoding().setSystem("urn:system").setCode("testPersistWithSimpleLinkO01");
|
||||
obs.setSubject(new ResourceReferenceDt("Patient/1.2.3.4"));
|
||||
|
||||
try {
|
||||
ourSystemDao.transaction(Arrays.asList((IResource) obs));
|
||||
} catch (InvalidRequestException e) {
|
||||
assertThat(e.getMessage(), containsString("Resource Patient/1.2.3.4 not found, specified in path: Observation.subject"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void afterClass() {
|
||||
ourCtx.close();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" path="target/generated-resources/tinder"/>
|
||||
<classpathentry kind="src" path="target/generated-sources/tinder"/>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
|
|
|
@ -70,8 +70,6 @@
|
|||
<configuration>
|
||||
<packageBase>ca.uhn.test.jpasrv</packageBase>
|
||||
<baseResourceNames>
|
||||
<!-- <baseResourceName>account</baseResourceName> -->
|
||||
<!-- <baseResourceName>activitydefinition-extensions</baseResourceName> -->
|
||||
<baseResourceName>adversereaction</baseResourceName>
|
||||
<baseResourceName>alert</baseResourceName>
|
||||
<baseResourceName>allergyintolerance</baseResourceName>
|
||||
|
@ -92,7 +90,6 @@
|
|||
<baseResourceName>documentmanifest</baseResourceName>
|
||||
<baseResourceName>documentreference</baseResourceName>
|
||||
<baseResourceName>encounter</baseResourceName>
|
||||
<!-- <baseResourceName>familyhistory-genetics-profile</baseResourceName> -->
|
||||
<baseResourceName>familyhistory</baseResourceName>
|
||||
<baseResourceName>geneexpression</baseResourceName>
|
||||
<baseResourceName>geneticanalysis</baseResourceName>
|
||||
|
@ -112,7 +109,6 @@
|
|||
<baseResourceName>medicationstatement</baseResourceName>
|
||||
<baseResourceName>messageheader</baseResourceName>
|
||||
<baseResourceName>microarray</baseResourceName>
|
||||
<!-- <baseResourceName>namespace</baseResourceName> -->
|
||||
<baseResourceName>observation</baseResourceName>
|
||||
<baseResourceName>operationoutcome</baseResourceName>
|
||||
<baseResourceName>orderresponse</baseResourceName>
|
||||
|
@ -120,34 +116,24 @@
|
|||
<baseResourceName>organization</baseResourceName>
|
||||
<baseResourceName>other</baseResourceName>
|
||||
<baseResourceName>patient</baseResourceName>
|
||||
<!--<baseResourceName>person</baseResourceName>-->
|
||||
<baseResourceName>practitioner</baseResourceName>
|
||||
<baseResourceName>procedure</baseResourceName>
|
||||
<baseResourceName>profile</baseResourceName>
|
||||
<!-- <baseResourceName>protocol</baseResourceName> -->
|
||||
<!-- <baseResourceName>provenance-extensions</baseResourceName> -->
|
||||
<baseResourceName>provenance</baseResourceName>
|
||||
<baseResourceName>query</baseResourceName>
|
||||
<!-- <baseResourceName>questionnaire-extensions</baseResourceName> -->
|
||||
<baseResourceName>questionnaire</baseResourceName>
|
||||
<baseResourceName>relatedperson</baseResourceName>
|
||||
<baseResourceName>remittance</baseResourceName>
|
||||
<!-- <baseResourceName>resource</baseResourceName> -->
|
||||
<baseResourceName>securityevent</baseResourceName>
|
||||
<!--<baseResourceName>sequence</baseResourceName>-->
|
||||
<baseResourceName>sequencinganalysis</baseResourceName>
|
||||
<baseResourceName>sequencinglab</baseResourceName>
|
||||
<baseResourceName>slot</baseResourceName>
|
||||
<baseResourceName>specimen</baseResourceName>
|
||||
<baseResourceName>substance</baseResourceName>
|
||||
<baseResourceName>supply</baseResourceName>
|
||||
<!--<baseResourceName>template</baseResourceName>-->
|
||||
<baseResourceName>test</baseResourceName>
|
||||
<!-- <baseResourceName>test</baseResourceName> -->
|
||||
<baseResourceName>user</baseResourceName>
|
||||
<!-- <baseResourceName>valueset-extensions</baseResourceName> -->
|
||||
<baseResourceName>valueset</baseResourceName>
|
||||
<!--<baseResourceName>vcfmeta</baseResourceName>-->
|
||||
<!--<baseResourceName>vcfvariant</baseResourceName>-->
|
||||
</baseResourceNames>
|
||||
<buildDatatypes>true</buildDatatypes>
|
||||
</configuration>
|
||||
|
@ -162,6 +148,7 @@
|
|||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<finalName>hapi-fhir-jpaserver</finalName>
|
||||
</build>
|
||||
|
||||
<packaging>war</packaging>
|
||||
|
|
|
@ -28,7 +28,7 @@ public class TestRestfulServer extends RestfulServer {
|
|||
ourLog.info("Failed to create database: {}",e.getMessage());
|
||||
}
|
||||
|
||||
myAppCtx = new ClassPathXmlApplicationContext("fhir-spring-uhnfhirtest-config.xml");
|
||||
myAppCtx = new ClassPathXmlApplicationContext("fhir-spring-uhnfhirtest-config.xml", "hapi-jpaserver-springbeans.xml");
|
||||
|
||||
Collection<IResourceProvider> beans = myAppCtx.getBeansOfType(IResourceProvider.class).values();
|
||||
for (IResourceProvider nextResourceProvider : beans) {
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
package ca.uhn.fhirtest;
|
||||
|
||||
import ca.uhn.fhir.rest.server.tester.RestfulServerTesterServlet;
|
||||
|
||||
public class TesterServlet extends RestfulServerTesterServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public TesterServlet() {
|
||||
String baseUrl = System.getProperty("fhir.baseurl");
|
||||
setServerBase(baseUrl);
|
||||
}
|
||||
|
||||
}
|
|
@ -13,47 +13,7 @@
|
|||
<context:annotation-config />
|
||||
<context:mbean-server />
|
||||
|
||||
<bean id="myDiagnosticReportDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.DiagnosticReport"/>
|
||||
</bean>
|
||||
<bean id="myDiagnosticReportRp" class="ca.uhn.test.jpasrv.DiagnosticReportResourceProvider">
|
||||
<property name="dao" ref="myDiagnosticReportDao"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myPatientDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.Patient"/>
|
||||
</bean>
|
||||
<bean id="myPatientRp" class="ca.uhn.test.jpasrv.PatientResourceProvider">
|
||||
<property name="dao" ref="myPatientDao"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myObservationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.Observation"/>
|
||||
</bean>
|
||||
<bean id="myObservationRp" class="ca.uhn.test.jpasrv.ObservationResourceProvider">
|
||||
<property name="dao" ref="myObservationDao"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myOrganizationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.Organization"/>
|
||||
</bean>
|
||||
<bean id="myOrganizationRp" class="ca.uhn.test.jpasrv.OrganizationResourceProvider">
|
||||
<property name="dao" ref="myOrganizationDao"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myLocationDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.Location"/>
|
||||
</bean>
|
||||
<bean id="myLocationRp" class="ca.uhn.test.jpasrv.LocationResourceProvider">
|
||||
<property name="dao" ref="myLocationDao"/>
|
||||
</bean>
|
||||
|
||||
<bean id="myQuestionnaireDao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.Questionnaire"/>
|
||||
</bean>
|
||||
<bean id="myQuestionnaireRp" class="ca.uhn.test.jpasrv.QuestionnaireResourceProvider">
|
||||
<property name="dao" ref="myQuestionnaireDao"/>
|
||||
</bean>
|
||||
<!-- <import resource="classpath:hapi-jpaserver-springbeans.xml" /> -->
|
||||
|
||||
<bean id="mySystemDao" class="ca.uhn.fhir.jpa.dao.FhirSystemDao">
|
||||
</bean>
|
||||
|
|
|
@ -9,9 +9,20 @@
|
|||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>testerServlet</servlet-name>
|
||||
<servlet-class>ca.uhn.fhirtest.TesterServlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>fhirServlet</servlet-name>
|
||||
<url-pattern>/base/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>testerServlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package ca.uhn.fhir.tinder;
|
||||
|
||||
import static org.apache.commons.lang.StringUtils.defaultString;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
|
@ -8,8 +10,10 @@ import java.io.InputStreamReader;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.http.ParseException;
|
||||
import org.apache.maven.model.Resource;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
|
@ -21,19 +25,9 @@ import org.apache.maven.project.MavenProject;
|
|||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
|
||||
import ca.uhn.fhir.context.FhirContext;
|
||||
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.api.IBasicClient;
|
||||
import ca.uhn.fhir.tinder.model.BaseRootType;
|
||||
import ca.uhn.fhir.tinder.model.RestResourceTm;
|
||||
import ca.uhn.fhir.tinder.model.SearchParameter;
|
||||
import ca.uhn.fhir.tinder.parser.ProfileParser;
|
||||
import ca.uhn.fhir.tinder.model.Extension;
|
||||
import ca.uhn.fhir.tinder.parser.ResourceGeneratorUsingSpreadsheet;
|
||||
import edu.emory.mathcs.backport.java.util.Collections;
|
||||
|
||||
@Mojo(name = "generate-jparest-server", defaultPhase = LifecyclePhase.GENERATE_SOURCES)
|
||||
public class TinderJpaRestServerMojo extends AbstractMojo {
|
||||
|
@ -43,6 +37,12 @@ public class TinderJpaRestServerMojo extends AbstractMojo {
|
|||
@Parameter(required = true, defaultValue = "${project.build.directory}/generated-sources/tinder")
|
||||
private File targetDirectory;
|
||||
|
||||
@Parameter(required = true, defaultValue = "${project.build.directory}/generated-resources/tinder")
|
||||
private File targetResourceDirectory;
|
||||
|
||||
@Parameter(required = true, defaultValue = "hapi-jpaserver-springbeans.xml")
|
||||
private String targetResourceSpringBeansFile;
|
||||
|
||||
@Parameter(required = true)
|
||||
private String packageBase;
|
||||
|
||||
|
@ -57,55 +57,78 @@ public class TinderJpaRestServerMojo extends AbstractMojo {
|
|||
|
||||
File directoryBase = new File(targetDirectory, packageBase.replace(".", File.separatorChar + ""));
|
||||
directoryBase.mkdirs();
|
||||
|
||||
|
||||
ResourceGeneratorUsingSpreadsheet gen = new ResourceGeneratorUsingSpreadsheet();
|
||||
gen.setBaseResourceNames(baseResourceNames);
|
||||
|
||||
|
||||
try {
|
||||
gen.parse();
|
||||
|
||||
|
||||
gen.setFilenameSuffix("ResourceProvider");
|
||||
gen.setTemplate("/vm/jpa_resource_provider.vm");
|
||||
gen.writeAll(directoryBase, packageBase);
|
||||
|
||||
// gen.setFilenameSuffix("ResourceTable");
|
||||
// gen.setTemplate("/vm/jpa_resource_table.vm");
|
||||
// gen.writeAll(directoryBase, packageBase);
|
||||
|
||||
|
||||
// gen.setFilenameSuffix("ResourceTable");
|
||||
// gen.setTemplate("/vm/jpa_resource_table.vm");
|
||||
// gen.writeAll(directoryBase, packageBase);
|
||||
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to generate server",e);
|
||||
throw new MojoFailureException("Failed to generate server", e);
|
||||
}
|
||||
|
||||
myProject.addCompileSourceRoot(directoryBase.getAbsolutePath());
|
||||
|
||||
try {
|
||||
VelocityContext ctx = new VelocityContext();
|
||||
ctx.put("resources", gen.getResources());
|
||||
|
||||
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/jpa_spring_beans.vm");
|
||||
InputStreamReader templateReader = new InputStreamReader(templateIs);
|
||||
|
||||
targetResourceDirectory.mkdirs();
|
||||
FileWriter w = new FileWriter(new File(targetResourceDirectory, targetResourceSpringBeansFile));
|
||||
v.evaluate(ctx, w, "", templateReader);
|
||||
|
||||
w.close();
|
||||
|
||||
Resource resource = new Resource();
|
||||
resource.setDirectory(targetResourceDirectory.getAbsolutePath());
|
||||
resource.addInclude(targetResourceSpringBeansFile);
|
||||
myProject.addResource(resource);
|
||||
} catch (Exception e) {
|
||||
throw new MojoFailureException("Failed to generate server", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void write() throws IOException {
|
||||
// File directoryBase;
|
||||
// directoryBase.mkdirs();
|
||||
//
|
||||
// File file = new File(directoryBase, myClientClassSimpleName + ".java");
|
||||
// FileWriter w = new FileWriter(file, false);
|
||||
//
|
||||
// ourLog.info("Writing file: {}", file.getAbsolutePath());
|
||||
//
|
||||
// VelocityContext ctx = new VelocityContext();
|
||||
// ctx.put("packageBase", packageBase);
|
||||
// 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();
|
||||
// File directoryBase;
|
||||
// directoryBase.mkdirs();
|
||||
//
|
||||
// File file = new File(directoryBase, myClientClassSimpleName + ".java");
|
||||
// FileWriter w = new FileWriter(file, false);
|
||||
//
|
||||
// ourLog.info("Writing file: {}", file.getAbsolutePath());
|
||||
//
|
||||
// VelocityContext ctx = new VelocityContext();
|
||||
// ctx.put("packageBase", packageBase);
|
||||
// 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 {
|
||||
|
@ -127,7 +150,7 @@ public class TinderJpaRestServerMojo extends AbstractMojo {
|
|||
|
||||
TinderJpaRestServerMojo mojo = new TinderJpaRestServerMojo();
|
||||
mojo.packageBase = "ca.uhn.test";
|
||||
mojo.baseResourceNames =java.util.Collections.singletonList("patient");
|
||||
mojo.baseResourceNames = java.util.Collections.singletonList("patient");
|
||||
mojo.targetDirectory = new File("target/gen");
|
||||
mojo.execute();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xmlns:util="http://www.springframework.org/schema/util"
|
||||
default-autowire="no" default-lazy-init="false"
|
||||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd
|
||||
"
|
||||
>
|
||||
|
||||
#foreach ( $res in $resources )
|
||||
|
||||
<bean id="my${res.name}Dao" class="ca.uhn.fhir.jpa.dao.FhirResourceDao">
|
||||
<property name="resourceType" value="ca.uhn.fhir.model.dstu.resource.${res.declaringClassNameComplete}"/>
|
||||
</bean>
|
||||
<bean id="my${res.name}Rp" class="ca.uhn.test.jpasrv.${res.declaringClassNameComplete}ResourceProvider">
|
||||
<property name="dao" ref="my${res.name}Dao"/>
|
||||
</bean>
|
||||
|
||||
#end
|
||||
|
||||
</beans>
|
Loading…
Reference in New Issue