001/* 002 * *** BEGIN LICENSE BLOCK ***** 003 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 004 * 005 * The contents of this file are subject to the Mozilla Public License Version 006 * 1.1 (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * http://www.mozilla.org/MPL/ 009 * 010 * Software distributed under the License is distributed on an "AS IS" basis, 011 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 012 * for the specific language governing rights and limitations under the 013 * License. 014 * 015 * The Original Code is part of dcm4che, an implementation of DICOM(TM) in 016 * Java(TM), hosted at https://github.com/gunterze/dcm4che. 017 * 018 * The Initial Developer of the Original Code is 019 * Agfa Healthcare. 020 * Portions created by the Initial Developer are Copyright (C) 2015 021 * the Initial Developer. All Rights Reserved. 022 * 023 * Contributor(s): 024 * See @authors listed below 025 * 026 * Alternatively, the contents of this file may be used under the terms of 027 * either the GNU General Public License Version 2 or later (the "GPL"), or 028 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 029 * in which case the provisions of the GPL or the LGPL are applicable instead 030 * of those above. If you wish to allow use of your version of this file only 031 * under the terms of either the GPL or the LGPL, and not to allow others to 032 * use your version of this file under the terms of the MPL, indicate your 033 * decision by deleting the provisions above and replace them with the notice 034 * and other provisions required by the GPL or the LGPL. If you do not delete 035 * the provisions above, a recipient may use your version of this file under 036 * the terms of any one of the MPL, the GPL or the LGPL. 037 * 038 * ***** END LICENSE BLOCK ***** 039 */ 040 041package org.dcm4che3.conf.dicom; 042 043import org.dcm4che3.conf.api.DicomConfiguration; 044import org.dcm4che3.conf.api.TCConfiguration; 045import org.dcm4che3.conf.api.TCGroupsProvider; 046import org.dcm4che3.conf.api.TransferCapabilityConfigExtension; 047import org.dcm4che3.conf.api.internal.DicomConfigurationManager; 048import org.dcm4che3.conf.core.api.ConfigurationException; 049import org.dcm4che3.conf.core.Nodes; 050import org.dcm4che3.data.UID; 051import org.dcm4che3.net.ApplicationEntity; 052import org.dcm4che3.net.Device; 053import org.dcm4che3.net.TCGroupConfigAEExtension; 054import org.dcm4che3.net.TransferCapability; 055import org.slf4j.Logger; 056import org.slf4j.LoggerFactory; 057 058import java.util.*; 059 060/** 061 * Relies on org.dcm4che3.net.TCGroupConfigAEExtension and TransferCapabilityConfigExtension to load Transfer Capabilities 062 * 063 * @author Roman K 064 */ 065public class AlternativeTCLoader { 066 067 private static final Logger log = 068 LoggerFactory.getLogger(AlternativeTCLoader.class); 069 070 private final DicomConfigurationManager config; 071 private final boolean doCacheGroups; 072 073 private TCConfiguration tcGroups; 074 075 076 public AlternativeTCLoader(DicomConfigurationManager config, boolean doCacheGroups) { 077 this.config = config; 078 this.doCacheGroups = doCacheGroups; 079 } 080 081 082 private TCConfiguration getTCConfig() throws ConfigurationException { 083 084 TCConfiguration tcGroups = null; 085 if (doCacheGroups) { 086 tcGroups = this.tcGroups; 087 } 088 089 if (tcGroups != null && tcGroups.getTransferCapabilityGroups() != null && tcGroups.getTransferCapabilityGroups().size() > 0) { 090 return tcGroups; 091 } 092 return this.tcGroups = config.getDicomConfigurationExtension(TransferCapabilityConfigExtension.class).getTransferCapabilityConfig(); 093 } 094 095 096 void initGroupBasedTCs(Device d) throws ConfigurationException { 097 098 TCConfiguration tcConfig = getTCConfig(); 099 100 for (ApplicationEntity applicationEntity : d.getApplicationEntities()) { 101 TCGroupConfigAEExtension tcGroupConfigAEExtension = applicationEntity.getAEExtension(TCGroupConfigAEExtension.class); 102 if (tcGroupConfigAEExtension != null) { 103 104 // override any entries that might have been added before 105 applicationEntity.setTransferCapabilities(new ArrayList<TransferCapability>()); 106 107 // Always add CEcho SCP 108 applicationEntity.addTransferCapability(new TransferCapability("CEcho SCP", UID.VerificationSOPClass, TransferCapability.Role.SCP, UID.ImplicitVRLittleEndian)); 109 110 // add processed TCs from pre-configured groups to this ae 111 for (Map.Entry<String, TCGroupConfigAEExtension.TCGroupDetails> tcGroupRefEntry : tcGroupConfigAEExtension.getScpTCs().entrySet()) 112 addTC(applicationEntity, tcConfig, tcGroupRefEntry, TransferCapability.Role.SCP); 113 for (Map.Entry<String, TCGroupConfigAEExtension.TCGroupDetails> tcGroupRefEntry : tcGroupConfigAEExtension.getScuTCs().entrySet()) 114 addTC(applicationEntity, tcConfig, tcGroupRefEntry, TransferCapability.Role.SCU); 115 116 } 117 } 118 } 119 120 121 @SuppressWarnings("Duplicates") 122 private void addTC(ApplicationEntity applicationEntity, TCConfiguration tcConfig, Map.Entry<String, TCGroupConfigAEExtension.TCGroupDetails> tcGroupRefEntry, TransferCapability.Role role) throws ConfigurationException { 123 TCConfiguration.TCGroup tcGroup = tcConfig.getTransferCapabilityGroups().get(tcGroupRefEntry.getKey()); 124 125 if (tcGroup == null) { 126 log.error("Transfer capability group " + tcGroupRefEntry.getKey() + " not found"); 127 return; 128 } 129 130 for (TransferCapability tc : tcGroup.getTransferCapabilities()) { 131 132 TCGroupConfigAEExtension.TCGroupDetails tcGroupDetails = tcGroupRefEntry.getValue(); 133 134 // exclude TC if blacklisted 135 if (tcGroupDetails.getExcludedTransferCapabilities().contains(tc.getSopClass())) 136 continue; 137 138 TransferCapability tcModified = tc.deepCopy(); 139 tcModified.setRole(role); 140 tcModified.setCommonName(tcModified.getCommonName() + " " + role); 141 142 // handle exclusions/whitelisting 143 ArrayList<String> tsList = new ArrayList<String>(Arrays.asList(tcModified.getTransferSyntaxes())); 144 Iterator<String> iterator = tsList.iterator(); 145 if (tcGroupDetails.getWhitelistedTransferSyntaxes() != null && 146 !tcGroupDetails.getWhitelistedTransferSyntaxes().isEmpty()) { 147 148 // use whitelisting logic if enabled - remove all but the specified TSs 149 while (iterator.hasNext()) 150 if (!tcGroupDetails.getWhitelistedTransferSyntaxes().contains(iterator.next())) 151 iterator.remove(); 152 } else { 153 154 // otherwise just filter out excluded TSs 155 while (iterator.hasNext()) 156 if (tcGroupDetails.getExcludedTransferSyntaxes().contains(iterator.next())) 157 iterator.remove(); 158 } 159 160 // add TC only if there is at least one TS left after filtering 161 if (!tsList.isEmpty()) { 162 tcModified.setTransferSyntaxes((String[]) tsList.toArray(new String[]{})); 163 applicationEntity.addTransferCapability(tcModified); 164 } 165 } 166 } 167 168 public void cleanUpTransferCapabilitiesInDeviceNode(Device device, Map<String, Object> deviceNode) { 169 Nodes.removeNodes(deviceNode, DicomPath.AllTCsOfAllAEsWithTCGroupExt.path()); 170 } 171 172 public void refreshTCGroups() { 173 tcGroups = null; 174 } 175}