Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
66ed2bca38
|
@ -181,7 +181,7 @@ public enum FhirVersionEnum {
|
|||
|
||||
private String myVersion;
|
||||
|
||||
public Dstu3Version() {
|
||||
Dstu3Version() {
|
||||
try {
|
||||
Class<?> c = Class.forName("org.hl7.fhir.dstu3.model.Constants");
|
||||
myVersion = (String) c.getDeclaredField("VERSION").get(null);
|
||||
|
@ -201,7 +201,7 @@ public enum FhirVersionEnum {
|
|||
|
||||
private String myVersion;
|
||||
|
||||
public R4Version() {
|
||||
R4Version() {
|
||||
try {
|
||||
Class<?> c = Class.forName("org.hl7.fhir.r4.model.Constants");
|
||||
myVersion = (String) c.getDeclaredField("VERSION").get(null);
|
||||
|
|
|
@ -55,7 +55,7 @@ public interface IParserErrorHandler {
|
|||
void incorrectJsonType(IParseLocation theLocation, String theElementName, ValueType theExpectedValueType, ScalarType theExpectedScalarType, ValueType theFoundValueType, ScalarType theFoundScalarType);
|
||||
|
||||
/**
|
||||
* The parser detected an atttribute value that was invalid (such as: empty "" values are not permitted)
|
||||
* The parser detected an attribute value that was invalid (such as: empty "" values are not permitted)
|
||||
*
|
||||
* @param theLocation
|
||||
* The location in the document. Note that this may be <code>null</code> as the ParseLocation feature is experimental. Use with caution, as the API may change.
|
||||
|
@ -70,7 +70,7 @@ public interface IParserErrorHandler {
|
|||
*
|
||||
* @param theLocation
|
||||
* The location in the document. Note that this may be <code>null</code> as the ParseLocation feature is experimental. Use with caution, as the API may change.
|
||||
* @param theReference The actual invalid reference (e.g. "#3")
|
||||
* @param theElementName The missing element name
|
||||
* @since 2.1
|
||||
*/
|
||||
void missingRequiredElement(IParseLocation theLocation, String theElementName);
|
||||
|
@ -123,7 +123,7 @@ public interface IParserErrorHandler {
|
|||
* type which will currently always be set to null. This interface is included here so that
|
||||
* locations can be added to the API in a future release without changing the API.
|
||||
*/
|
||||
public interface IParseLocation {
|
||||
interface IParseLocation {
|
||||
|
||||
/**
|
||||
* Returns the name of the parent element (the element containing the element currently being parsed)
|
||||
|
|
|
@ -1033,7 +1033,7 @@ public class JsonParser extends BaseParser implements IJsonLikeParser {
|
|||
} else {
|
||||
parentElementName = "extension";
|
||||
}
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation(parentElementName), "url");
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation().setParentElementName(parentElementName), "url");
|
||||
url = null;
|
||||
} else {
|
||||
url = getExtensionUrl(jsonElement.getAsString());
|
||||
|
|
|
@ -29,9 +29,8 @@ class ParseLocation implements IParseLocation {
|
|||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public ParseLocation(String theParentElementName) {
|
||||
public ParseLocation() {
|
||||
super();
|
||||
myParentElementName = theParentElementName;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,4 +38,9 @@ class ParseLocation implements IParseLocation {
|
|||
return myParentElementName;
|
||||
}
|
||||
|
||||
public ParseLocation setParentElementName(String theParentElementName) {
|
||||
myParentElementName = theParentElementName;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -806,7 +806,7 @@ class ParserState<T> {
|
|||
@SuppressWarnings("unchecked")
|
||||
List<IBase> securityLabels = (List<IBase>) myMap.get(ResourceMetadataKeyEnum.SECURITY_LABELS);
|
||||
if (securityLabels == null) {
|
||||
securityLabels = new ArrayList<IBase>();
|
||||
securityLabels = new ArrayList<>();
|
||||
myMap.put(ResourceMetadataKeyEnum.SECURITY_LABELS, securityLabels);
|
||||
}
|
||||
IBase securityLabel = myContext.getVersion().newCodingDt();
|
||||
|
|
|
@ -139,7 +139,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
Attribute urlAttr = elem.getAttributeByName(new QName("url"));
|
||||
String url;
|
||||
if (urlAttr == null || isBlank(urlAttr.getValue())) {
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation("extension"), "url");
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation().setParentElementName("extension"), "url");
|
||||
url = null;
|
||||
} else {
|
||||
url = urlAttr.getValue();
|
||||
|
@ -149,7 +149,7 @@ public class XmlParser extends BaseParser /* implements IParser */ {
|
|||
Attribute urlAttr = elem.getAttributeByName(new QName("url"));
|
||||
String url;
|
||||
if (urlAttr == null || isBlank(urlAttr.getValue())) {
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation("modifierExtension"), "url");
|
||||
getErrorHandler().missingRequiredElement(new ParseLocation().setParentElementName("modifierExtension"), "url");
|
||||
url = null;
|
||||
} else {
|
||||
url = urlAttr.getValue();
|
||||
|
|
|
@ -7,6 +7,7 @@ import ca.uhn.fhir.model.dstu2.resource.Bundle.Entry;
|
|||
import ca.uhn.fhir.model.dstu2.resource.StructureDefinition;
|
||||
import ca.uhn.fhir.model.dstu2.resource.ValueSet;
|
||||
import ca.uhn.fhir.rest.client.api.IGenericClient;
|
||||
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.Option;
|
||||
|
@ -274,6 +275,8 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
ourLog.info(" - Got ID: {}", id.getValue());
|
||||
} catch (UnprocessableEntityException e) {
|
||||
ourLog.warn("UnprocessableEntityException: " + e.toString());
|
||||
} catch (BaseServerResponseException e) {
|
||||
ourLog.warn("Server responded HTTP " + e.getStatusCode() + ": " + e.toString());
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
@ -519,7 +522,11 @@ public class ValidationDataUploader extends BaseCommand {
|
|||
}
|
||||
|
||||
ourLog.info("Uploading {} StructureDefinition {}/{} : {}", new Object[] {name, count, total, next.getIdElement().getValue()});
|
||||
try {
|
||||
client.update().resource(next).execute();
|
||||
} catch (BaseServerResponseException e) {
|
||||
ourLog.warn("Server responded HTTP " + e.getStatusCode() + ": " + e.toString());
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
|
|
|
@ -82,10 +82,11 @@ import java.util.Map.Entry;
|
|||
|
||||
import static org.apache.commons.lang3.StringUtils.*;
|
||||
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
||||
|
||||
public static final long INDEX_STATUS_INDEXED = Long.valueOf(1L);
|
||||
public static final long INDEX_STATUS_INDEXING_FAILED = Long.valueOf(2L);
|
||||
public static final long INDEX_STATUS_INDEXED = 1L;
|
||||
public static final long INDEX_STATUS_INDEXING_FAILED = 2L;
|
||||
public static final String NS_JPA_PROFILE = "https://github.com/jamesagnew/hapi-fhir/ns/jpa/profile";
|
||||
public static final String OO_SEVERITY_ERROR = "error";
|
||||
public static final String OO_SEVERITY_INFO = "information";
|
||||
|
@ -379,7 +380,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
} else {
|
||||
ResourceLink resourceLink = new ResourceLink(nextPathAndRef.getPath(), theEntity, nextId, theUpdateTime);
|
||||
if (theLinks.add(resourceLink)) {
|
||||
ourLog.info("Indexing remote resource reference URL: {}", nextId);
|
||||
ourLog.debug("Indexing remote resource reference URL: {}", nextId);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
@ -417,7 +418,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
IBaseResource newResource = missingResourceDef.newInstance();
|
||||
newResource.setId(resName + "/" + id);
|
||||
IFhirResourceDao<IBaseResource> placeholderResourceDao = (IFhirResourceDao<IBaseResource>) getDao(newResource.getClass());
|
||||
ourLog.info("Automatically creating empty placeholder resource: {}", newResource.getIdElement().getValue());
|
||||
ourLog.debug("Automatically creating empty placeholder resource: {}", newResource.getIdElement().getValue());
|
||||
valueOf = placeholderResourceDao.update(newResource).getEntity().getId();
|
||||
} else {
|
||||
throw new InvalidRequestException("Resource " + resName + "/" + id + " not found, specified in path: " + nextPathsUnsplit);
|
||||
|
@ -673,7 +674,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
@SuppressWarnings("unchecked")
|
||||
public <R extends IBaseResource> IFhirResourceDao<R> getDao(Class<R> theType) {
|
||||
if (myResourceTypeToDao == null) {
|
||||
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<Class<? extends IBaseResource>, IFhirResourceDao<?>>();
|
||||
Map<Class<? extends IBaseResource>, IFhirResourceDao<?>> theResourceTypeToDao = new HashMap<>();
|
||||
for (IFhirResourceDao<?> next : myResourceDaos) {
|
||||
theResourceTypeToDao.put(next.getResourceType(), next);
|
||||
}
|
||||
|
@ -1549,7 +1550,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
Long next = matches.iterator().next();
|
||||
String newId = translatePidIdToForcedId(resourceTypeString, next);
|
||||
ourLog.info("Replacing inline match URL[{}] with ID[{}}", nextId.getValue(), newId);
|
||||
ourLog.debug("Replacing inline match URL[{}] with ID[{}}", nextId.getValue(), newId);
|
||||
nextRef.setReference(newId);
|
||||
}
|
||||
}
|
||||
|
@ -1615,7 +1616,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
if (!changed.isChanged() && !theForceUpdate && myConfig.isSuppressUpdatesWithNoChange()) {
|
||||
ourLog.info("Resource {} has not changed", theEntity.getIdDt().toUnqualified().getValue());
|
||||
ourLog.debug("Resource {} has not changed", theEntity.getIdDt().toUnqualified().getValue());
|
||||
if (theResource != null) {
|
||||
populateResourceIdFromEntity(theEntity, theResource);
|
||||
}
|
||||
|
@ -1657,7 +1658,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
historyEntry.setEncoding(changed.getEncoding());
|
||||
historyEntry.setResource(changed.getResource());
|
||||
|
||||
ourLog.info("Saving history entry {}", historyEntry.getIdDt());
|
||||
ourLog.debug("Saving history entry {}", historyEntry.getIdDt());
|
||||
myResourceHistoryTableDao.save(historyEntry);
|
||||
}
|
||||
|
||||
|
@ -1765,7 +1766,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
// Store composite string uniques
|
||||
if (getConfig().isUniqueIndexesEnabled()) {
|
||||
for (ResourceIndexedCompositeStringUnique next : removeCommon(existingCompositeStringUniques, compositeStringUniques)) {
|
||||
ourLog.info("Removing unique index: {}", next);
|
||||
ourLog.debug("Removing unique index: {}", next);
|
||||
myEntityManager.remove(next);
|
||||
theEntity.getParamsCompositeStringUnique().remove(next);
|
||||
}
|
||||
|
@ -1776,7 +1777,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
throw new PreconditionFailedException("Can not create resource of type " + theEntity.getResourceType() + " as it would create a duplicate index matching query: " + next.getIndexString() + " (existing index belongs to " + existing.getResource().getIdDt().toUnqualifiedVersionless().getValue() + ")");
|
||||
}
|
||||
}
|
||||
ourLog.info("Persisting unique index: {}", next);
|
||||
ourLog.debug("Persisting unique index: {}", next);
|
||||
myEntityManager.persist(next);
|
||||
}
|
||||
}
|
||||
|
@ -1821,7 +1822,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
|
||||
if (nextChildDef instanceof RuntimeChildResourceDefinition) {
|
||||
RuntimeChildResourceDefinition nextChildDefRes = (RuntimeChildResourceDefinition) nextChildDef;
|
||||
Set<String> validTypes = new HashSet<String>();
|
||||
Set<String> validTypes = new HashSet<>();
|
||||
boolean allowAny = false;
|
||||
for (Class<? extends IBaseResource> nextValidType : nextChildDefRes.getResourceTypes()) {
|
||||
if (nextValidType.isInterface()) {
|
||||
|
@ -2147,7 +2148,7 @@ public abstract class BaseHapiFhirDao<T extends IBaseResource> implements IDao {
|
|||
}
|
||||
|
||||
if (forcedId.isEmpty() == false) {
|
||||
List<Long> retVal = new ArrayList<Long>(forcedId.size());
|
||||
List<Long> retVal = new ArrayList<>(forcedId.size());
|
||||
for (ForcedId next : forcedId) {
|
||||
retVal.add(next.getResourcePid());
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
}
|
||||
}
|
||||
|
||||
ourLog.info("Processed addTag {}/{} on {} in {}ms", theScheme, theTerm, theId, w.getMillisAndRestart());
|
||||
ourLog.debug("Processed addTag {}/{} on {} in {}ms", theScheme, theTerm, theId, w.getMillisAndRestart());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -273,7 +273,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
validateDeleteConflictsEmptyOrThrowException(deleteConflicts);
|
||||
|
||||
ourLog.info("Processed delete on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
|
||||
ourLog.debug("Processed delete on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -350,7 +350,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
||||
}
|
||||
|
||||
ourLog.info("Processed delete on {} (matched {} resource(s)) in {}ms", theUrl, deletedResources.size(), w.getMillis());
|
||||
ourLog.debug("Processed delete on {} (matched {} resource(s)) in {}ms", theUrl, deletedResources.size(), w.getMillis());
|
||||
|
||||
DeleteMethodOutcome retVal = new DeleteMethodOutcome();
|
||||
retVal.setDeletedEntities(deletedResources);
|
||||
|
@ -462,7 +462,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulCreate", outcome.getId(), w.getMillisAndRestart());
|
||||
outcome.setOperationOutcome(createInfoOperationOutcome(msg));
|
||||
|
||||
ourLog.info(msg);
|
||||
ourLog.debug(msg);
|
||||
return outcome;
|
||||
}
|
||||
|
||||
|
@ -530,7 +530,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
StopWatch w = new StopWatch();
|
||||
TagList tags = super.getTags(myResourceType, null);
|
||||
ourLog.info("Processed getTags on {} in {}ms", myResourceName, w.getMillisAndRestart());
|
||||
ourLog.debug("Processed getTags on {} in {}ms", myResourceName, w.getMillisAndRestart());
|
||||
return tags;
|
||||
}
|
||||
|
||||
|
@ -557,7 +557,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
StopWatch w = new StopWatch();
|
||||
TagList retVal = super.getTags(myResourceType, theResourceId);
|
||||
ourLog.info("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
|
||||
ourLog.debug("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -569,7 +569,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
StopWatch w = new StopWatch();
|
||||
IBundleProvider retVal = super.history(myResourceName, null, theSince, theUntil);
|
||||
ourLog.info("Processed history on {} in {}ms", myResourceName, w.getMillisAndRestart());
|
||||
ourLog.debug("Processed history on {} in {}ms", myResourceName, w.getMillisAndRestart());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -586,7 +586,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
IBundleProvider retVal = super.history(myResourceName, entity.getId(), theSince, theUntil);
|
||||
|
||||
ourLog.info("Processed history on {} in {}ms", id, w.getMillisAndRestart());
|
||||
ourLog.debug("Processed history on {} in {}ms", id, w.getMillisAndRestart());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -622,7 +622,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
if (myDaoConfig.isMarkResourcesForReindexingUponSearchParameterChange()) {
|
||||
if (isNotBlank(theExpression)) {
|
||||
final String resourceType = theExpression.substring(0, theExpression.indexOf('.'));
|
||||
ourLog.info("Marking all resources of type {} for reindexing due to updated search parameter with path: {}", resourceType, theExpression);
|
||||
ourLog.debug("Marking all resources of type {} for reindexing due to updated search parameter with path: {}", resourceType, theExpression);
|
||||
|
||||
TransactionTemplate txTemplate = new TransactionTemplate(myPlatformTransactionManager);
|
||||
txTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
||||
|
@ -633,7 +633,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
}
|
||||
});
|
||||
|
||||
ourLog.info("Marked {} resources for reindexing", updatedCount);
|
||||
ourLog.debug("Marked {} resources for reindexing", updatedCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -665,7 +665,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
doMetaAdd(theMetaAdd, history);
|
||||
}
|
||||
|
||||
ourLog.info("Processed metaAddOperation on {} in {}ms", new Object[]{theResourceId, w.getMillisAndRestart()});
|
||||
ourLog.debug("Processed metaAddOperation on {} in {}ms", new Object[]{theResourceId, w.getMillisAndRestart()});
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
MT retVal = (MT) metaGetOperation(theMetaAdd.getClass(), theResourceId, theRequestDetails);
|
||||
|
@ -699,7 +699,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
myEntityManager.flush();
|
||||
|
||||
ourLog.info("Processed metaDeleteOperation on {} in {}ms", new Object[]{theResourceId.getValue(), w.getMillisAndRestart()});
|
||||
ourLog.debug("Processed metaDeleteOperation on {} in {}ms", new Object[]{theResourceId.getValue(), w.getMillisAndRestart()});
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
MT retVal = (MT) metaGetOperation(theMetaDel.getClass(), theResourceId, theRequestDetails);
|
||||
|
@ -864,7 +864,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
throw new ResourceGoneException("Resource was deleted at " + deleted.getValueAsString());
|
||||
}
|
||||
|
||||
ourLog.info("Processed read on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
|
||||
ourLog.debug("Processed read on {} in {}ms", theId.getValue(), w.getMillisAndRestart());
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -968,7 +968,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
|
||||
myEntityManager.merge(entity);
|
||||
|
||||
ourLog.info("Processed remove tag {}/{} on {} in {}ms", theScheme, theTerm, theId.getValue(), w.getMillisAndRestart());
|
||||
ourLog.debug("Processed remove tag {}/{} on {} in {}ms", theScheme, theTerm, theId.getValue(), w.getMillisAndRestart());
|
||||
}
|
||||
|
||||
@Transactional(propagation = Propagation.SUPPORTS)
|
||||
|
@ -1282,7 +1282,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
String msg = getContext().getLocalizer().getMessage(BaseHapiFhirResourceDao.class, "successfulCreate", outcome.getId(), w.getMillisAndRestart());
|
||||
outcome.setOperationOutcome(createInfoOperationOutcome(msg));
|
||||
|
||||
ourLog.info(msg);
|
||||
ourLog.debug(msg);
|
||||
return outcome;
|
||||
}
|
||||
|
||||
|
@ -1339,7 +1339,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||
}
|
||||
|
||||
if (myDaoConfig.isEnforceReferentialIntegrityOnDelete() == false && !theForValidate) {
|
||||
ourLog.info("Deleting {} resource dependencies which can no longer be satisfied", resultList.size());
|
||||
ourLog.debug("Deleting {} resource dependencies which can no longer be satisfied", resultList.size());
|
||||
myResourceLinkDao.delete(resultList);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
|
||||
private static final List<Long> EMPTY_LONG_LIST = Collections.unmodifiableList(new ArrayList<Long>());
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SearchBuilder.class);
|
||||
private static Long NO_MORE = Long.valueOf(-1);
|
||||
private static Long NO_MORE = -1L;
|
||||
private static HandlerTypeEnum ourLastHandlerMechanismForUnitTest;
|
||||
private List<Long> myAlsoIncludePids;
|
||||
private CriteriaBuilder myBuilder;
|
||||
|
@ -331,10 +331,9 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
List<Predicate> codePredicates = new ArrayList<Predicate>();
|
||||
|
||||
for (IQueryParameterType nextOr : theList) {
|
||||
IQueryParameterType params = nextOr;
|
||||
|
||||
if (params instanceof ReferenceParam) {
|
||||
ReferenceParam ref = (ReferenceParam) params;
|
||||
if (nextOr instanceof ReferenceParam) {
|
||||
ReferenceParam ref = (ReferenceParam) nextOr;
|
||||
|
||||
if (isBlank(ref.getChain())) {
|
||||
IIdType dt = new IdDt(ref.getBaseUrl(), ref.getResourceType(), ref.getIdPart(), null);
|
||||
|
@ -533,7 +532,7 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
}
|
||||
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid token type (expecting ReferenceParam): " + params.getClass());
|
||||
throw new IllegalArgumentException("Invalid token type (expecting ReferenceParam): " + nextOr.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2006,8 +2005,17 @@ public class SearchBuilder implements ISearchBuilder {
|
|||
RuntimeResourceDefinition resourceDef = theContext.getResourceDefinition(theResourceType);
|
||||
RuntimeSearchParam param = theCallingDao.getSearchParamByName(resourceDef, theParamName);
|
||||
List<String> path = param.getPathsSplit();
|
||||
Predicate type = theFrom.get("mySourcePath").in(path);
|
||||
return type;
|
||||
|
||||
/*
|
||||
* SearchParameters can declare paths on multiple resources
|
||||
* types. Here we only want the ones that actually apply.
|
||||
*/
|
||||
for (Iterator<String> iter = path.iterator(); iter.hasNext(); ) {
|
||||
if (!iter.next().startsWith(theResourceType + ".")) {
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
return theFrom.get("mySourcePath").in(path);
|
||||
}
|
||||
|
||||
private static List<Long> filterResourceIdsByLastUpdated(EntityManager theEntityManager, final DateRangeParam theLastUpdated, Collection<Long> thePids) {
|
||||
|
|
|
@ -21,6 +21,7 @@ package ca.uhn.fhir.jpa.dao.dstu3;
|
|||
*/
|
||||
import static org.apache.commons.lang3.StringUtils.isBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||
import static org.apache.commons.lang3.StringUtils.trim;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
@ -478,8 +479,8 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
multiType = true;
|
||||
}
|
||||
|
||||
List<String> systems = new ArrayList<String>();
|
||||
List<String> codes = new ArrayList<String>();
|
||||
List<String> systems = new ArrayList<>();
|
||||
List<String> codes = new ArrayList<>();
|
||||
|
||||
// String needContactPointSystem = null;
|
||||
// if (nextPath.contains(".where(system='phone')")) {
|
||||
|
@ -693,11 +694,11 @@ public class SearchParamExtractorDstu3 extends BaseSearchParamExtractor implemen
|
|||
IWorkerContext worker = new org.hl7.fhir.dstu3.hapi.ctx.HapiWorkerContext(getContext(), myValidationSupport);
|
||||
FHIRPathEngine fp = new FHIRPathEngine(worker);
|
||||
|
||||
List<Object> values = new ArrayList<Object>();
|
||||
List<Object> values = new ArrayList<>();
|
||||
try {
|
||||
String[] nextPathsSplit = SPLIT.split(thePaths);
|
||||
for (String nextPath : nextPathsSplit) {
|
||||
List<Base> allValues = fp.evaluate((Base) theResource, nextPath);
|
||||
List<Base> allValues = fp.evaluate((Base) theResource, trim(nextPath));
|
||||
if (allValues.isEmpty() == false) {
|
||||
values.addAll(allValues);
|
||||
}
|
||||
|
|
|
@ -40,9 +40,6 @@ import static org.apache.commons.lang3.StringUtils.isBlank;
|
|||
|
||||
public class FhirResourceDaoSearchParameterR4 extends FhirResourceDaoR4<SearchParameter> implements IFhirResourceDaoSearchParameter<SearchParameter> {
|
||||
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoSearchParameterR4.class);
|
||||
|
||||
|
||||
@Autowired
|
||||
private IFhirSystemDao<Bundle, Meta> mySystemDao;
|
||||
|
||||
|
@ -130,7 +127,6 @@ public class FhirResourceDaoSearchParameterR4 extends FhirResourceDaoR4<SearchPa
|
|||
theExpression = theExpression.trim();
|
||||
|
||||
String[] expressionSplit = BaseSearchParamExtractor.SPLIT.split(theExpression);
|
||||
String allResourceName = null;
|
||||
for (String nextPath : expressionSplit) {
|
||||
nextPath = nextPath.trim();
|
||||
|
||||
|
@ -146,14 +142,6 @@ public class FhirResourceDaoSearchParameterR4 extends FhirResourceDaoR4<SearchPa
|
|||
throw new UnprocessableEntityException("Invalid SearchParameter.expression value \"" + nextPath + "\": " + e.getMessage());
|
||||
}
|
||||
|
||||
if (allResourceName == null) {
|
||||
allResourceName = resourceName;
|
||||
} else {
|
||||
if (!allResourceName.equals(resourceName)) {
|
||||
throw new UnprocessableEntityException("Invalid SearchParameter.expression value \"" + nextPath + "\". All paths in a single SearchParameter must match the same resource type");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} // if have expression
|
||||
|
|
|
@ -36,6 +36,7 @@ public abstract class BaseHasResource {
|
|||
@Temporal(TemporalType.TIMESTAMP)
|
||||
private Date myDeleted;
|
||||
|
||||
// TODO: move to resource history table
|
||||
@Column(name = "RES_VERSION", nullable = true, length = 7)
|
||||
@Enumerated(EnumType.STRING)
|
||||
@OptimisticLock(excluded = true)
|
||||
|
|
|
@ -95,7 +95,6 @@ public class JavaMailEmailSender implements IEmailSender {
|
|||
@Override
|
||||
public void send(EmailDetails theDetails) {
|
||||
String subscriptionId = theDetails.getSubscription().toUnqualifiedVersionless().getValue();
|
||||
ourLog.info("Sending email for subscription {} to recipients: {}", subscriptionId, theDetails.getTo());
|
||||
StopWatch sw = new StopWatch();
|
||||
|
||||
StringTemplateResolver templateResolver = new StringTemplateResolver();
|
||||
|
@ -116,15 +115,18 @@ public class JavaMailEmailSender implements IEmailSender {
|
|||
|
||||
MimeMessage email = mySender.createMimeMessage();
|
||||
|
||||
String from = trim(theDetails.getFrom());
|
||||
ourLog.info("Sending email for subscription {} from [{}] to recipients: [{}]", subscriptionId, from, theDetails.getTo());
|
||||
|
||||
try {
|
||||
email.setFrom(trim(theDetails.getFrom()));
|
||||
email.setFrom(from);
|
||||
email.setRecipients(Message.RecipientType.TO, toTrimmedCommaSeparatedString(theDetails.getTo()));
|
||||
email.setSubject(subject);
|
||||
email.setText(body);
|
||||
email.setSentDate(new Date());
|
||||
email.addHeader("X-FHIR-Subscription", subscriptionId);
|
||||
} catch (MessagingException e) {
|
||||
throw new InternalErrorException("Failed to create email messaage", e);
|
||||
throw new InternalErrorException("Failed to create email message", e);
|
||||
}
|
||||
|
||||
mySender.send(email);
|
||||
|
|
|
@ -1,17 +1,5 @@
|
|||
package ca.uhn.fhir.jpa.dao.dstu3;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.Appointment.AppointmentStatus;
|
||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.*;
|
||||
|
||||
import ca.uhn.fhir.jpa.dao.SearchParameterMap;
|
||||
import ca.uhn.fhir.model.api.Include;
|
||||
import ca.uhn.fhir.rest.api.server.IBundleProvider;
|
||||
|
@ -19,6 +7,19 @@ import ca.uhn.fhir.rest.param.*;
|
|||
import ca.uhn.fhir.rest.server.exceptions.InvalidRequestException;
|
||||
import ca.uhn.fhir.rest.server.exceptions.UnprocessableEntityException;
|
||||
import ca.uhn.fhir.util.TestUtil;
|
||||
import org.hl7.fhir.dstu3.model.*;
|
||||
import org.hl7.fhir.dstu3.model.Appointment.AppointmentStatus;
|
||||
import org.hl7.fhir.dstu3.model.Enumerations.AdministrativeGender;
|
||||
import org.hl7.fhir.exceptions.FHIRException;
|
||||
import org.hl7.fhir.instance.model.api.IIdType;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu3Test {
|
||||
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirResourceDaoDstu3SearchCustomSearchParamTest.class);
|
||||
|
@ -228,6 +229,76 @@ public class FhirResourceDaoDstu3SearchCustomSearchParamTest extends BaseJpaDstu
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* See #863
|
||||
*/
|
||||
@Test
|
||||
public void testParamWithMultipleBasesReference() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setUrl("http://clinicalcloud.solutions/fhir/SearchParameter/request-reason");
|
||||
sp.setName("reason");
|
||||
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
sp.setCode("reason");
|
||||
sp.addBase("MedicationRequest");
|
||||
sp.addBase("ProcedureRequest");
|
||||
sp.setType(Enumerations.SearchParamType.REFERENCE);
|
||||
sp.setExpression("MedicationRequest.reasonReference | ProcedureRequest.reasonReference");
|
||||
sp.addTarget("Condition");
|
||||
sp.addTarget("Observation");
|
||||
mySearchParameterDao.create(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
|
||||
Condition condition = new Condition();
|
||||
condition.getCode().setText("A condition");
|
||||
String conditionId = myConditionDao.create(condition).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.addReasonReference().setReference(conditionId);
|
||||
String mrId = myMedicationRequestDao.create(mr).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.addReasonReference().setReference(conditionId);
|
||||
myProcedureRequestDao.create(pr);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add("reason", new ReferenceParam(conditionId));
|
||||
List<String> results = toUnqualifiedVersionlessIdValues(myMedicationRequestDao.search(map));
|
||||
assertThat(results, contains(mrId));
|
||||
}
|
||||
|
||||
/**
|
||||
* See #863
|
||||
*/
|
||||
@Test
|
||||
public void testParamWithMultipleBasesToken() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setUrl("http://clinicalcloud.solutions/fhir/SearchParameter/request-reason");
|
||||
sp.setName("reason");
|
||||
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
sp.setCode("reason");
|
||||
sp.addBase("MedicationRequest");
|
||||
sp.addBase("ProcedureRequest");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setExpression("MedicationRequest.reasonCode | ProcedureRequest.reasonCode");
|
||||
mySearchParameterDao.create(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.addReasonCode().addCoding().setSystem("foo").setCode("bar");
|
||||
String mrId = myMedicationRequestDao.create(mr).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
ProcedureRequest pr = new ProcedureRequest();
|
||||
pr.addReasonCode().addCoding().setSystem("foo").setCode("bar");
|
||||
myProcedureRequestDao.create(pr);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add("reason", new TokenParam("foo", "bar"));
|
||||
List<String> results = toUnqualifiedVersionlessIdValues(myMedicationRequestDao.search(map));
|
||||
assertThat(results, contains(mrId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchForExtensionReferenceWithNonMatchingTarget() {
|
||||
SearchParameter siblingSp = new SearchParameter();
|
||||
|
|
|
@ -71,23 +71,6 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateInvalidParamMismatchedResourceName() {
|
||||
SearchParameter fooSp = new SearchParameter();
|
||||
fooSp.addBase("Patient");
|
||||
fooSp.setCode("foo");
|
||||
fooSp.setType(org.hl7.fhir.r4.model.Enumerations.SearchParamType.TOKEN);
|
||||
fooSp.setTitle("FOO SP");
|
||||
fooSp.setExpression("Patient.gender or Observation.code");
|
||||
fooSp.setXpathUsage(org.hl7.fhir.r4.model.SearchParameter.XPathUsageType.NORMAL);
|
||||
fooSp.setStatus(org.hl7.fhir.r4.model.Enumerations.PublicationStatus.ACTIVE);
|
||||
try {
|
||||
mySearchParameterDao.create(fooSp, mySrd);
|
||||
fail();
|
||||
} catch (UnprocessableEntityException e) {
|
||||
assertEquals("Invalid SearchParameter.expression value \"Observation.code\". All paths in a single SearchParameter must match the same resource type", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateInvalidParamNoPath() {
|
||||
|
@ -334,6 +317,77 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
|
|||
}), empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* See #863
|
||||
*/
|
||||
@Test
|
||||
public void testParamWithMultipleBases() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setUrl("http://clinicalcloud.solutions/fhir/SearchParameter/request-reason");
|
||||
sp.setName("reason");
|
||||
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
sp.setCode("reason");
|
||||
sp.addBase("MedicationRequest");
|
||||
sp.addBase("ServiceRequest");
|
||||
sp.setType(Enumerations.SearchParamType.REFERENCE);
|
||||
sp.setExpression("MedicationRequest.reasonReference | ServiceRequest.reasonReference");
|
||||
sp.addTarget("Condition");
|
||||
sp.addTarget("Observation");
|
||||
mySearchParameterDao.create(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
|
||||
Condition condition = new Condition();
|
||||
condition.getCode().setText("A condition");
|
||||
String conditionId = myConditionDao.create(condition).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.addReasonReference().setReference(conditionId);
|
||||
String mrId = myMedicationRequestDao.create(mr).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
ServiceRequest pr = new ServiceRequest();
|
||||
pr.addReasonReference().setReference(conditionId);
|
||||
myServiceRequestDao.create(pr);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add("reason", new ReferenceParam(conditionId));
|
||||
List<String> results = toUnqualifiedVersionlessIdValues(myMedicationRequestDao.search(map));
|
||||
assertThat(results, contains(mrId));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* See #863
|
||||
*/
|
||||
@Test
|
||||
public void testParamWithMultipleBasesToken() {
|
||||
SearchParameter sp = new SearchParameter();
|
||||
sp.setUrl("http://clinicalcloud.solutions/fhir/SearchParameter/request-reason");
|
||||
sp.setName("reason");
|
||||
sp.setStatus(Enumerations.PublicationStatus.ACTIVE);
|
||||
sp.setCode("reason");
|
||||
sp.addBase("MedicationRequest");
|
||||
sp.addBase("ServiceRequest");
|
||||
sp.setType(Enumerations.SearchParamType.TOKEN);
|
||||
sp.setExpression("MedicationRequest.reasonCode | ServiceRequest.reasonCode");
|
||||
mySearchParameterDao.create(sp);
|
||||
mySearchParamRegsitry.forceRefresh();
|
||||
|
||||
MedicationRequest mr = new MedicationRequest();
|
||||
mr.addReasonCode().addCoding().setSystem("foo").setCode("bar");
|
||||
String mrId = myMedicationRequestDao.create(mr).getId().toUnqualifiedVersionless().getValue();
|
||||
|
||||
ServiceRequest pr = new ServiceRequest();
|
||||
pr.addReasonCode().addCoding().setSystem("foo").setCode("bar");
|
||||
myServiceRequestDao.create(pr);
|
||||
|
||||
SearchParameterMap map = new SearchParameterMap();
|
||||
map.setLoadSynchronous(true);
|
||||
map.add("reason", new TokenParam("foo", "bar"));
|
||||
List<String> results = toUnqualifiedVersionlessIdValues(myMedicationRequestDao.search(map));
|
||||
assertThat(results, contains(mrId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSearchForExtensionReferenceWithNonMatchingTarget() {
|
||||
SearchParameter siblingSp = new SearchParameter();
|
||||
|
|
|
@ -96,27 +96,29 @@ public class Controller extends BaseController {
|
|||
}
|
||||
|
||||
@RequestMapping(value = { "/delete" })
|
||||
public String actionDelete(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
|
||||
addCommonParams(theReq, theRequest, theModel);
|
||||
public String actionDelete(HttpServletRequest theServletRequest, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
|
||||
addCommonParams(theServletRequest, theRequest, theModel);
|
||||
|
||||
CaptureInterceptor interceptor = new CaptureInterceptor();
|
||||
GenericClient client = theRequest.newClient(theReq, getContext(theRequest), myConfig, interceptor);
|
||||
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
|
||||
|
||||
RuntimeResourceDefinition def;
|
||||
try {
|
||||
def = getResourceType(theRequest, theReq);
|
||||
def = getResourceType(theRequest, theServletRequest);
|
||||
} catch (ServletException e) {
|
||||
populateModelForResource(theServletRequest, theRequest, theModel);
|
||||
theModel.put("errorMsg", toDisplayError(e.toString(), e));
|
||||
return "resource";
|
||||
}
|
||||
|
||||
String id = StringUtils.defaultString(theReq.getParameter("resource-delete-id"));
|
||||
String id = StringUtils.defaultString(theServletRequest.getParameter("resource-delete-id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
populateModelForResource(theServletRequest, theRequest, theModel);
|
||||
theModel.put("errorMsg", toDisplayError("No ID specified", null));
|
||||
return "resource";
|
||||
}
|
||||
|
||||
ResultType returnsResource = ResultType.BUNDLE;
|
||||
ResultType returnsResource = ResultType.RESOURCE;
|
||||
String outcomeDescription = "Delete Resource";
|
||||
|
||||
long start = System.currentTimeMillis();
|
||||
|
@ -192,27 +194,29 @@ public class Controller extends BaseController {
|
|||
}
|
||||
|
||||
@RequestMapping(value = { "/read" })
|
||||
public String actionRead(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
|
||||
addCommonParams(theReq, theRequest, theModel);
|
||||
public String actionRead(HttpServletRequest theServletRequest, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) {
|
||||
addCommonParams(theServletRequest, theRequest, theModel);
|
||||
|
||||
CaptureInterceptor interceptor = new CaptureInterceptor();
|
||||
GenericClient client = theRequest.newClient(theReq, getContext(theRequest), myConfig, interceptor);
|
||||
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
|
||||
|
||||
RuntimeResourceDefinition def;
|
||||
try {
|
||||
def = getResourceType(theRequest, theReq);
|
||||
def = getResourceType(theRequest, theServletRequest);
|
||||
} catch (ServletException e) {
|
||||
populateModelForResource(theServletRequest, theRequest, theModel);
|
||||
theModel.put("errorMsg", toDisplayError(e.toString(), e));
|
||||
return "resource";
|
||||
}
|
||||
String id = StringUtils.defaultString(theReq.getParameter("id"));
|
||||
String id = StringUtils.defaultString(theServletRequest.getParameter("id"));
|
||||
if (StringUtils.isBlank(id)) {
|
||||
populateModelForResource(theServletRequest, theRequest, theModel);
|
||||
theModel.put("errorMsg", toDisplayError("No ID specified", null));
|
||||
return "resource";
|
||||
}
|
||||
ResultType returnsResource = ResultType.RESOURCE;
|
||||
|
||||
String versionId = StringUtils.defaultString(theReq.getParameter("vid"));
|
||||
String versionId = StringUtils.defaultString(theServletRequest.getParameter("vid"));
|
||||
String outcomeDescription;
|
||||
if (StringUtils.isBlank(versionId)) {
|
||||
versionId = null;
|
||||
|
@ -242,19 +246,38 @@ public class Controller extends BaseController {
|
|||
|
||||
@RequestMapping({ "/resource" })
|
||||
public String actionResource(HttpServletRequest theServletRequest, final ResourceRequest theRequest, final BindingResult theBindingResult, final ModelMap theModel) {
|
||||
IBaseResource conformance = addCommonParams(theServletRequest, theRequest, theModel);
|
||||
|
||||
CaptureInterceptor interceptor = new CaptureInterceptor();
|
||||
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
|
||||
|
||||
String resourceName = theRequest.getResource();
|
||||
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
|
||||
|
||||
TreeSet<String> includes = new TreeSet<String>();
|
||||
TreeSet<String> revIncludes = new TreeSet<String>();
|
||||
TreeSet<String> sortParams = new TreeSet<String>();
|
||||
populateModelForResource(theServletRequest, theRequest, theModel);
|
||||
|
||||
if (isNotBlank(theRequest.getUpdateId())) {
|
||||
String updateId = theRequest.getUpdateId();
|
||||
String updateVid = defaultIfEmpty(theRequest.getUpdateVid(), null);
|
||||
CaptureInterceptor interceptor = new CaptureInterceptor();
|
||||
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
|
||||
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
|
||||
IBaseResource updateResource = client.read(def.getImplementingClass(), new IdDt(resourceName, updateId, updateVid));
|
||||
String updateResourceString = theRequest.newParser(getContext(theRequest)).setPrettyPrint(true).encodeResourceToString(updateResource);
|
||||
theModel.put("updateResource", updateResourceString);
|
||||
theModel.put("updateResourceId", updateId);
|
||||
}
|
||||
|
||||
ourLog.info(logPrefix(theModel) + "Showing resource page: {}", resourceName);
|
||||
|
||||
return "resource";
|
||||
}
|
||||
|
||||
private void populateModelForResource(HttpServletRequest theServletRequest, HomeRequest theRequest, ModelMap theModel) {
|
||||
IBaseResource conformance = addCommonParams(theServletRequest, theRequest, theModel);
|
||||
|
||||
String resourceName = theRequest.getResource();
|
||||
|
||||
TreeSet<String> includes = new TreeSet<>();
|
||||
TreeSet<String> revIncludes = new TreeSet<>();
|
||||
TreeSet<String> sortParams = new TreeSet<>();
|
||||
boolean haveSearchParams = false;
|
||||
List<List<String>> queryIncludes = new ArrayList<List<String>>();
|
||||
List<List<String>> queryIncludes = new ArrayList<>();
|
||||
|
||||
switch (theRequest.getFhirVersion(myConfig)) {
|
||||
case DSTU2:
|
||||
|
@ -276,25 +299,12 @@ public class Controller extends BaseController {
|
|||
theModel.put("haveSearchParams", haveSearchParams);
|
||||
theModel.put("queryIncludes", queryIncludes);
|
||||
theModel.put("sortParams", sortParams);
|
||||
|
||||
if (isNotBlank(theRequest.getUpdateId())) {
|
||||
String updateId = theRequest.getUpdateId();
|
||||
String updateVid = defaultIfEmpty(theRequest.getUpdateVid(), null);
|
||||
IBaseResource updateResource = (IBaseResource) client.read(def.getImplementingClass(), new IdDt(resourceName, updateId, updateVid));
|
||||
String updateResourceString = theRequest.newParser(getContext(theRequest)).setPrettyPrint(true).encodeResourceToString(updateResource);
|
||||
theModel.put("updateResource", updateResourceString);
|
||||
theModel.put("updateResourceId", updateId);
|
||||
}
|
||||
|
||||
ourLog.info(logPrefix(theModel) + "Showing resource page: {}", resourceName);
|
||||
|
||||
return "resource";
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@RequestMapping(value = { "/search" })
|
||||
public String actionSearch(HttpServletRequest theReq, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) throws IOException {
|
||||
addCommonParams(theReq, theRequest, theModel);
|
||||
public String actionSearch(HttpServletRequest theServletRequest, HomeRequest theRequest, BindingResult theBindingResult, ModelMap theModel) throws IOException {
|
||||
addCommonParams(theServletRequest, theRequest, theModel);
|
||||
|
||||
StringWriter clientCodeJsonStringWriter = new StringWriter();
|
||||
JsonWriter clientCodeJsonWriter = new JsonWriter(clientCodeJsonStringWriter);
|
||||
|
@ -305,19 +315,20 @@ public class Controller extends BaseController {
|
|||
clientCodeJsonWriter.value((String) theModel.get("base"));
|
||||
|
||||
CaptureInterceptor interceptor = new CaptureInterceptor();
|
||||
GenericClient client = theRequest.newClient(theReq, getContext(theRequest), myConfig, interceptor);
|
||||
GenericClient client = theRequest.newClient(theServletRequest, getContext(theRequest), myConfig, interceptor);
|
||||
|
||||
IUntypedQuery search = client.search();
|
||||
IQuery query;
|
||||
if (isNotBlank(theReq.getParameter("resource"))) {
|
||||
if (isNotBlank(theServletRequest.getParameter("resource"))) {
|
||||
try {
|
||||
query = search.forResource((Class<? extends IBaseResource>) getResourceType(theRequest, theReq).getImplementingClass());
|
||||
query = search.forResource(getResourceType(theRequest, theServletRequest).getImplementingClass());
|
||||
} catch (ServletException e) {
|
||||
populateModelForResource(theServletRequest, theRequest, theModel);
|
||||
theModel.put("errorMsg", toDisplayError(e.toString(), e));
|
||||
return "resource";
|
||||
}
|
||||
clientCodeJsonWriter.name("resource");
|
||||
clientCodeJsonWriter.value(theReq.getParameter("resource"));
|
||||
clientCodeJsonWriter.value(theServletRequest.getParameter("resource"));
|
||||
} else {
|
||||
query = search.forAllResources();
|
||||
clientCodeJsonWriter.name("resource");
|
||||
|
@ -349,7 +360,7 @@ public class Controller extends BaseController {
|
|||
paramIdx++;
|
||||
|
||||
String paramIdxString = Integer.toString(paramIdx);
|
||||
boolean shouldContinue = handleSearchParam(paramIdxString, theReq, query, clientCodeJsonWriter);
|
||||
boolean shouldContinue = handleSearchParam(paramIdxString, theServletRequest, query, clientCodeJsonWriter);
|
||||
if (!shouldContinue) {
|
||||
break;
|
||||
}
|
||||
|
@ -358,7 +369,7 @@ public class Controller extends BaseController {
|
|||
|
||||
clientCodeJsonWriter.name("includes");
|
||||
clientCodeJsonWriter.beginArray();
|
||||
String[] incValues = theReq.getParameterValues(Constants.PARAM_INCLUDE);
|
||||
String[] incValues = theServletRequest.getParameterValues(Constants.PARAM_INCLUDE);
|
||||
if (incValues != null) {
|
||||
for (String next : incValues) {
|
||||
if (isNotBlank(next)) {
|
||||
|
@ -371,7 +382,7 @@ public class Controller extends BaseController {
|
|||
|
||||
clientCodeJsonWriter.name("revincludes");
|
||||
clientCodeJsonWriter.beginArray();
|
||||
String[] revIncValues = theReq.getParameterValues(Constants.PARAM_REVINCLUDE);
|
||||
String[] revIncValues = theServletRequest.getParameterValues(Constants.PARAM_REVINCLUDE);
|
||||
if (revIncValues != null) {
|
||||
for (String next : revIncValues) {
|
||||
if (isNotBlank(next)) {
|
||||
|
@ -382,9 +393,10 @@ public class Controller extends BaseController {
|
|||
}
|
||||
clientCodeJsonWriter.endArray();
|
||||
|
||||
String limit = theReq.getParameter("resource-search-limit");
|
||||
String limit = theServletRequest.getParameter("resource-search-limit");
|
||||
if (isNotBlank(limit)) {
|
||||
if (!limit.matches("[0-9]+")) {
|
||||
populateModelForResource(theServletRequest, theRequest, theModel);
|
||||
theModel.put("errorMsg", toDisplayError("Search limit must be a numeric value.", null));
|
||||
return "resource";
|
||||
}
|
||||
|
@ -397,13 +409,13 @@ public class Controller extends BaseController {
|
|||
clientCodeJsonWriter.nullValue();
|
||||
}
|
||||
|
||||
String[] sort = theReq.getParameterValues("sort_by");
|
||||
String[] sort = theServletRequest.getParameterValues("sort_by");
|
||||
if (sort != null) {
|
||||
for (String next : sort) {
|
||||
if (isBlank(next)) {
|
||||
continue;
|
||||
}
|
||||
String direction = theReq.getParameter("sort_direction");
|
||||
String direction = theServletRequest.getParameter("sort_direction");
|
||||
if ("asc".equals(direction)) {
|
||||
query.sort().ascending(new StringClientParam(next));
|
||||
} else if ("desc".equals(direction)) {
|
||||
|
@ -505,7 +517,7 @@ public class Controller extends BaseController {
|
|||
Class<? extends IBaseResource> type = null; // def.getImplementingClass();
|
||||
if ("history-type".equals(theMethod)) {
|
||||
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
|
||||
type = (Class<? extends IBaseResource>) def.getImplementingClass();
|
||||
type = def.getImplementingClass();
|
||||
}
|
||||
|
||||
String body = validate ? theReq.getParameter("resource-validate-body") : theReq.getParameter("resource-create-body");
|
||||
|
@ -588,7 +600,7 @@ public class Controller extends BaseController {
|
|||
Class<? extends IBaseResource> type = null; // def.getImplementingClass();
|
||||
if ("history-type".equals(theMethod)) {
|
||||
RuntimeResourceDefinition def = getContext(theRequest).getResourceDefinition(theRequest.getResource());
|
||||
type = (Class<? extends IBaseResource>) def.getImplementingClass();
|
||||
type = def.getImplementingClass();
|
||||
id = StringUtils.defaultString(theReq.getParameter("resource-history-id"));
|
||||
}
|
||||
|
||||
|
|
4
pom.xml
4
pom.xml
|
@ -1118,8 +1118,8 @@
|
|||
<encoding>UTF-8</encoding>
|
||||
|
||||
<fork>true</fork>
|
||||
<meminitial>128m</meminitial>
|
||||
<maxmem>1600m</maxmem>
|
||||
<meminitial>500m</meminitial>
|
||||
<maxmem>2000m</maxmem>
|
||||
</configuration>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
|
|
@ -150,6 +150,21 @@
|
|||
elements of type "Reference". Thanks to GitHub user @t4deon for supplying
|
||||
a testcase!
|
||||
</action>
|
||||
<action type="fix">
|
||||
Deleting a resource from the testpage overlay resulted in an error page after
|
||||
clicking "delete", even though the delete succeeded.
|
||||
</action>
|
||||
<action type="remove">
|
||||
A number of info level log lines have been reduced to debug level in the JPA server, in
|
||||
order to reduce contention during heavy loads.
|
||||
</action>
|
||||
<action type="fix" issue="863">
|
||||
JPA server now correctly indexes custom search parameters which
|
||||
have multiple base resource types. Previously, the indexing could
|
||||
cause resources of the wrong type to be returned in a search
|
||||
if a parameter being used also matched that type. Thanks
|
||||
to Dave Carlson for reporting!
|
||||
</action>
|
||||
</release>
|
||||
<release version="3.2.0" date="2018-01-13">
|
||||
<action type="add">
|
||||
|
|
Loading…
Reference in New Issue