Merge remote-tracking branch 'remotes/origin/master' into ks-subscription-delivery-queue-configurable-name

This commit is contained in:
Ken Stevens 2019-10-01 09:20:00 -04:00
commit ade9e0316e
21 changed files with 495 additions and 327 deletions

View File

@ -66,13 +66,17 @@ public abstract class BaseRuntimeChildDefinition {
}
public interface IAccessor {
List<IBase> getValues(Object theTarget);
List<IBase> getValues(IBase theTarget);
default IBase getFirstValueOrNull(IBase theTarget) {
return getValues(theTarget).stream().findFirst().orElse(null);
}
}
public interface IMutator {
void addValue(Object theTarget, IBase theValue);
void addValue(IBase theTarget, IBase theValue);
void setValue(Object theTarget, IBase theValue);
void setValue(IBase theTarget, IBase theValue);
}
BaseRuntimeElementDefinition<?> findResourceReferenceDefinition(Map<Class<? extends IBase>, BaseRuntimeElementDefinition<?>> theClassToElementDefinitions) {

View File

@ -20,34 +20,33 @@ package ca.uhn.fhir.context;
* #L%
*/
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.util.ValidateUtil;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBase;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBase;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.api.annotation.Description;
import ca.uhn.fhir.util.ValidateUtil;
public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChildDefinition {
private final IAccessor myAccessor;
private String myBindingValueSet;
private final String myElementName;
private final Field myField;
private final String myFormalDefinition;
private final int myMax;
private final int myMin;
private boolean myModifier;
private final IMutator myMutator;
private final String myShortDefinition;
private String myBindingValueSet;
private boolean myModifier;
private boolean mySummary;
BaseRuntimeDeclaredChildDefinition(Field theField, Child theChildAnnotation, Description theDescriptionAnnotation, String theElementName) throws ConfigurationException {
super();
Validate.notNull(theField, "No field speficied");
Validate.notNull(theField, "No field specified");
ValidateUtil.isGreaterThanOrEqualTo(theChildAnnotation.min(), 0, "Min must be >= 0");
Validate.isTrue(theChildAnnotation.max() == -1 || theChildAnnotation.max() >= theChildAnnotation.min(), "Max must be >= Min (unless it is -1 / unlimited)");
Validate.notBlank(theElementName, "Element name must not be blank");
@ -87,6 +86,10 @@ public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChil
return myBindingValueSet;
}
void setBindingValueSet(String theBindingValueSet) {
myBindingValueSet = theBindingValueSet;
}
@Override
public String getElementName() {
return myElementName;
@ -119,107 +122,99 @@ public abstract class BaseRuntimeDeclaredChildDefinition extends BaseRuntimeChil
return myShortDefinition;
}
public BaseRuntimeElementDefinition<?> getSingleChildOrThrow() {
if (getValidChildNames().size() != 1) {
throw new IllegalStateException("This child has " + getValidChildNames().size() + " children, expected 1. This is a HAPI bug. Found: " + getValidChildNames());
}
return getChildByName(getValidChildNames().iterator().next());
}
public boolean isModifier() {
return myModifier;
}
protected void setModifier(boolean theModifier) {
myModifier = theModifier;
}
@Override
public boolean isSummary() {
return mySummary;
}
void setBindingValueSet(String theBindingValueSet) {
myBindingValueSet = theBindingValueSet;
}
protected void setModifier(boolean theModifier) {
myModifier = theModifier;
}
private final class FieldListAccessor implements IAccessor {
@SuppressWarnings("unchecked")
@Override
public List<IBase> getValues(Object theTarget) {
List<IBase> retVal;
try {
retVal = (List<IBase>) myField.get(theTarget);
} catch (Exception e) {
throw new ConfigurationException("Failed to get value", e);
}
public List<IBase> getValues(IBase theTarget) {
List<IBase> retVal = (List<IBase>) getFieldValue(theTarget, myField);
if (retVal == null) {
retVal = Collections.emptyList();
}
return retVal;
}
}
protected final class FieldListMutator implements IMutator {
@Override
public void addValue(Object theTarget, IBase theValue) {
public void addValue(IBase theTarget, IBase theValue) {
addValue(theTarget, theValue, false);
}
private void addValue(Object theTarget, IBase theValue, boolean theClear) {
try {
private void addValue(IBase theTarget, IBase theValue, boolean theClear) {
@SuppressWarnings("unchecked")
List<IBase> existingList = (List<IBase>) myField.get(theTarget);
List<IBase> existingList = (List<IBase>) getFieldValue(theTarget, myField);
if (existingList == null) {
existingList = new ArrayList<IBase>(2);
myField.set(theTarget, existingList);
existingList = new ArrayList<>(2);
setFieldValue(theTarget, existingList, myField);
}
if (theClear) {
existingList.clear();
}
existingList.add(theValue);
} catch (Exception e) {
throw new ConfigurationException("Failed to set value", e);
}
}
@Override
public void setValue(Object theTarget, IBase theValue) {
public void setValue(IBase theTarget, IBase theValue) {
addValue(theTarget, theValue, true);
}
}
private final class FieldPlainAccessor implements IAccessor {
@Override
public List<IBase> getValues(Object theTarget) {
try {
Object values = myField.get(theTarget);
public List<IBase> getValues(IBase theTarget) {
Object values = getFieldValue(theTarget, myField);
if (values == null) {
return Collections.emptyList();
}
List<IBase> retVal = Collections.singletonList((IBase) values);
return retVal;
} catch (Exception e) {
throw new ConfigurationException("Failed to get value", e);
return Collections.singletonList((IBase) values);
}
@Override
public IBase getFirstValueOrNull(IBase theTarget) {
return (IBase) getFieldValue(theTarget, myField);
}
}
protected final class FieldPlainMutator implements IMutator {
@Override
public void addValue(Object theTarget, IBase theValue) {
try {
myField.set(theTarget, theValue);
} catch (Exception e) {
throw new ConfigurationException("Failed to set value", e);
}
public void addValue(IBase theTarget, IBase theValue) {
setFieldValue(theTarget, theValue, myField);
}
@Override
public void setValue(Object theTarget, IBase theValue) {
public void setValue(IBase theTarget, IBase theValue) {
addValue(theTarget, theValue);
}
}
private static void setFieldValue(IBase theTarget, Object theValue, Field theField) {
try {
theField.set(theTarget, theValue);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Failed to set value", e);
}
}
private static Object getFieldValue(IBase theTarget, Field theField) {
try {
return theField.get(theTarget);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Failed to get value", e);
}
}
}

View File

@ -68,7 +68,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
public IAccessor getAccessor() {
return new IAccessor() {
@Override
public List<IBase> getValues(Object theTarget) {
public List<IBase> getValues(IBase theTarget) {
ExtensionDt target = (ExtensionDt) theTarget;
if (target.getValue() != null) {
return Collections.singletonList((IBase) target.getValue());
@ -76,6 +76,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
ArrayList<IBase> retVal = new ArrayList<IBase>(target.getUndeclaredExtensions());
return retVal;
}
};
}
@ -113,7 +114,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
public IMutator getMutator() {
return new IMutator() {
@Override
public void addValue(Object theTarget, IBase theValue) {
public void addValue(IBase theTarget, IBase theValue) {
ExtensionDt target = (ExtensionDt) theTarget;
if (theValue instanceof IDatatype) {
target.setValue((IDatatype) theTarget);
@ -123,7 +124,7 @@ public class RuntimeChildUndeclaredExtensionDefinition extends BaseRuntimeChildD
}
@Override
public void setValue(Object theTarget, IBase theValue) {
public void setValue(IBase theTarget, IBase theValue) {
ExtensionDt target = (ExtensionDt) theTarget;
if (theValue instanceof IDatatype) {
target.setValue((IDatatype) theTarget);

View File

@ -19,17 +19,6 @@ package ca.uhn.fhir.parser;
* limitations under the License.
* #L%
*/
import static org.apache.commons.lang3.StringUtils.*;
import java.util.*;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.instance.model.api.*;
import ca.uhn.fhir.context.*;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition.IMutator;
@ -37,21 +26,32 @@ import ca.uhn.fhir.model.api.*;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.ResourceMetadataMap;
import ca.uhn.fhir.model.primitive.*;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.XhtmlDt;
import ca.uhn.fhir.parser.json.JsonLikeValue.ScalarType;
import ca.uhn.fhir.parser.json.JsonLikeValue.ValueType;
import ca.uhn.fhir.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.tuple.Pair;
import org.hl7.fhir.instance.model.api.*;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import java.util.*;
import static org.apache.commons.lang3.StringUtils.*;
class ParserState<T> {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ParserState.class);
private List<String> myComments = new ArrayList<String>(2);
private final FhirContext myContext;
private final IParserErrorHandler myErrorHandler;
private final boolean myJsonMode;
private T myObject;
private final IParser myParser;
private List<String> myComments = new ArrayList<String>(2);
private T myObject;
private IBase myPreviousElement;
private BaseState myState;
@ -152,38 +152,6 @@ class ParserState<T> {
}
}
/**
* @param theResourceType
* May be null
*/
static <T extends IBaseResource> ParserState<T> getPreResourceInstance(IParser theParser, Class<T> theResourceType, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler)
throws DataFormatException {
ParserState<T> retVal = new ParserState<T>(theParser, theContext, theJsonMode, theErrorHandler);
if (theResourceType == null) {
if (theContext.getVersion().getVersion().isRi()) {
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
} else {
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
}
} else {
if (IResource.class.isAssignableFrom(theResourceType)) {
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
} else {
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
}
}
return retVal;
}
static ParserState<TagList> getPreTagListInstance(IParser theParser, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) {
ParserState<TagList> retVal = new ParserState<TagList>(theParser, theContext, theJsonMode, theErrorHandler);
retVal.push(retVal.new PreTagListState());
return retVal;
}
private abstract class BaseState {
private PreResourceState myPreResourceState;
@ -195,8 +163,7 @@ class ParserState<T> {
}
/**
* @param theValue
* The attribute value
* @param theValue The attribute value
*/
public void attributeValue(String theName, String theValue) throws DataFormatException {
myErrorHandler.unknownAttribute(null, theName);
@ -211,8 +178,7 @@ class ParserState<T> {
}
/**
* @param theNamespaceUri
* The XML namespace (if XML) or null
* @param theNamespaceUri The XML namespace (if XML) or null
*/
public void enteringNewElement(String theNamespaceUri, String theLocalPart) throws DataFormatException {
myErrorHandler.unknownElement(null, theLocalPart);
@ -275,8 +241,7 @@ class ParserState<T> {
}
/**
* @param theData
* The string value
* @param theData The string value
*/
public void string(String theData) {
// ignore by default
@ -287,8 +252,7 @@ class ParserState<T> {
}
/**
* @param theNextEvent
* The XML event
* @param theNextEvent The XML event
*/
public void xmlEvent(XMLEvent theNextEvent) {
// ignore
@ -890,7 +854,6 @@ class ParserState<T> {
}
private abstract class PreResourceState extends BaseState {
private Map<String, IBaseResource> myContainedResources;
@ -1137,7 +1100,7 @@ class ParserState<T> {
private class PreResourceStateHapi extends PreResourceState {
private IMutator myMutator;
private Object myTarget;
private IBase myTarget;
public PreResourceStateHapi(Class<? extends IBaseResource> theResourceType) {
@ -1145,7 +1108,7 @@ class ParserState<T> {
assert theResourceType == null || IResource.class.isAssignableFrom(theResourceType);
}
public PreResourceStateHapi(Object theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
public PreResourceStateHapi(IBase theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
myTarget = theTarget;
myMutator = theMutator;
@ -1195,13 +1158,13 @@ class ParserState<T> {
private class PreResourceStateHl7Org extends PreResourceState {
private IMutator myMutator;
private Object myTarget;
private IBase myTarget;
public PreResourceStateHl7Org(Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
}
public PreResourceStateHl7Org(Object theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
public PreResourceStateHl7Org(IBase theTarget, IMutator theMutator, Class<? extends IBaseResource> theResourceType) {
super(theResourceType);
myMutator = theMutator;
myTarget = theTarget;
@ -1604,4 +1567,32 @@ class ParserState<T> {
}
/**
* @param theResourceType May be null
*/
static <T extends IBaseResource> ParserState<T> getPreResourceInstance(IParser theParser, Class<T> theResourceType, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler)
throws DataFormatException {
ParserState<T> retVal = new ParserState<T>(theParser, theContext, theJsonMode, theErrorHandler);
if (theResourceType == null) {
if (theContext.getVersion().getVersion().isRi()) {
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
} else {
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
}
} else {
if (IResource.class.isAssignableFrom(theResourceType)) {
retVal.push(retVal.new PreResourceStateHapi(theResourceType));
} else {
retVal.push(retVal.new PreResourceStateHl7Org(theResourceType));
}
}
return retVal;
}
static ParserState<TagList> getPreTagListInstance(IParser theParser, FhirContext theContext, boolean theJsonMode, IParserErrorHandler theErrorHandler) {
ParserState<TagList> retVal = new ParserState<TagList>(theParser, theContext, theJsonMode, theErrorHandler);
retVal.push(retVal.new PreTagListState());
return retVal;
}
}

View File

@ -354,17 +354,10 @@ public class XmlParser extends BaseParser {
}
if (nextChild instanceof RuntimeChildNarrativeDefinition) {
INarrative narr = (INarrative) nextChild.getAccessor().getFirstValueOrNull(theElement);
INarrativeGenerator gen = myContext.getNarrativeGenerator();
INarrative narr;
if (theResource instanceof IResource) {
narr = ((IResource) theResource).getText();
} else if (theResource instanceof IDomainResource) {
narr = ((IDomainResource) theResource).getText();
} else {
narr = null;
}
// FIXME potential null access on narr see line 623
if (gen != null && narr.isEmpty()) {
if (gen != null && (narr == null || narr.isEmpty())) {
gen.populateResourceNarrative(myContext, theResource);
}
if (narr != null && narr.isEmpty() == false) {

View File

@ -216,12 +216,12 @@ public class FhirTerser {
}
public Object getSingleValueOrNull(IBase theTarget, String thePath) {
Class<Object> wantedType = Object.class;
Class<IBase> wantedType = IBase.class;
return getSingleValueOrNull(theTarget, thePath, wantedType);
}
public <T> T getSingleValueOrNull(IBase theTarget, String thePath, Class<T> theWantedType) {
public <T extends IBase> T getSingleValueOrNull(IBase theTarget, String thePath, Class<T> theWantedType) {
Validate.notNull(theTarget, "theTarget must not be null");
Validate.notBlank(thePath, "thePath must not be empty");
@ -241,12 +241,12 @@ public class FhirTerser {
return retVal.get(0);
}
private <T> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, Object theCurrentObj, List<String> theSubList, Class<T> theWantedClass) {
private <T extends IBase> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, IBase theCurrentObj, List<String> theSubList, Class<T> theWantedClass) {
return getValues(theCurrentDef, theCurrentObj, theSubList, theWantedClass, false, false);
}
@SuppressWarnings("unchecked")
private <T> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, Object theCurrentObj, List<String> theSubList, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
private <T extends IBase> List<T> getValues(BaseRuntimeElementCompositeDefinition<?> theCurrentDef, IBase theCurrentObj, List<String> theSubList, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
String name = theSubList.get(0);
List<T> retVal = new ArrayList<>();
@ -325,7 +325,7 @@ public class FhirTerser {
List<T> values = retVal;
retVal = new ArrayList<>();
for (T nextElement : values) {
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition((Class<? extends IBase>) nextElement.getClass());
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(nextElement.getClass());
List<T> foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate, theAddExtension);
retVal.addAll(foundValues);
}
@ -410,7 +410,7 @@ public class FhirTerser {
List<T> values = retVal;
retVal = new ArrayList<>();
for (T nextElement : values) {
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition((Class<? extends IBase>) nextElement.getClass());
BaseRuntimeElementCompositeDefinition<?> nextChildDef = (BaseRuntimeElementCompositeDefinition<?>) myContext.getElementDefinition(nextElement.getClass());
List<T> foundValues = getValues(nextChildDef, nextElement, theSubList.subList(1, theSubList.size()), theWantedClass, theCreate, theAddExtension);
retVal.addAll(foundValues);
}
@ -476,9 +476,10 @@ public class FhirTerser {
* @return A list of values of type {@link Object}.
*/
public List<Object> getValues(IBaseResource theResource, String thePath) {
Class<Object> wantedClass = Object.class;
Class<IBase> wantedClass = IBase.class;
return getValues(theResource, thePath, wantedClass);
List values = getValues(theResource, thePath, wantedClass);
return values;
}
/**
@ -491,9 +492,10 @@ public class FhirTerser {
* @return A list of values of type {@link Object}.
*/
public List<Object> getValues(IBaseResource theResource, String thePath, boolean theCreate) {
Class<Object> wantedClass = Object.class;
Class<IBase> wantedClass = IBase.class;
return getValues(theResource, thePath, wantedClass, theCreate);
List retVal = getValues(theResource, thePath, wantedClass, theCreate);
return retVal;
}
/**
@ -507,9 +509,10 @@ public class FhirTerser {
* @return A list of values of type {@link Object}.
*/
public List<Object> getValues(IBaseResource theResource, String thePath, boolean theCreate, boolean theAddExtension) {
Class<Object> wantedClass = Object.class;
Class<IBase> wantedClass = IBase.class;
return getValues(theResource, thePath, wantedClass, theCreate, theAddExtension);
List retVal = getValues(theResource, thePath, wantedClass, theCreate, theAddExtension);
return retVal;
}
/**
@ -522,7 +525,7 @@ public class FhirTerser {
* @param <T> Type declared by <code>theWantedClass</code>
* @return A list of values of type <code>theWantedClass</code>.
*/
public <T> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass) {
public <T extends IBase> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass) {
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
List<String> parts = parsePath(def, thePath);
return getValues(def, theResource, parts, theWantedClass);
@ -539,7 +542,7 @@ public class FhirTerser {
* @param <T> Type declared by <code>theWantedClass</code>
* @return A list of values of type <code>theWantedClass</code>.
*/
public <T> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate) {
public <T extends IBase> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate) {
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
List<String> parts = parsePath(def, thePath);
return getValues(def, theResource, parts, theWantedClass, theCreate, false);
@ -557,7 +560,7 @@ public class FhirTerser {
* @param <T> Type declared by <code>theWantedClass</code>
* @return A list of values of type <code>theWantedClass</code>.
*/
public <T> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
public <T extends IBase> List<T> getValues(IBaseResource theResource, String thePath, Class<T> theWantedClass, boolean theCreate, boolean theAddExtension) {
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
List<String> parts = parsePath(def, thePath);
return getValues(def, theResource, parts, theWantedClass, theCreate, theAddExtension);

View File

@ -276,6 +276,12 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
@ -500,6 +506,12 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-elasticsearch</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Misc -->

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.dao;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2019 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 ca.uhn.fhir.jpa.model.entity.ResourceTable;
import ca.uhn.fhir.rest.api.server.RequestDetails;
import org.hl7.fhir.instance.model.api.IBaseResource;

View File

@ -1,5 +1,25 @@
package ca.uhn.fhir.jpa.search.elastic;
/*-
* #%L
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2019 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 org.hibernate.search.cfg.Environment;
import org.hibernate.search.elasticsearch.cfg.ElasticsearchEnvironment;
import org.hibernate.search.elasticsearch.cfg.ElasticsearchIndexStatus;

View File

@ -2,7 +2,7 @@ package ca.uhn.fhir.jpa.search.elastic;
/*-
* #%L
* HAPI FHIR JPA Server - ElasticSearch Integration
* HAPI FHIR JPA Server
* %%
* Copyright (C) 2014 - 2019 University Health Network
* %%

View File

@ -80,7 +80,6 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
bulkExportJob.addIndex("IDX_BLKEX_EXPTIME").unique(false).withColumns("EXP_TIME");
bulkExportJob.addIndex("IDX_BLKEX_JOB_ID").unique(true).withColumns("JOB_ID");
// HFJ_BLK_EXPORT_COLLECTION
version.addIdGenerator("SEQ_BLKEXCOL_PID");
Builder.BuilderAddTableByColumns bulkExportCollection = version.addTableByColumns("HFJ_BLK_EXPORT_COLLECTION", "PID");
@ -99,7 +98,7 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
bulkExportCollectionFile.addColumn("RES_ID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, 100);
bulkExportCollectionFile.addForeignKey("FK_BLKEXCOLFILE_COLLECT").toColumn("COLLECTION_PID").references("HFJ_BLK_EXPORT_COLLECTION", "PID");
// HFJ_RES_VER_PROV
version.startSectionWithMessage("Processing bulkExportCollectionFile: HFJ_RES_VER_PROV");
Builder.BuilderAddTableByColumns resVerProv = version.addTableByColumns("HFJ_RES_VER_PROV", "RES_VER_PID");
resVerProv.addColumn("RES_VER_PID").nonNullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.LONG);
@ -149,7 +148,6 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
.unique(true)
.withColumns("VALUESET_PID", "VALUESET_ORDER");
// Account for RESTYPE_LEN column increasing from 30 to 35
version.onTable("HFJ_RESOURCE").modifyColumn("RES_TYPE").nonNullable().withType(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, 35);
version.onTable("HFJ_HISTORY_TAG").modifyColumn("RES_TYPE").nonNullable().withType(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, 35);
@ -165,8 +163,9 @@ public class HapiFhirJpaMigrationTasks extends BaseMigrationTasks<VersionEnum> {
version.startSectionWithMessage("Processing table: TRM_VALUESET_C_DESIGNATION");
version.onTable("TRM_VALUESET_C_DESIGNATION").modifyColumn("VAL").nonNullable().withType(BaseTableColumnTypeTask.ColumnTypeEnum.STRING, 2000);
// TermConceptProperty
version.startSectionWithMessage("Processing table: TRM_CONCEPT_PROPERTY");
version.onTable("TRM_CONCEPT_PROPERTY").addColumn("PROP_VAL_LOB").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.CLOB);
version.onTable("TRM_CONCEPT_PROPERTY").addColumn("PROP_VAL_LOB").nullable().type(BaseTableColumnTypeTask.ColumnTypeEnum.BLOB);
}
protected void init400() {

View File

@ -319,6 +319,29 @@ public class JsonParserDstu3Test {
}
/**
* See #402
*/
@Test
public void testEncodeCompositionDoesntOverwriteNarrative() {
FhirContext ctx = FhirContext.forDstu3();
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
Composition composition = new Composition();
composition.getText().setDivAsString("<div>root</div>");
composition.addSection().getText().setDivAsString("<div>section0</div>");
composition.addSection().getText().setDivAsString("<div>section1</div>");
String output = ctx.newJsonParser().setPrettyPrint(true).encodeResourceToString(composition);
ourLog.info(output);
assertThat(output, containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">root</div>"));
assertThat(output, containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">section0</div>"));
assertThat(output, containsString("<div xmlns=\\\"http://www.w3.org/1999/xhtml\\\">section1</div>"));
}
@Test
public void testEncodeAndParseMetaProfileAndTags() {
Patient p = new Patient();

View File

@ -1070,6 +1070,28 @@ public class XmlParserDstu3Test {
assertEquals("grandparent", gp.getName());
}
/**
* See #402
*/
@Test
public void testEncodeCompositionDoesntOverwriteNarrative() {
FhirContext ctx = FhirContext.forDstu3();
ctx.setNarrativeGenerator(new DefaultThymeleafNarrativeGenerator());
Composition composition = new Composition();
composition.getText().setDivAsString("<div>root</div>");
composition.addSection().getText().setDivAsString("<div>section0</div>");
composition.addSection().getText().setDivAsString("<div>section1</div>");
String output = ctx.newXmlParser().setPrettyPrint(true).encodeResourceToString(composition);
ourLog.info(output);
assertThat(output, containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">root</div>"));
assertThat(output, containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">section0</div>"));
assertThat(output, containsString("<div xmlns=\"http://www.w3.org/1999/xhtml\">section1</div>"));
}
/**
* See #326
*/

View File

@ -448,6 +448,34 @@ public class JsonParserR4Test {
}
private Composition createComposition(String sectionText) {
Composition c = new Composition();
Narrative compositionText = new Narrative().setStatus(Narrative.NarrativeStatus.GENERATED);
compositionText.setDivAsString("Composition");
Narrative compositionSectionText = new Narrative().setStatus(Narrative.NarrativeStatus.GENERATED);
compositionSectionText.setDivAsString(sectionText);
c.setText(compositionText);
c.addSection().setText(compositionSectionText);
return c;
}
/**
* See #402 (however JSON is fine)
*/
@Test
public void testEncodingTextSection() {
String sectionText = "sectionText";
Composition composition = createComposition(sectionText);
String encoded = ourCtx.newJsonParser().encodeResourceToString(composition);
ourLog.info(encoded);
int idx = encoded.indexOf(sectionText);
assertNotEquals(-1, idx);
}
/**
* 2019-09-19 - Pre #1489
* 18:24:48.548 [main] INFO ca.uhn.fhir.parser.JsonParserR4Test [JsonParserR4Test.java:483] - Encoded 200 passes - 50ms / pass - 19.7 / second

View File

@ -0,0 +1,45 @@
package ca.uhn.fhir.parser;
import static org.junit.Assert.assertNotEquals;
import org.hl7.fhir.r4.model.Composition;
import org.hl7.fhir.r4.model.Narrative;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ca.uhn.fhir.context.FhirContext;
public class XmlParserR4Test {
private static final Logger ourLog = LoggerFactory.getLogger(XmlParserR4Test.class);
private static FhirContext ourCtx = FhirContext.forR4();
private Composition createComposition(String sectionText) {
Composition c = new Composition();
Narrative compositionText = new Narrative().setStatus(Narrative.NarrativeStatus.GENERATED);
compositionText.setDivAsString("Composition");
Narrative compositionSectionText = new Narrative().setStatus(Narrative.NarrativeStatus.GENERATED);
compositionSectionText.setDivAsString(sectionText);
c.setText(compositionText);
c.addSection().setText(compositionSectionText);
return c;
}
/**
* See #402 section.text is overwritten by composition.text
*/
@Test
public void testEncodingTextSection() {
String sectionText = "sectionText";
Composition composition = createComposition(sectionText);
String encoded = ourCtx.newXmlParser().encodeResourceToString(composition);
ourLog.info(encoded);
int idx = encoded.indexOf(sectionText);
assertNotEquals(-1, idx);
}
}

View File

@ -20,7 +20,7 @@
<script th:src="@{/fa/js/all.min.js}" data-auto-replace-svg="nest"></script>
<link href="css/hapi-narrative.css" rel="stylesheet"/>
<script type="text/javascript" src="js/moment.min.js"></script>
<script type="text/javascript" src="js/moment-with-locales.min.js"></script>
<link href="css/bootstrap-datetimepicker.min.css" rel="stylesheet"/>
<script src="js/bootstrap-datetimepicker.min.js"></script>
<link href="css/select2.css" rel="stylesheet"/>

View File

@ -331,8 +331,8 @@ function addSearchControlDate(theSearchParamName, theContainerRowNum, theRowNum,
)
);
input.datetimepicker({
pickTime: false,
showToday: true
format: "YYYY-MM-DD",
showTodayButton: true
});
// Set up the qualifier dropdown after we've initialized the datepicker, since it
// overrides all addon buttons while it inits..

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -552,6 +552,9 @@
<id>dmap</id>
<name>David Maplesden</name>
</developer>
<developer>
<id>jaferkhan</id>
</developer>
</developers>
<licenses>

View File

@ -287,6 +287,15 @@
conditional creates can now be authorized even if they are happening inside a FHIR
transaction.
</action>
<action type="fix" issue="402">
When encoding a Composition resource in XML, the section narrative blocks were incorrectly
replaced by the main resource narrative. Thanks to Mirjam Baltus for reporting!
</action>
<action type="fix" issue="1473">
AN issue with date pickers not working in the hapi-fhir-testpage-overlay
project has been fixed. Thanks to GitHub user @jaferkhan for the pull
request!
</action>
</release>
<release version="4.0.3" date="2019-09-03" description="Igloo (Point Release)">
<action type="fix">