/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is part of dcm4che, an implementation of DICOM(TM) in
* Java(TM), hosted at https://github.com/gunterze/dcm4che.
*
* The Initial Developer of the Original Code is
* Agfa Healthcare.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* See @authors listed below
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package org.dcm4chee.archive.conf;
import org.dcm4che3.conf.api.AttributeCoercion;
import org.dcm4che3.conf.api.AttributeCoercions;
import org.dcm4che3.conf.api.extensions.ReconfiguringIterator;
import org.dcm4che3.conf.core.api.ConfigurableClass;
import org.dcm4che3.conf.core.api.ConfigurableProperty;
import org.dcm4che3.conf.core.api.ConfigurableProperty.ConfigurablePropertyType;
import org.dcm4che3.conf.core.api.LDAP;
import org.dcm4che3.imageio.codec.CompressionRule;
import org.dcm4che3.imageio.codec.CompressionRules;
import org.dcm4che3.io.TemplatesCache;
import org.dcm4che3.net.*;
import org.dcm4che3.net.TransferCapability.Role;
import org.dcm4che3.util.StringUtils;
import org.dcm4chee.archive.dto.ReferenceUpdateOnRetrieveScope;
import org.dcm4chee.storage.conf.Availability;
import javax.xml.transform.Templates;
import javax.xml.transform.TransformerConfigurationException;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
/**
* @author Gunter Zeilinger <gunterze@gmail.com>
* @author Michael Backhaus <michael.backhaus@agfa.com>
*/
@LDAP(objectClasses = "dcmArchiveNetworkAE", noContainerNode = true)
@ConfigurableClass
public class ArchiveAEExtension extends AEExtension {
private static final long serialVersionUID = -2390448404282661045L;
public static final String DEF_RETRY_INTERVAL = "60";
@ConfigurableProperty(type = ConfigurablePropertyType.OptimisticLockingHash)
private String olockHash;
@ConfigurableProperty(name = "dcmModifyingSystem")
private String modifyingSystem;
@ConfigurableProperty(name = "dcmWadoSupportedSRClasses")
private String[] wadoSupportedSRClasses = {};
@ConfigurableProperty(name = "dcmWadoOverlayRendering", defaultValue = "true")
private boolean wadoOverlayRendering;
@ConfigurableProperty(name = "dcmStorageSystemGroupID")
private String storageSystemGroupID;
@ConfigurableProperty(name = "dcmStorageSystemGroupType")
private String storageSystemGroupType;
@ConfigurableProperty(name= "dcmQidoClientAcceptMediaType", defaultValue="application/json")
private String qidoClientAcceptType = "application/json";
@ConfigurableProperty(name = "dcmSpoolDirectoryPath")
private String spoolDirectoryPath;
@ConfigurableProperty(name = "dcmMetaDataStorageSystemGroupID")
private String metaDataStorageSystemGroupID;
@ConfigurableProperty(name = "dcmSuppressWarningCoercionOfDataElements", defaultValue = "false")
private boolean suppressWarningCoercionOfDataElements;
@ConfigurableProperty(name = "dcmCheckNonDBAttributesOnStorage", defaultValue = "false")
private boolean checkNonDBAttributesOnStorage;
@ConfigurableProperty(name = "dcmIgnoreDuplicatesOnStorage", defaultValue = "true")
private boolean ignoreDuplicatesOnStorage;
@ConfigurableProperty(name = "dcmPreserveSpoolFileOnFailure", defaultValue = "false")
private boolean preserveSpoolFileOnFailure;
@ConfigurableProperty(name = "dcmPersonNameComponentOrderInsensitiveMatching", defaultValue = "false")
private boolean personNameComponentOrderInsensitiveMatching;
@ConfigurableProperty(name = "dcmMatchUnknown", defaultValue = "false")
private boolean matchUnknown;
@ConfigurableProperty(name = "dcmMatchLinkedPatientIDs", defaultValue = "false")
private boolean matchLinkedPatientIDs;
@ConfigurableProperty(name = "dcmSendPendingCGet", defaultValue = "false")
private boolean sendPendingCGet;
@ConfigurableProperty(name = "dcmSendPendingCMoveInterval", defaultValue = "0")
private int sendPendingCMoveInterval;
@ConfigurableProperty(name = "dcmStgCmtDelay", defaultValue = "0")
private int storageCommitmentDelay;
@ConfigurableProperty(name = "dcmStgCmtMaxRetries", defaultValue = "0")
private int storageCommitmentMaxRetries;
@ConfigurableProperty(name = "dcmStgCmtRetryInterval", defaultValue = DEF_RETRY_INTERVAL)
private int storageCommitmentRetryInterval = Integer
.parseInt(DEF_RETRY_INTERVAL);
@ConfigurableProperty(name = "dcmFwdMppsDestination", collectionOfReferences = true)
private List<ApplicationEntity> forwardMPPSDestinations = new ArrayList<>();
@ConfigurableProperty(name = "dcmIanDestination")
private String[] IANDestinations = {};
@ConfigurableProperty(name = "dcmIanMaxRetries", defaultValue = "0")
private int IANMaxRetries;
@ConfigurableProperty(name = "dcmIanRetryInterval", defaultValue = DEF_RETRY_INTERVAL)
private int IANRetryInterval = Integer.parseInt(DEF_RETRY_INTERVAL);
@LDAP(noContainerNode = true)
@ConfigurableProperty(name = "dcmAttributeCoercions")
private AttributeCoercions attributeCoercions = new AttributeCoercions();
@LDAP(noContainerNode = true)
@ConfigurableProperty(name = "dcmCompressionRules")
private CompressionRules compressionRules = new CompressionRules();
@ConfigurableProperty(name = "dcmReturnOtherPatientIDs", defaultValue = "false")
private boolean returnOtherPatientIDs;
@ConfigurableProperty(name = "dcmReturnOtherPatientNames", defaultValue = "false")
private boolean returnOtherPatientNames;
@ConfigurableProperty(name = "hl7PIXManagerApplication")
private String remotePIXManagerApplication;
@ConfigurableProperty(name = "hl7PIXConsumerApplication")
private String localPIXConsumerApplication;
@ConfigurableProperty(name = "dcmQidoMaxNumberOfResults", defaultValue = "0")
private int QIDOMaxNumberOfResults;
@ConfigurableProperty(name = "dcmWadoSRTemplateURI")
private String wadoSRTemplateURI;
@ConfigurableProperty(name = "dcmQueryRetrieveViewID")
private String queryRetrieveViewID;
@ConfigurableProperty(name = "dcmDefaultExternalRetrieveAETAvailability")
private Availability defaultExternalRetrieveAETAvailability;
@ConfigurableProperty(name = "dcmQCUpdateReferencesOnRetrieve", defaultValue="DEACTIVATE",
label="QC Update Reference on Retrieve",
description="Sets the scope for the QC retrieve service decorator "
+ "can be DEACTIVATE, STUDY or PATIENT "
+ ", the update check is performed according to that scope")
private ReferenceUpdateOnRetrieveScope qcUpdateReferencesOnRetrieve = ReferenceUpdateOnRetrieveScope.DEACTIVATE;
@ConfigurableProperty(name = "dcmRetrieveSuppressionCriteria")
private RetrieveSuppressionCriteria retrieveSuppressionCriteria = new RetrieveSuppressionCriteria();
@LDAP(noContainerNode=true)
@ConfigurableProperty(name = "dcmArchivingRules")
private ArchivingRules archivingRules = new ArchivingRules();
@ConfigurableProperty(name = "dcmPatientSelector")
private PatientSelectorConfig patientSelectorConfig;
@ConfigurableProperty(name = "dcmStoreRememberMaxRetries", defaultValue = "0")
private int storeAndRememberMaxRetries;
@ConfigurableProperty(name = "dcmStoreRememberDelayAfterFailedResponse", defaultValue = "3600")
private int storeAndRememberDelayAfterFailedResponse = 3600;
public RetrieveSuppressionCriteria getRetrieveSuppressionCriteria() {
return retrieveSuppressionCriteria;
}
public void setRetrieveSuppressionCriteria(
RetrieveSuppressionCriteria retrieveSuppressionCriteria) {
this.retrieveSuppressionCriteria = retrieveSuppressionCriteria;
}
public PatientSelectorConfig getPatientSelectorConfig() {
return patientSelectorConfig;
}
public void setPatientSelectorConfig(
PatientSelectorConfig patientSelectorConfig) {
this.patientSelectorConfig = patientSelectorConfig;
}
public String[] getWadoSupportedSRClasses() {
return wadoSupportedSRClasses;
}
public void setWadoSupportedSRClasses(String[] wadoSupportedSRClasses) {
this.wadoSupportedSRClasses = wadoSupportedSRClasses;
}
public boolean isWadoOverlayRendering() {
return wadoOverlayRendering;
}
public void setWadoOverlayRendering(boolean wadoOverlayRendering) {
this.wadoOverlayRendering = wadoOverlayRendering;
}
public AttributeCoercion getAttributeCoercion(String sopClass, Dimse dimse,
Role role, String aeTitle) {
return attributeCoercions.findAttributeCoercion(sopClass, dimse, role,
aeTitle);
}
public AttributeCoercions getAttributeCoercions() {
return attributeCoercions;
}
public void addAttributeCoercion(AttributeCoercion ac) {
attributeCoercions.add(ac);
}
public void setAttributeCoercions(AttributeCoercions acs) {
attributeCoercions.clear();
if (acs!=null)
attributeCoercions.add(acs);
}
public boolean removeAttributeCoercion(AttributeCoercion ac) {
return attributeCoercions.remove(ac);
}
public CompressionRules getCompressionRules() {
return compressionRules;
}
public void addCompressionRule(CompressionRule rule) {
compressionRules.add(rule);
}
public void setCompressionRules(CompressionRules rules) {
compressionRules = rules;
}
public boolean removeCompressionRule(CompressionRule ac) {
return compressionRules.remove(ac);
}
public String getModifyingSystem() {
return modifyingSystem;
}
public String getEffectiveModifyingSystem() {
return modifyingSystem != null ? modifyingSystem
: getApplicationEntity().getDevice().getDeviceName();
}
public void setModifyingSystem(String modifyingSystem) {
this.modifyingSystem = modifyingSystem;
}
public String getStorageSystemGroupID() {
return storageSystemGroupID;
}
public void setStorageSystemGroupID(String storageSystemGroupID) {
this.storageSystemGroupID = storageSystemGroupID;
}
public void setStorageSystemGroupType(String storageSystemGroupType) {
this.storageSystemGroupType = storageSystemGroupType;
}
public String getStorageSystemGroupType() {
return storageSystemGroupType;
}
public String getSpoolDirectoryPath() {
return spoolDirectoryPath;
}
public void setSpoolDirectoryPath(String spoolDirectoryPath) {
this.spoolDirectoryPath = spoolDirectoryPath;
}
public String getMetaDataStorageSystemGroupID() {
return metaDataStorageSystemGroupID;
}
public void setMetaDataStorageSystemGroupID(String metaDataStorageSystemGroupID) {
this.metaDataStorageSystemGroupID = metaDataStorageSystemGroupID;
}
public Templates getAttributeCoercionTemplates(String cuid, Dimse dimse,
TransferCapability.Role role, String aet)
throws TransformerConfigurationException {
AttributeCoercion ac = getAttributeCoercion(cuid, dimse, role, aet);
return ac != null ? TemplatesCache.getDefault().get(
StringUtils.replaceSystemProperties(ac.getURI())) : null;
}
public boolean isSuppressWarningCoercionOfDataElements() {
return suppressWarningCoercionOfDataElements;
}
public void setSuppressWarningCoercionOfDataElements(
boolean suppressWarningCoercionOfDataElements) {
this.suppressWarningCoercionOfDataElements = suppressWarningCoercionOfDataElements;
}
public boolean isCheckNonDBAttributesOnStorage() {
return checkNonDBAttributesOnStorage;
}
public void setCheckNonDBAttributesOnStorage(
boolean checkNonDBAttributesOnStorage) {
this.checkNonDBAttributesOnStorage = checkNonDBAttributesOnStorage;
}
public boolean isIgnoreDuplicatesOnStorage() {
return ignoreDuplicatesOnStorage;
}
public void setIgnoreDuplicatesOnStorage(boolean ignoreDuplicatesOnStorage) {
this.ignoreDuplicatesOnStorage = ignoreDuplicatesOnStorage;
}
public boolean isPreserveSpoolFileOnFailure() {
return preserveSpoolFileOnFailure;
}
public void setPreserveSpoolFileOnFailure(boolean preserveSpoolFileOnFailure) {
this.preserveSpoolFileOnFailure = preserveSpoolFileOnFailure;
}
public boolean isPersonNameComponentOrderInsensitiveMatching() {
return personNameComponentOrderInsensitiveMatching;
}
public void setPersonNameComponentOrderInsensitiveMatching(
boolean personNameComponentOrderInsensitiveMatching) {
this.personNameComponentOrderInsensitiveMatching = personNameComponentOrderInsensitiveMatching;
}
public boolean isMatchUnknown() {
return matchUnknown;
}
public void setMatchUnknown(boolean matchUnknown) {
this.matchUnknown = matchUnknown;
}
public boolean isMatchLinkedPatientIDs() {
return matchLinkedPatientIDs;
}
public void setMatchLinkedPatientIDs(boolean matchLinkedPatientIDs) {
this.matchLinkedPatientIDs = matchLinkedPatientIDs;
}
public boolean isSendPendingCGet() {
return sendPendingCGet;
}
public void setSendPendingCGet(boolean sendPendingCGet) {
this.sendPendingCGet = sendPendingCGet;
}
public int getSendPendingCMoveInterval() {
return sendPendingCMoveInterval;
}
public void setSendPendingCMoveInterval(int sendPendingCMoveInterval) {
this.sendPendingCMoveInterval = sendPendingCMoveInterval;
}
public final int getStorageCommitmentDelay() {
return storageCommitmentDelay;
}
public final void setStorageCommitmentDelay(int storageCommitmentDelay) {
this.storageCommitmentDelay = storageCommitmentDelay;
}
public final int getStorageCommitmentMaxRetries() {
return storageCommitmentMaxRetries;
}
public final void setStorageCommitmentMaxRetries(
int storageCommitmentMaxRetries) {
this.storageCommitmentMaxRetries = storageCommitmentMaxRetries;
}
public final int getStorageCommitmentRetryInterval() {
return storageCommitmentRetryInterval;
}
public final void setStorageCommitmentRetryInterval(
int storageCommitmentRetryInterval) {
this.storageCommitmentRetryInterval = storageCommitmentRetryInterval;
}
public List<ApplicationEntity> getForwardMPPSDestinations() {
return forwardMPPSDestinations;
}
public void setForwardMPPSDestinations(List<ApplicationEntity> forwardMPPSDestinations) {
this.forwardMPPSDestinations = forwardMPPSDestinations;
}
public String[] getIANDestinations() {
return IANDestinations;
}
public void setIANDestinations(String[] ianDestinations) {
this.IANDestinations = ianDestinations;
}
public boolean hasIANDestinations() {
return IANDestinations.length > 0;
}
public int getIANMaxRetries() {
return IANMaxRetries;
}
public void setIANMaxRetries(int ianMaxRetries) {
this.IANMaxRetries = ianMaxRetries;
}
public int getIANRetryInterval() {
return IANRetryInterval;
}
public void setIANRetryInterval(int ianRetryInterval) {
this.IANRetryInterval = ianRetryInterval;
}
public boolean isReturnOtherPatientIDs() {
return returnOtherPatientIDs;
}
public void setReturnOtherPatientIDs(boolean returnOtherPatientIDs) {
this.returnOtherPatientIDs = returnOtherPatientIDs;
}
public boolean isReturnOtherPatientNames() {
return returnOtherPatientNames;
}
public void setReturnOtherPatientNames(boolean returnOtherPatientNames) {
this.returnOtherPatientNames = returnOtherPatientNames;
}
public String getRemotePIXManagerApplication() {
return remotePIXManagerApplication;
}
public void setRemotePIXManagerApplication(String appName) {
this.remotePIXManagerApplication = appName;
}
public String getLocalPIXConsumerApplication() {
return localPIXConsumerApplication;
}
public void setLocalPIXConsumerApplication(String appName) {
this.localPIXConsumerApplication = appName;
}
public int getQIDOMaxNumberOfResults() {
return QIDOMaxNumberOfResults;
}
public void setQIDOMaxNumberOfResults(int qidoMaxNumberOfResults) {
this.QIDOMaxNumberOfResults = qidoMaxNumberOfResults;
}
public ArchivingRules getArchivingRules() {
return archivingRules;
}
public void addArchivingRule(ArchivingRule rule) {
archivingRules.add(rule);
}
public void setArchivingRules(ArchivingRules rules) {
archivingRules.clear();
if (rules != null)
archivingRules.add(rules);
}
public boolean removeArchivingRule(ArchivingRule ac) {
return archivingRules.remove(ac);
}
@Override
public void reconfigure(AEExtension from) {
ArchiveAEExtension arcae = (ArchiveAEExtension) from;
ReconfiguringIterator.reconfigure(arcae, this, ArchiveAEExtension.class);
setAttributeCoercions(arcae.getAttributeCoercions());
setCompressionRules(arcae.getCompressionRules());
setArchivingRules(arcae.getArchivingRules());
}
public StoreParam getStoreParam() {
StoreParam storeParam = applicationEntity.getDevice()
.getDeviceExtension(ArchiveDeviceExtension.class)
.getStoreParam();
storeParam.setModifyingSystem(getEffectiveModifyingSystem());
storeParam.setPatientSelectorConfig(getPatientSelectorConfig());
return storeParam;
}
public QueryParam getQueryParam(EnumSet<QueryOption> queryOpts,
String[] accessControlIDs) {
ArchiveDeviceExtension arcDev = applicationEntity.getDevice()
.getDeviceExtension(ArchiveDeviceExtension.class);
QueryParam queryParam = arcDev.getQueryParam();
queryParam.setCombinedDatetimeMatching(queryOpts
.contains(QueryOption.DATETIME));
queryParam.setFuzzySemanticMatching(queryOpts
.contains(QueryOption.FUZZY));
queryParam.setPersonNameComponentOrderInsensitiveMatching(
personNameComponentOrderInsensitiveMatching);
queryParam.setMatchUnknown(matchUnknown);
queryParam.setMatchLinkedPatientIDs(matchLinkedPatientIDs);
queryParam.setAccessControlIDs(accessControlIDs);
queryParam.setQueryRetrieveView(
arcDev.getQueryRetrieveView(queryRetrieveViewID));
return queryParam;
}
public String getWadoSRTemplateURI() {
return wadoSRTemplateURI;
}
public void setWadoSRTemplateURI(String wadoSRTemplateURI) {
this.wadoSRTemplateURI = wadoSRTemplateURI;
}
public String getQueryRetrieveViewID() {
return queryRetrieveViewID;
}
public void setQueryRetrieveViewID(String queryRetrieveViewID) {
this.queryRetrieveViewID = queryRetrieveViewID;
}
public ReferenceUpdateOnRetrieveScope getQcUpdateReferencesOnRetrieve() {
return qcUpdateReferencesOnRetrieve;
}
public void setQcUpdateReferencesOnRetrieve(
ReferenceUpdateOnRetrieveScope qcUpdateReferencesOnRetrieve) {
this.qcUpdateReferencesOnRetrieve = qcUpdateReferencesOnRetrieve;
}
public String getQidoClientAcceptType() {
return qidoClientAcceptType;
}
public void setQidoClientAcceptType(String qidoClientAcceptType) {
this.qidoClientAcceptType = qidoClientAcceptType;
}
public Availability getDefaultExternalRetrieveAETAvailability() {
return defaultExternalRetrieveAETAvailability;
}
public void setDefaultExternalRetrieveAETAvailability(
Availability defaultExternalRetrieveAETAvailability) {
this.defaultExternalRetrieveAETAvailability = defaultExternalRetrieveAETAvailability;
}
public int getStoreAndRememberMaxRetries() {
return storeAndRememberMaxRetries;
}
public void setStoreAndRememberMaxRetries(int storeAndRememberMaxRetries) {
this.storeAndRememberMaxRetries = storeAndRememberMaxRetries;
}
public int getStoreAndRememberDelayAfterFailedResponse() {
return storeAndRememberDelayAfterFailedResponse;
}
public void setStoreAndRememberDelayAfterFailedResponse(
int storeAndRememberDelayAfterFailedResponse) {
this.storeAndRememberDelayAfterFailedResponse = storeAndRememberDelayAfterFailedResponse;
}
public String getOlockHash() {
return olockHash;
}
public void setOlockHash(String olockHash) {
this.olockHash = olockHash;
}
}