001package org.dcm4che3.net; 002 003import org.dcm4che3.conf.core.api.ConfigurableClass; 004import org.dcm4che3.conf.core.api.ConfigurableProperty; 005import org.dcm4che3.data.UID; 006 007import java.io.Serializable; 008import java.util.*; 009 010import static org.dcm4che3.net.TransferCapability.Role.SCU; 011 012/** 013 * Alternative representation of Transfer Capabilities for an application entity 014 * 015 * @author Roman K 016 */ 017@ConfigurableClass 018public class TCGroupConfigAEExtension extends AEExtension { 019 020 /** 021 * Certain components' logic may be bound to these group names 022 */ 023 public enum DefaultGroup { 024 STORAGE, 025 PPS, 026 QUERY, 027 RETRIEVE, 028 MWL, 029 STORAGE_COMMITMENT 030 } 031 032 @ConfigurableProperty( 033 label = "Enabled transfer capability groups - SCU" 034 ) 035 Map<String, TCGroupDetails> scuTCs = new TreeMap<String, TCGroupDetails>(); 036 037 038 @ConfigurableProperty( 039 label = "Enabled transfer capability groups - SCP" 040 ) 041 Map<String, TCGroupDetails> scpTCs = new TreeMap<String, TCGroupDetails>(); 042 043 public TCGroupConfigAEExtension() { 044 } 045 046 public TCGroupConfigAEExtension(EnumSet<DefaultGroup> scpGroups, EnumSet<DefaultGroup> scuGroups) { 047 for (DefaultGroup defaultGroup : scpGroups) scpTCs.put(defaultGroup.name(), new TCGroupDetails()); 048 for (DefaultGroup defaultGroup : scuGroups) scuTCs.put(defaultGroup.name(), new TCGroupDetails()); 049 } 050 051 /** 052 * Shortcut to define which default SCP groups are supported, omitting exclusion details 053 * 054 * @return 055 */ 056 public EnumSet<DefaultGroup> getSupportedDefaultScpGroups() { 057 EnumSet<DefaultGroup> groups = EnumSet.noneOf(DefaultGroup.class); 058 for (Map.Entry<String, TCGroupDetails> entry : scpTCs.entrySet()) { 059 060 try { 061 DefaultGroup group = DefaultGroup.valueOf(entry.getKey()); 062 groups.add(group); 063 } catch (IllegalArgumentException e) { 064 //noop 065 } 066 } 067 return groups; 068 } 069 070 /** 071 * Restricts transfer syntaxes for all SOP classes for this AE to Little Endian Implicit and Video-related ones 072 */ 073 public void setLEIAndVideoOnly(boolean leiAndVideoOnly) { 074 if (leiAndVideoOnly) { 075 for (TCGroupDetails tcGroupDetails : scpTCs.values()) 076 whitelistLEIAndVideoTSs(tcGroupDetails); 077 for (TCGroupDetails tcGroupDetails : scuTCs.values()) 078 whitelistLEIAndVideoTSs(tcGroupDetails); 079 } else { 080 081 for (TCGroupDetails tcGroupDetails : scpTCs.values()) 082 tcGroupDetails.getWhitelistedTransferSyntaxes().clear(); 083 for (TCGroupDetails tcGroupDetails : scuTCs.values()) 084 tcGroupDetails.getWhitelistedTransferSyntaxes().clear(); 085 } 086 } 087 088 private void whitelistLEIAndVideoTSs(TCGroupDetails tcGroupDetails) { 089 tcGroupDetails.getWhitelistedTransferSyntaxes().clear(); 090 tcGroupDetails.getWhitelistedTransferSyntaxes().add(UID.ImplicitVRLittleEndian); 091 092 for (String videoTsuid : DefaultTransferCapabilities.VIDEO_TSUIDS) { 093 tcGroupDetails.getWhitelistedTransferSyntaxes().add(videoTsuid); 094 } 095 } 096 097 public Map<String, TCGroupDetails> getScuTCs() { 098 return scuTCs; 099 } 100 101 public void setScuTCs(Map<String, TCGroupDetails> scuTCs) { 102 this.scuTCs = scuTCs; 103 } 104 105 public Map<String, TCGroupDetails> getScpTCs() { 106 return scpTCs; 107 } 108 109 public void setScpTCs(Map<String, TCGroupDetails> scpTCs) { 110 this.scpTCs = scpTCs; 111 } 112 113 @ConfigurableClass 114 public static class TCGroupDetails implements Serializable { 115 116 public TCGroupDetails() { 117 } 118 119 @ConfigurableProperty 120 private List<String> excludedTransferSyntaxes = new ArrayList<String>(); 121 122 @ConfigurableProperty( 123 description = "If not empty, all the syntaxes but those specified by this parameter" + 124 "will be effectively removed from this AE's transfer capabilities") 125 private List<String> whitelistedTransferSyntaxes = new ArrayList<String>(); 126 127 @ConfigurableProperty( 128 label = "Excluded SOP classes", 129 description = "This AE will include all transfer capabilities from the corresponding group, " + 130 "except those with SOP classes specified here" 131 ) 132 private List<String> excludedTransferCapabilities = new ArrayList<String>(); 133 134 public List<String> getExcludedTransferSyntaxes() { 135 return excludedTransferSyntaxes; 136 } 137 138 public void setExcludedTransferSyntaxes(List<String> excludedTransferSyntaxes) { 139 this.excludedTransferSyntaxes = excludedTransferSyntaxes; 140 } 141 142 public List<String> getExcludedTransferCapabilities() { 143 return excludedTransferCapabilities; 144 } 145 146 public void setExcludedTransferCapabilities(List<String> excludedTransferCapabilities) { 147 this.excludedTransferCapabilities = excludedTransferCapabilities; 148 } 149 150 public List<String> getWhitelistedTransferSyntaxes() { 151 return whitelistedTransferSyntaxes; 152 } 153 154 public void setWhitelistedTransferSyntaxes(List<String> whitelistedTransferSyntaxes) { 155 this.whitelistedTransferSyntaxes = whitelistedTransferSyntaxes; 156 } 157 } 158 159 @Override 160 public void reconfigure(AEExtension from) { 161 TCGroupConfigAEExtension tcGroupConfigAEExtension = (TCGroupConfigAEExtension) from; 162 setScpTCs(tcGroupConfigAEExtension.getScpTCs()); 163 setScuTCs(tcGroupConfigAEExtension.getScuTCs()); 164 } 165 166 167 public static List<TransferCapability> getTCsForDefaultGroup(DefaultGroup group) { 168 169 ArrayList<TransferCapability> transferCapabilities; 170 171 switch (group) { 172 case STORAGE: 173 transferCapabilities = new ArrayList<TransferCapability>(); 174 allTCToList(transferCapabilities, DefaultTransferCapabilities.IMAGE_CUIDS, null, DefaultTransferCapabilities.IMAGE_TSUIDS); 175 allTCToList(transferCapabilities, DefaultTransferCapabilities.VIDEO_CUIDS, null, DefaultTransferCapabilities.VIDEO_TSUIDS); 176 allTCToList(transferCapabilities, DefaultTransferCapabilities.OTHER_CUIDS, null, DefaultTransferCapabilities.OTHER_TSUIDS); 177 allTCToList(transferCapabilities, new String[]{UID.InstanceAvailabilityNotificationSOPClass, UID.VerificationSOPClass}, null, UID.ImplicitVRLittleEndian); 178 return transferCapabilities; 179 180 case QUERY: 181 transferCapabilities = new ArrayList<TransferCapability>(); 182 allTCToList(transferCapabilities, DefaultTransferCapabilities.QUERY_CUIDS, EnumSet.allOf(QueryOption.class), DefaultTransferCapabilities.OTHER_TSUIDS); 183 allTCToList(transferCapabilities, new String[]{UID.VerificationSOPClass}, null, UID.ImplicitVRLittleEndian); 184 return transferCapabilities; 185 186 case RETRIEVE: 187 transferCapabilities = new ArrayList<TransferCapability>(); 188 allTCToList(transferCapabilities, DefaultTransferCapabilities.RETRIEVE_CUIDS, EnumSet.of(QueryOption.RELATIONAL), DefaultTransferCapabilities.OTHER_TSUIDS); 189 allTCToList(transferCapabilities, new String[]{UID.CompositeInstanceRetrieveWithoutBulkDataGET, UID.VerificationSOPClass}, null, UID.ImplicitVRLittleEndian); 190 return transferCapabilities; 191 192 case MWL: 193 transferCapabilities = new ArrayList<TransferCapability>(); 194 allTCToList(transferCapabilities, new String[]{UID.ModalityWorklistInformationModelFIND, UID.VerificationSOPClass}, EnumSet.allOf(QueryOption.class), UID.ImplicitVRLittleEndian); 195 return transferCapabilities; 196 197 case PPS: 198 transferCapabilities = new ArrayList<TransferCapability>(); 199 allTCToList(transferCapabilities, new String[]{UID.ModalityPerformedProcedureStepSOPClass, UID.VerificationSOPClass}, null, UID.ImplicitVRLittleEndian); 200 return transferCapabilities; 201 202 case STORAGE_COMMITMENT: 203 transferCapabilities = new ArrayList<TransferCapability>(); 204 allTCToList(transferCapabilities, new String[]{UID.StorageCommitmentPushModelSOPClass, UID.VerificationSOPClass}, null, UID.ImplicitVRLittleEndian); 205 return transferCapabilities; 206 207 default: 208 throw new RuntimeException("Group " + group + " is undefined"); 209 210 } 211 } 212 213 private static void allTCToList(ArrayList<TransferCapability> transferCapabilities, String[] imageCuids, EnumSet<QueryOption> queryOptions, String... transferSyntaxes) { 214 for (String cuid : imageCuids) { 215 String name = UID.nameOf(cuid).replace('/', ' '); 216 TransferCapability tc = new TransferCapability(name, cuid, SCU, transferSyntaxes); 217 tc.setQueryOptions(queryOptions); 218 transferCapabilities.add(tc); 219 } 220 } 221 222}