mirror of
https://github.com/hapifhir/hapi-fhir.git
synced 2025-02-27 08:47:07 +00:00
Merge branch 'master' of github.com:jamesagnew/hapi-fhir
This commit is contained in:
commit
d18a0ea32f
@ -19,18 +19,6 @@ package ca.uhn.fhir.model.api;
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
* #L%
|
* #L%
|
||||||
*/
|
*/
|
||||||
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
import org.hl7.fhir.instance.model.api.IAnyResource;
|
|
||||||
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
|
||||||
import ca.uhn.fhir.model.primitive.DecimalDt;
|
import ca.uhn.fhir.model.primitive.DecimalDt;
|
||||||
@ -39,6 +27,14 @@ import ca.uhn.fhir.model.primitive.InstantDt;
|
|||||||
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
|
||||||
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
import ca.uhn.fhir.model.valueset.BundleEntryTransactionMethodEnum;
|
||||||
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IPrimitiveType;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import static org.apache.commons.lang3.StringUtils.isNotBlank;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Keys in this map refer to <b>resource metadata keys</b>, which are keys used to access information about specific resource instances that live outside of the resource body. Typically, these are
|
* Keys in this map refer to <b>resource metadata keys</b>, which are keys used to access information about specific resource instances that live outside of the resource body. Typically, these are
|
||||||
@ -64,8 +60,6 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
|
|||||||
*/
|
*/
|
||||||
public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 is only used in a limited number
|
* 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 is only used in a limited number
|
||||||
* of scenarios, such as POSTing transaction bundles to a server, or returning resource history.
|
* of scenarios, such as POSTing transaction bundles to a server, or returning resource history.
|
||||||
@ -81,23 +75,22 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), DELETED_AT);
|
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), DELETED_AT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(IResource theResource, InstantDt theObject) {
|
|
||||||
theResource.getResourceMetadata().put(DELETED_AT, theObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public IPrimitiveType<Date> get(IAnyResource theResource) {
|
public IPrimitiveType<Date> get(IAnyResource theResource) {
|
||||||
return (IPrimitiveType<Date>) theResource.getUserData(DELETED_AT.name());
|
return (IPrimitiveType<Date>) theResource.getUserData(DELETED_AT.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(IResource theResource, InstantDt theObject) {
|
||||||
|
theResource.getResourceMetadata().put(DELETED_AT, theObject);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(IAnyResource theResource, IPrimitiveType<Date> theObject) {
|
public void put(IAnyResource theResource, IPrimitiveType<Date> theObject) {
|
||||||
theResource.setUserData(DELETED_AT.name(), theObject);
|
theResource.setUserData(DELETED_AT.name(), theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Denotes the search score which a given resource should match in a transaction. See the FHIR transaction definition for information about this. Corresponds to the value in
|
* Denotes the search score which a given resource should match in a transaction. See the FHIR transaction definition for information about this. Corresponds to the value in
|
||||||
* <code>Bundle.entry.score</code> in a Bundle resource.
|
* <code>Bundle.entry.score</code> in a Bundle resource.
|
||||||
@ -121,7 +114,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(ENTRY_SCORE, theObject);
|
theResource.getResourceMetadata().put(ENTRY_SCORE, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If present and populated with a {@link BundleEntrySearchModeEnum}, contains the "bundle entry search mode", which is the value of the status field in the Bundle entry containing this resource.
|
* If present and populated with a {@link BundleEntrySearchModeEnum}, contains the "bundle entry search mode", which is the value of the status field in the Bundle entry containing this resource.
|
||||||
* The value for this key corresponds to field <code>Bundle.entry.search.mode</code>. This value can be set to provide a status value of "include" for included resources being returned by a
|
* The value for this key corresponds to field <code>Bundle.entry.search.mode</code>. This value can be set to provide a status value of "include" for included resources being returned by a
|
||||||
@ -135,27 +127,27 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeySupportingAnyResource<BundleEntrySearchModeEnum, String> ENTRY_SEARCH_MODE = new ResourceMetadataKeySupportingAnyResource<BundleEntrySearchModeEnum, String>("ENTRY_SEARCH_MODE") {
|
public static final ResourceMetadataKeySupportingAnyResource<BundleEntrySearchModeEnum, String> ENTRY_SEARCH_MODE = new ResourceMetadataKeySupportingAnyResource<BundleEntrySearchModeEnum, String>("ENTRY_SEARCH_MODE") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BundleEntrySearchModeEnum get(IResource theResource) {
|
public BundleEntrySearchModeEnum get(IResource theResource) {
|
||||||
return getEnumFromMetadataOrNullIfNone(theResource.getResourceMetadata(), ENTRY_SEARCH_MODE, BundleEntrySearchModeEnum.class, BundleEntrySearchModeEnum.VALUESET_BINDER);
|
return getEnumFromMetadataOrNullIfNone(theResource.getResourceMetadata(), ENTRY_SEARCH_MODE, BundleEntrySearchModeEnum.class, BundleEntrySearchModeEnum.VALUESET_BINDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void put(IResource theResource, BundleEntrySearchModeEnum theObject) {
|
|
||||||
theResource.getResourceMetadata().put(ENTRY_SEARCH_MODE, theObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(IAnyResource theResource) {
|
public String get(IAnyResource theResource) {
|
||||||
return (String) theResource.getUserData(ENTRY_SEARCH_MODE.name());
|
return (String) theResource.getUserData(ENTRY_SEARCH_MODE.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(IResource theResource, BundleEntrySearchModeEnum theObject) {
|
||||||
|
theResource.getResourceMetadata().put(ENTRY_SEARCH_MODE, theObject);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(IAnyResource theResource, String theObject) {
|
public void put(IAnyResource theResource, String theObject) {
|
||||||
theResource.setUserData(ENTRY_SEARCH_MODE.name(), theObject);
|
theResource.setUserData(ENTRY_SEARCH_MODE.name(), theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If present and populated with a {@link BundleEntryTransactionMethodEnum}, contains the "bundle entry transaction operation", which is the value of the status field in the Bundle entry
|
* If present and populated with a {@link BundleEntryTransactionMethodEnum}, contains the "bundle entry transaction operation", which is the value of the status field in the Bundle entry
|
||||||
* containing this resource. The value for this key corresponds to field <code>Bundle.entry.transaction.operation</code>. This value can be set in resources being transmitted to a server to
|
* containing this resource. The value for this key corresponds to field <code>Bundle.entry.transaction.operation</code>. This value can be set in resources being transmitted to a server to
|
||||||
@ -179,13 +171,13 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void put(IResource theResource, BundleEntryTransactionMethodEnum theObject) {
|
public String get(IAnyResource theResource) {
|
||||||
theResource.getResourceMetadata().put(ENTRY_TRANSACTION_METHOD, theObject);
|
return (String) theResource.getUserData(ENTRY_TRANSACTION_METHOD.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(IAnyResource theResource) {
|
public void put(IResource theResource, BundleEntryTransactionMethodEnum theObject) {
|
||||||
return (String) theResource.getUserData(ENTRY_TRANSACTION_METHOD.name());
|
theResource.getResourceMetadata().put(ENTRY_TRANSACTION_METHOD, theObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -194,7 +186,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If present and populated with a string, provides the "alternate link" (the link element in the bundle entry with <code>rel="alternate"</code>). Server implementations may populate this with a
|
* If present and populated with a string, provides the "alternate link" (the link element in the bundle entry with <code>rel="alternate"</code>). Server implementations may populate this with a
|
||||||
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient/1243") in which case the server will convert this to
|
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient/1243") in which case the server will convert this to
|
||||||
@ -205,6 +196,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<String> LINK_ALTERNATE = new ResourceMetadataKeyEnum<String>("LINK_ALTERNATE") {
|
public static final ResourceMetadataKeyEnum<String> LINK_ALTERNATE = new ResourceMetadataKeyEnum<String>("LINK_ALTERNATE") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(IResource theResource) {
|
public String get(IResource theResource) {
|
||||||
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), LINK_ALTERNATE);
|
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), LINK_ALTERNATE);
|
||||||
@ -215,7 +207,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(LINK_ALTERNATE, theObject);
|
theResource.getResourceMetadata().put(LINK_ALTERNATE, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If present and populated with a string, provides the "search link" (the link element in the bundle entry with <code>rel="search"</code>). Server implementations may populate this with a
|
* If present and populated with a string, provides the "search link" (the link element in the bundle entry with <code>rel="search"</code>). Server implementations may populate this with a
|
||||||
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient?name=tester") in which case the server will convert
|
* complete URL, in which case the URL will be placed as-is in the bundle. They may alternately specify a resource relative URL (e.g. "Patient?name=tester") in which case the server will convert
|
||||||
@ -226,6 +217,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<String> LINK_SEARCH = new ResourceMetadataKeyEnum<String>("LINK_SEARCH") {
|
public static final ResourceMetadataKeyEnum<String> LINK_SEARCH = new ResourceMetadataKeyEnum<String>("LINK_SEARCH") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(IResource theResource) {
|
public String get(IResource theResource) {
|
||||||
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), LINK_SEARCH);
|
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), LINK_SEARCH);
|
||||||
@ -236,7 +228,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(LINK_SEARCH, theObject);
|
theResource.getResourceMetadata().put(LINK_SEARCH, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for this key represents a previous ID used to identify this resource. This key is currently only used internally during transaction method processing.
|
* The value for this key represents a previous ID used to identify this resource. This key is currently only used internally during transaction method processing.
|
||||||
* <p>
|
* <p>
|
||||||
@ -245,6 +236,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<IdDt> PREVIOUS_ID = new ResourceMetadataKeyEnum<IdDt>("PREVIOUS_ID") {
|
public static final ResourceMetadataKeyEnum<IdDt> PREVIOUS_ID = new ResourceMetadataKeyEnum<IdDt>("PREVIOUS_ID") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdDt get(IResource theResource) {
|
public IdDt get(IResource theResource) {
|
||||||
return getIdFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PREVIOUS_ID);
|
return getIdFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PREVIOUS_ID);
|
||||||
@ -255,16 +247,16 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(PREVIOUS_ID, theObject);
|
theResource.getResourceMetadata().put(PREVIOUS_ID, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for this key represents a {@link List} of profile IDs that this resource claims to conform to.
|
* The value for this key represents a {@link List} of profile IDs that this resource claims to conform to.
|
||||||
*
|
* <p>
|
||||||
* <p>
|
* <p>
|
||||||
* Values for this key are of type <b>List<IdDt></b>. Note that the returned list is <i>unmodifiable</i>, so you need to create a new list and call <code>put</code> to change its value.
|
* Values for this key are of type <b>List<IdDt></b>. Note that the returned list is <i>unmodifiable</i>, so you need to create a new list and call <code>put</code> to change its value.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<List<IdDt>> PROFILES = new ResourceMetadataKeyEnum<List<IdDt>>("PROFILES") {
|
public static final ResourceMetadataKeyEnum<List<IdDt>> PROFILES = new ResourceMetadataKeyEnum<List<IdDt>>("PROFILES") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<IdDt> get(IResource theResource) {
|
public List<IdDt> get(IResource theResource) {
|
||||||
return getIdListFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PROFILES);
|
return getIdListFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PROFILES);
|
||||||
@ -275,7 +267,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(PROFILES, theObject);
|
theResource.getResourceMetadata().put(PROFILES, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for this key is the bundle entry <b>Published</b> time. This is defined by FHIR as "Time resource copied into the feed", which is generally best left to the current time.
|
* The value for this key is the bundle entry <b>Published</b> time. This is defined by FHIR as "Time resource copied into the feed", which is generally best left to the current time.
|
||||||
* <p>
|
* <p>
|
||||||
@ -289,6 +280,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<InstantDt> PUBLISHED = new ResourceMetadataKeyEnum<InstantDt>("PUBLISHED") {
|
public static final ResourceMetadataKeyEnum<InstantDt> PUBLISHED = new ResourceMetadataKeyEnum<InstantDt>("PUBLISHED") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstantDt get(IResource theResource) {
|
public InstantDt get(IResource theResource) {
|
||||||
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PUBLISHED);
|
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), PUBLISHED);
|
||||||
@ -299,9 +291,9 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(PUBLISHED, theObject);
|
theResource.getResourceMetadata().put(PUBLISHED, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public static final ResourceMetadataKeyEnum<List<BaseCodingDt>> SECURITY_LABELS = new ResourceMetadataKeyEnum<List<BaseCodingDt>>("SECURITY_LABELS") {
|
public static final ResourceMetadataKeyEnum<List<BaseCodingDt>> SECURITY_LABELS = new ResourceMetadataKeyEnum<List<BaseCodingDt>>("SECURITY_LABELS") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<BaseCodingDt> get(IResource resource) {
|
public List<BaseCodingDt> get(IResource resource) {
|
||||||
Object obj = resource.getResourceMetadata().get(SECURITY_LABELS);
|
Object obj = resource.getResourceMetadata().get(SECURITY_LABELS);
|
||||||
@ -328,7 +320,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for this key is the list of tags associated with this resource
|
* The value for this key is the list of tags associated with this resource
|
||||||
* <p>
|
* <p>
|
||||||
@ -339,6 +330,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<TagList> TAG_LIST = new ResourceMetadataKeyEnum<TagList>("TAG_LIST") {
|
public static final ResourceMetadataKeyEnum<TagList> TAG_LIST = new ResourceMetadataKeyEnum<TagList>("TAG_LIST") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TagList get(IResource theResource) {
|
public TagList get(IResource theResource) {
|
||||||
Object retValObj = theResource.getResourceMetadata().get(TAG_LIST);
|
Object retValObj = theResource.getResourceMetadata().get(TAG_LIST);
|
||||||
@ -359,7 +351,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(TAG_LIST, theObject);
|
theResource.getResourceMetadata().put(TAG_LIST, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If present and populated with a string (as an instance of {@link String}), this value contains the title for this resource, as supplied in any bundles containing the resource.
|
* If present and populated with a string (as an instance of {@link String}), this value contains the title for this resource, as supplied in any bundles containing the resource.
|
||||||
* <p>
|
* <p>
|
||||||
@ -368,6 +359,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<String> TITLE = new ResourceMetadataKeyEnum<String>("TITLE") {
|
public static final ResourceMetadataKeyEnum<String> TITLE = new ResourceMetadataKeyEnum<String>("TITLE") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(IResource theResource) {
|
public String get(IResource theResource) {
|
||||||
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), TITLE);
|
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), TITLE);
|
||||||
@ -378,7 +370,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(TITLE, theObject);
|
theResource.getResourceMetadata().put(TITLE, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for this key is the bundle entry <b>Updated</b> time. This is defined by FHIR as "Last Updated for resource". This value is also used for populating the "Last-Modified" header in the
|
* The value for this key is the bundle entry <b>Updated</b> time. This is defined by FHIR as "Last Updated for resource". This value is also used for populating the "Last-Modified" header in the
|
||||||
* case of methods that return a single resource (read, vread, etc.)
|
* case of methods that return a single resource (read, vread, etc.)
|
||||||
@ -390,6 +381,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<InstantDt> UPDATED = new ResourceMetadataKeyEnum<InstantDt>("UPDATED") {
|
public static final ResourceMetadataKeyEnum<InstantDt> UPDATED = new ResourceMetadataKeyEnum<InstantDt>("UPDATED") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InstantDt get(IResource theResource) {
|
public InstantDt get(IResource theResource) {
|
||||||
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), UPDATED);
|
return getInstantFromMetadataOrNullIfNone(theResource.getResourceMetadata(), UPDATED);
|
||||||
@ -400,7 +392,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(UPDATED, theObject);
|
theResource.getResourceMetadata().put(UPDATED, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for this key is the version ID of the resource object.
|
* The value for this key is the version ID of the resource object.
|
||||||
* <p>
|
* <p>
|
||||||
@ -409,6 +400,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public static final ResourceMetadataKeyEnum<String> VERSION = new ResourceMetadataKeyEnum<String>("VERSION") {
|
public static final ResourceMetadataKeyEnum<String> VERSION = new ResourceMetadataKeyEnum<String>("VERSION") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(IResource theResource) {
|
public String get(IResource theResource) {
|
||||||
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), VERSION);
|
return getStringFromMetadataOrNullIfNone(theResource.getResourceMetadata(), VERSION);
|
||||||
@ -419,7 +411,6 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(VERSION, theObject);
|
theResource.getResourceMetadata().put(VERSION, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The value for this key is the version ID of the resource object.
|
* The value for this key is the version ID of the resource object.
|
||||||
* <p>
|
* <p>
|
||||||
@ -431,6 +422,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public static final ResourceMetadataKeyEnum<IdDt> VERSION_ID = new ResourceMetadataKeyEnum<IdDt>("VERSION_ID") {
|
public static final ResourceMetadataKeyEnum<IdDt> VERSION_ID = new ResourceMetadataKeyEnum<IdDt>("VERSION_ID") {
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IdDt get(IResource theResource) {
|
public IdDt get(IResource theResource) {
|
||||||
return getIdFromMetadataOrNullIfNone(theResource.getResourceMetadata(), VERSION_ID);
|
return getIdFromMetadataOrNullIfNone(theResource.getResourceMetadata(), VERSION_ID);
|
||||||
@ -441,7 +433,7 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
theResource.getResourceMetadata().put(VERSION_ID, theObject);
|
theResource.getResourceMetadata().put(VERSION_ID, theObject);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
private final String myValue;
|
private final String myValue;
|
||||||
|
|
||||||
public ResourceMetadataKeyEnum(String theValue) {
|
public ResourceMetadataKeyEnum(String theValue) {
|
||||||
@ -601,13 +593,12 @@ public abstract class ResourceMetadataKeyEnum<T> implements Serializable {
|
|||||||
|
|
||||||
public static abstract class ResourceMetadataKeySupportingAnyResource<T, T2> extends ResourceMetadataKeyEnum<T> {
|
public static abstract class ResourceMetadataKeySupportingAnyResource<T, T2> extends ResourceMetadataKeyEnum<T> {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
public ResourceMetadataKeySupportingAnyResource(String theValue) {
|
public ResourceMetadataKeySupportingAnyResource(String theValue) {
|
||||||
super(theValue);
|
super(theValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
|
|
||||||
public abstract T2 get(IAnyResource theResource);
|
public abstract T2 get(IAnyResource theResource);
|
||||||
|
|
||||||
public abstract void put(IAnyResource theResource, T2 theObject);
|
public abstract void put(IAnyResource theResource, T2 theObject);
|
||||||
|
@ -44,12 +44,12 @@ public interface IBaseResource extends IBase, IElement {
|
|||||||
/**
|
/**
|
||||||
* Include constant for <code>*</code> (return all includes)
|
* Include constant for <code>*</code> (return all includes)
|
||||||
*/
|
*/
|
||||||
public static final Include INCLUDE_ALL = new Include("*", false).toLocked();
|
Include INCLUDE_ALL = new Include("*", false).toLocked();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Include set containing only {@link #INCLUDE_ALL}
|
* Include set containing only {@link #INCLUDE_ALL}
|
||||||
*/
|
*/
|
||||||
public static final Set<Include> WILDCARD_ALL_SET = Collections.unmodifiableSet(new HashSet<Include>(Arrays.asList(INCLUDE_ALL)));
|
Set<Include> WILDCARD_ALL_SET = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(INCLUDE_ALL)));
|
||||||
|
|
||||||
IIdType getIdElement();
|
IIdType getIdElement();
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Processed addTag {}/{} on {} in {}ms", new Object[]{theScheme, theTerm, theId, w.getMillisAndRestart()});
|
ourLog.info("Processed addTag {}/{} on {} in {}ms", theScheme, theTerm, theId, w.getMillisAndRestart());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -350,7 +350,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||||||
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
OperationOutcomeUtil.addIssue(getContext(), oo, severity, message, null, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
ourLog.info("Processed delete on {} (matched {} resource(s)) in {}ms", new Object[]{theUrl, deletedResources.size(), w.getMillis()});
|
ourLog.info("Processed delete on {} (matched {} resource(s)) in {}ms", theUrl, deletedResources.size(), w.getMillis());
|
||||||
|
|
||||||
DeleteMethodOutcome retVal = new DeleteMethodOutcome();
|
DeleteMethodOutcome retVal = new DeleteMethodOutcome();
|
||||||
retVal.setDeletedEntities(deletedResources);
|
retVal.setDeletedEntities(deletedResources);
|
||||||
@ -613,7 +613,12 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||||||
return theRequestDetails.getServer().getPagingProvider() instanceof DatabaseBackedPagingProvider;
|
return theRequestDetails.getServer().getPagingProvider() instanceof DatabaseBackedPagingProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void markResourcesMatchingExpressionAsNeedingReindexing(String theExpression) {
|
protected void markResourcesMatchingExpressionAsNeedingReindexing(Boolean theCurrentlyReindexing, String theExpression) {
|
||||||
|
// Avoid endless loops
|
||||||
|
if (Boolean.TRUE.equals(theCurrentlyReindexing)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (myDaoConfig.isMarkResourcesForReindexingUponSearchParameterChange()) {
|
if (myDaoConfig.isMarkResourcesForReindexingUponSearchParameterChange()) {
|
||||||
if (isNotBlank(theExpression)) {
|
if (isNotBlank(theExpression)) {
|
||||||
final String resourceType = theExpression.substring(0, theExpression.indexOf('.'));
|
final String resourceType = theExpression.substring(0, theExpression.indexOf('.'));
|
||||||
@ -924,7 +929,9 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||||||
@Override
|
@Override
|
||||||
public void reindex(T theResource, ResourceTable theEntity) {
|
public void reindex(T theResource, ResourceTable theEntity) {
|
||||||
ourLog.debug("Indexing resource {} - PID {}", theResource.getIdElement().getValue(), theEntity.getId());
|
ourLog.debug("Indexing resource {} - PID {}", theResource.getIdElement().getValue(), theEntity.getId());
|
||||||
|
CURRENTLY_REINDEXING.put(theResource, Boolean.TRUE);
|
||||||
updateEntity(theResource, theEntity, null, true, false, theEntity.getUpdatedDate(), true, false);
|
updateEntity(theResource, theEntity, null, true, false, theEntity.getUpdatedDate(), true, false);
|
||||||
|
CURRENTLY_REINDEXING.put(theResource, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -961,7 +968,7 @@ public abstract class BaseHapiFhirResourceDao<T extends IBaseResource> extends B
|
|||||||
|
|
||||||
myEntityManager.merge(entity);
|
myEntityManager.merge(entity);
|
||||||
|
|
||||||
ourLog.info("Processed remove tag {}/{} on {} in {}ms", new Object[]{theScheme, theTerm, theId.getValue(), w.getMillisAndRestart()});
|
ourLog.info("Processed remove tag {}/{} on {} in {}ms", theScheme, theTerm, theId.getValue(), w.getMillisAndRestart());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional(propagation = Propagation.SUPPORTS)
|
@Transactional(propagation = Propagation.SUPPORTS)
|
||||||
|
@ -45,7 +45,9 @@ public class FhirResourceDaoSearchParameterDstu2 extends FhirResourceDaoDstu2<Se
|
|||||||
private IFhirSystemDao<Bundle, MetaDt> mySystemDao;
|
private IFhirSystemDao<Bundle, MetaDt> mySystemDao;
|
||||||
|
|
||||||
protected void markAffectedResources(SearchParameter theResource) {
|
protected void markAffectedResources(SearchParameter theResource) {
|
||||||
markResourcesMatchingExpressionAsNeedingReindexing(theResource != null ? theResource.getXpath() : null);
|
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
|
||||||
|
String expression = theResource != null ? theResource.getXpath() : null;
|
||||||
|
markResourcesMatchingExpressionAsNeedingReindexing(reindex, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
package ca.uhn.fhir.jpa.dao;
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.hl7.fhir.instance.model.api.IBaseResource;
|
|
||||||
|
|
||||||
import ca.uhn.fhir.context.FhirContext;
|
import ca.uhn.fhir.context.FhirContext;
|
||||||
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
import ca.uhn.fhir.context.RuntimeResourceDefinition;
|
||||||
import ca.uhn.fhir.context.RuntimeSearchParam;
|
import ca.uhn.fhir.context.RuntimeSearchParam;
|
||||||
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
import ca.uhn.fhir.jpa.entity.BaseHasResource;
|
||||||
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
import ca.uhn.fhir.jpa.entity.ResourceTable;
|
||||||
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
import ca.uhn.fhir.jpa.search.PersistedJpaBundleProvider;
|
||||||
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum.ResourceMetadataKeySupportingAnyResource;
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* #%L
|
* #%L
|
||||||
@ -35,7 +33,9 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum.ResourceMetadataKeySupporti
|
|||||||
|
|
||||||
public interface IDao {
|
public interface IDao {
|
||||||
|
|
||||||
ResourceMetadataKeySupportingAnyResource<Long, Long> RESOURCE_PID = new MetadataKeyResourcePid("RESOURCE_PID");
|
MetadataKeyResourcePid RESOURCE_PID = new MetadataKeyResourcePid("RESOURCE_PID");
|
||||||
|
|
||||||
|
MetadataKeyCurrentlyReindexing CURRENTLY_REINDEXING = new MetadataKeyCurrentlyReindexing("CURRENTLY_REINDEXING");
|
||||||
|
|
||||||
FhirContext getContext();
|
FhirContext getContext();
|
||||||
|
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
package ca.uhn.fhir.jpa.dao;
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* #%L
|
||||||
|
* HAPI FHIR JPA Server
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2014 - 2018 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.model.api.IResource;
|
||||||
|
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum.ResourceMetadataKeySupportingAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IAnyResource;
|
||||||
|
import org.hl7.fhir.instance.model.api.IBaseResource;
|
||||||
|
|
||||||
|
public final class MetadataKeyCurrentlyReindexing extends ResourceMetadataKeySupportingAnyResource<Boolean, Boolean> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
MetadataKeyCurrentlyReindexing(String theValue) {
|
||||||
|
super(theValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(IAnyResource theResource) {
|
||||||
|
return (Boolean) theResource.getUserData(IDao.CURRENTLY_REINDEXING.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean get(IResource theResource) {
|
||||||
|
return (Boolean) theResource.getResourceMetadata().get(IDao.CURRENTLY_REINDEXING);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean get(IBaseResource theResource) {
|
||||||
|
if (theResource instanceof IAnyResource) {
|
||||||
|
return get((IAnyResource) theResource);
|
||||||
|
} else {
|
||||||
|
return get((IResource) theResource);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(IAnyResource theResource, Boolean theObject) {
|
||||||
|
theResource.setUserData(IDao.CURRENTLY_REINDEXING.name(), theObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void put(IBaseResource theResource, Boolean theValue) {
|
||||||
|
if (theResource instanceof IAnyResource) {
|
||||||
|
put((IAnyResource) theResource, theValue);
|
||||||
|
} else {
|
||||||
|
put((IResource) theResource, theValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(IResource theResource, Boolean theObject) {
|
||||||
|
theResource.getResourceMetadata().put(IDao.CURRENTLY_REINDEXING, theObject);
|
||||||
|
}
|
||||||
|
}
|
@ -50,7 +50,9 @@ public class FhirResourceDaoSearchParameterDstu3 extends FhirResourceDaoDstu3<Se
|
|||||||
private IFhirSystemDao<Bundle, Meta> mySystemDao;
|
private IFhirSystemDao<Bundle, Meta> mySystemDao;
|
||||||
|
|
||||||
protected void markAffectedResources(SearchParameter theResource) {
|
protected void markAffectedResources(SearchParameter theResource) {
|
||||||
markResourcesMatchingExpressionAsNeedingReindexing(theResource != null ? theResource.getExpression() : null);
|
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
|
||||||
|
String expression = theResource != null ? theResource.getExpression() : null;
|
||||||
|
markResourcesMatchingExpressionAsNeedingReindexing(reindex, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -47,7 +47,9 @@ public class FhirResourceDaoSearchParameterR4 extends FhirResourceDaoR4<SearchPa
|
|||||||
private IFhirSystemDao<Bundle, Meta> mySystemDao;
|
private IFhirSystemDao<Bundle, Meta> mySystemDao;
|
||||||
|
|
||||||
protected void markAffectedResources(SearchParameter theResource) {
|
protected void markAffectedResources(SearchParameter theResource) {
|
||||||
markResourcesMatchingExpressionAsNeedingReindexing(theResource != null ? theResource.getExpression() : null);
|
Boolean reindex = theResource != null ? CURRENTLY_REINDEXING.get(theResource) : null;
|
||||||
|
String expression = theResource != null ? theResource.getExpression() : null;
|
||||||
|
markResourcesMatchingExpressionAsNeedingReindexing(reindex, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -144,6 +144,24 @@ public class FhirResourceDaoR4SearchCustomSearchParamTest extends BaseJpaR4Test
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateSearchParameterOnSearchParameterDoesntCauseEndlessReindexLoop() throws InterruptedException {
|
||||||
|
SearchParameter fooSp = new SearchParameter();
|
||||||
|
fooSp.setCode("foo");
|
||||||
|
fooSp.addBase("SearchParameter");
|
||||||
|
fooSp.setType(org.hl7.fhir.r4.model.Enumerations.SearchParamType.TOKEN);
|
||||||
|
fooSp.setTitle("FOO SP");
|
||||||
|
fooSp.setExpression("SearchParameter.code");
|
||||||
|
fooSp.setXpathUsage(org.hl7.fhir.r4.model.SearchParameter.XPathUsageType.NORMAL);
|
||||||
|
fooSp.setStatus(org.hl7.fhir.r4.model.Enumerations.PublicationStatus.ACTIVE);
|
||||||
|
|
||||||
|
mySearchParameterDao.create(fooSp, mySrd);
|
||||||
|
|
||||||
|
assertEquals(1, mySystemDao.performReindexingPass(100).intValue());
|
||||||
|
assertEquals(0, mySystemDao.performReindexingPass(100).intValue());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCustomReferenceParameter() throws Exception {
|
public void testCustomReferenceParameter() throws Exception {
|
||||||
SearchParameter sp = new SearchParameter();
|
SearchParameter sp = new SearchParameter();
|
||||||
|
@ -142,7 +142,7 @@ public class RestHookTestWithInterceptorRegisteredToDaoConfigDstu2Test extends B
|
|||||||
|
|
||||||
subscriptionTemp.setCriteria(criteria1);
|
subscriptionTemp.setCriteria(criteria1);
|
||||||
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
ourClient.update().resource(subscriptionTemp).withId(subscriptionTemp.getIdElement()).execute();
|
||||||
|
waitForQueueToDrain();
|
||||||
|
|
||||||
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
Observation observation2 = sendObservation(code, "SNOMED-CT");
|
||||||
|
|
||||||
|
@ -140,6 +140,10 @@
|
|||||||
parameters and updating a resource to no longer match
|
parameters and updating a resource to no longer match
|
||||||
one of these search parameters.
|
one of these search parameters.
|
||||||
</action>
|
</action>
|
||||||
|
<action type="fix">
|
||||||
|
Avoid an endless loop of reindexing in JPA if a SearchParameter is
|
||||||
|
created which indexed the SearchParameter resource itself
|
||||||
|
</action>
|
||||||
</release>
|
</release>
|
||||||
<release version="3.2.0" date="2018-01-13">
|
<release version="3.2.0" date="2018-01-13">
|
||||||
<action type="add">
|
<action type="add">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user