Skip to content

Commit

Permalink
Extensions to the SOP classes and Transfer Syntaxes hardcoded lists. (#…
Browse files Browse the repository at this point in the history
…516)

* New datastructs to support schema upcoming change

* New attributes and functions to support confs/server.xml schema upcoming change

* Planned #498 course of action (TODOs)

* Implemented support for extended SOP classes and Transfer Syntaxes

* Tweaks in comments

* Tweaks in comments

* Added licence to new files

* Fixed licence header on new datastructures

* Fixed* uninitialized server settings problems.

*shadowed TransfersStorage's changes in this branch temporarily

Signed-off-by: Almeida-a <[email protected]>

* Implemented the recently added signatures in LegacyServerSettings's interfaces

Signed-off-by: Almeida-a <[email protected]>

* Parser from AdditionalTransferSyntax to TransferSyntax from dcm4che; Code rearrangement for readability

Signed-off-by: Almeida-a <[email protected]>

* TransfersStorage refactor, tweaks and tests

 * Everything working, with the only task missing being the new configs appearing in the dicoogle's GUI

Signed-off-by: Almeida-a <[email protected]>

* New SOP classes now appear on transfer options; New transfer syntaxes appear now only on new SOP Classes;

 * Problem on new SOP classes not showing on the list was because I forgot to add them to SOP array (SOPList.updateList)
 * The new transfer syntaxes don't appear on the hardcoded SOP list because it is static. To be solved asap

Signed-off-by: Almeida-a <[email protected]>

* Fixed problem of hardcoded SOP list not containing added transfer syntaxes

Signed-off-by: Almeida-a <[email protected]>

* Set default TSs for new SOP classes

Signed-off-by: Almeida-a <[email protected]>

* Minor tweaks/cleanup and optimization.

 * Optimized the use of TransfersStorage.namesUidMapping (updated to static variable)
 * TODO#498 in ServerSettingsManager was marked with feedback keyword, as the issue is a mere conceptual one, and doesn't affect any functional operations in dicoogle.

Signed-off-by: Almeida-a <[email protected]>

* "Additionals" related functions are now a no-op

Signed-off-by: Almeida-a <[email protected]>

* Refactored additional datastructs following the first feedback from #516 pull request.

 * Format was switched to more verbose parameters, like explicitVR, encapsulated, etc.;
 * Invalid, and therefore, suppressed additionals leave a logger warning indicating the problem in concrete;
 * ServerSettingsTest.testAdditionals cover the referenced additions.

Signed-off-by: Almeida-a <[email protected]>

* #516 pull request's 2nd review changes.

 * Changed defaults
 * Removed Additional datastructs' id and thus refactored isValid logs
 * Changed JacksonXmlProperty notations to JsonProperty (and fixed typo on attribute' name reference)
 * Other suggested minor changes

Signed-off-by: Almeida-a <[email protected]>

* Minor changes in code for readability

Signed-off-by: Almeida-a <[email protected]>

* #498 #516 Reference fix

Signed-off-by: Almeida-a <[email protected]>

* #516 Moved from JsonProperty to JacksonXmlProperty

Also, removed unused imports

* #516 Suppressed logs in ServerSettingsTest$testAdditionals

---------

Signed-off-by: Almeida-a <[email protected]>
  • Loading branch information
Almeida-a authored Jun 7, 2023
1 parent ecafbad commit 3a84aba
Show file tree
Hide file tree
Showing 13 changed files with 666 additions and 81 deletions.
43 changes: 42 additions & 1 deletion dicoogle/src/main/java/pt/ua/dicoogle/core/settings/LegacyServerSettings.java
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import org.dcm4che2.data.UID;
import org.slf4j.LoggerFactory;
import pt.ua.dicoogle.core.XMLSupport;
import pt.ua.dicoogle.sdk.datastructs.AdditionalSOPClass;
import pt.ua.dicoogle.sdk.datastructs.AdditionalTransferSyntax;
import pt.ua.dicoogle.sdk.datastructs.MoveDestination;
import pt.ua.dicoogle.sdk.datastructs.SOPClass;
import pt.ua.dicoogle.sdk.settings.server.ServerSettings;
Expand Down Expand Up @@ -664,10 +666,28 @@ public void setSOPClasses(Collection<SOPClass> classes) {
+ " in legacy configuration file \"config.xml\". Please upgrade your server to use the latest format.");
}

public void setAdditionalSOPClasses(Collection<AdditionalSOPClass> classes) {
// No-op
}

public void setAdditionalTransferSyntaxes(Collection<AdditionalTransferSyntax> syntaxes) {
// No-op
}

public List<SOPClass> getSOPClasses() {
return SOPList.getInstance().asSOPClassList();
}

public List<AdditionalSOPClass> getAdditionalSOPClass() {
// No-op
return Collections.emptyList();
}

public List<AdditionalTransferSyntax> getAdditionalTransferSyntax() {
// No-op
return Collections.emptyList();
}

public void setDIMSERspTimeout(int timeout) {
this.DIMSERspTimeout = timeout;
}
Expand Down Expand Up @@ -1264,7 +1284,7 @@ public List<String> getDefaultStorage() {
public String getNodeName() {
return LegacyServerSettings.this.getNodeName();
}

@JsonGetter("encrypt-users-file")
@Override
public boolean isEncryptUsersFile() {
Expand Down Expand Up @@ -1292,6 +1312,7 @@ public Archive getArchiveSettings() {
@JsonAutoDetect(isGetterVisibility = JsonAutoDetect.Visibility.NONE,
getterVisibility = JsonAutoDetect.Visibility.NONE, setterVisibility = JsonAutoDetect.Visibility.NONE)
protected class StubDicomServices implements DicomServices {

@Override
public void setAETitle(String aetitle) {
LegacyServerSettings.this.setAETitle(aetitle);
Expand Down Expand Up @@ -1342,6 +1363,16 @@ public void setSOPClasses(Collection<SOPClass> sopClasses) {
LegacyServerSettings.this.setSOPClasses(sopClasses);
}

@Override
public void setAdditionalSOPClasses(Collection<AdditionalSOPClass> additionalSOPClasses) {
LegacyServerSettings.this.setAdditionalSOPClasses(additionalSOPClasses);
}

@Override
public void setAdditionalTransferSyntaxes(Collection<AdditionalTransferSyntax> additionalTransferSyntaxes) {
LegacyServerSettings.this.setAdditionalTransferSyntaxes(additionalTransferSyntaxes);
}

@Override
public ServiceBase getStorageSettings() {
return LegacyServerSettings.this.getStorageSettings();
Expand Down Expand Up @@ -1387,6 +1418,16 @@ public Collection<SOPClass> getSOPClasses() {
return LegacyServerSettings.this.getSOPClasses();
}

@Override
public Collection<AdditionalSOPClass> getAdditionalSOPClasses() {
return LegacyServerSettings.this.getAdditionalSOPClass();
}

@Override
public Collection<AdditionalTransferSyntax> getAdditionalTransferSyntaxes() {
return LegacyServerSettings.this.getAdditionalTransferSyntax();
}

@Override
public List<MoveDestination> getMoveDestinations() {
return LegacyServerSettings.this.getMoveDestinations();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@
import org.slf4j.LoggerFactory;
import org.xml.sax.SAXException;
import pt.ua.dicoogle.core.XMLSupport;
import pt.ua.dicoogle.utils.Platform;
import pt.ua.dicoogle.sdk.datastructs.AdditionalSOPClass;
import pt.ua.dicoogle.sdk.datastructs.AdditionalTransferSyntax;
import pt.ua.dicoogle.sdk.settings.server.ServerSettings;
import pt.ua.dicoogle.server.SOPList;
import pt.ua.dicoogle.server.TransfersStorage;
import pt.ua.dicoogle.utils.Platform;

import java.io.*;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Objects;
import java.util.stream.Collectors;

/**
* @author Eduardo Pinho <[email protected]>
Expand Down Expand Up @@ -98,6 +103,21 @@ public static void init() throws IOException {
} else {
// use main configuration file
inner = loadSettingsAt(MAIN_CONFIG_PATH);
/*
TODO#498 (feedback needed) export this following block of code to somewhere more fitting
Check which new UIDs from "additional*" tags are valid (SOP Class UIDs can skip this if
they are already present in the transfer options: e.g. in SOPList) and filter them
Validate and filter Transfer Syntaxes;
*/
inner.getDicomServicesSettings()
.setAdditionalTransferSyntaxes(inner.getDicomServicesSettings().getAdditionalTransferSyntaxes()
.stream().filter(AdditionalTransferSyntax::isValid).collect(Collectors.toList()));
TransfersStorage.completeList();
// Validate and filter SOP Classes; add them to SOPList
inner.getDicomServicesSettings()
.setAdditionalSOPClasses(inner.getDicomServicesSettings().getAdditionalSOPClasses().stream()
.filter(AdditionalSOPClass::isValid).collect(Collectors.toList()));
SOPList.getInstance().updateList();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
import com.fasterxml.jackson.annotation.*;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import pt.ua.dicoogle.sdk.datastructs.AdditionalSOPClass;
import pt.ua.dicoogle.sdk.datastructs.AdditionalTransferSyntax;
import pt.ua.dicoogle.sdk.datastructs.MoveDestination;
import pt.ua.dicoogle.sdk.datastructs.SOPClass;
import pt.ua.dicoogle.sdk.settings.server.ServerSettings;
Expand Down Expand Up @@ -118,6 +120,12 @@ private void setAllowedHostnames_(Object o) {
@JsonProperty("sop-classes")
private Collection<SOPClass> sopClasses = Collections.emptyList();

@JsonProperty("additional-sop-classes")
private Collection<AdditionalSOPClass> additionalSOPClasses = Collections.emptyList();

@JsonProperty("additional-transfer-syntaxes")
private Collection<AdditionalTransferSyntax> additionalTransferSyntaxes = Collections.emptyList();

@JacksonXmlElementWrapper(localName = "move-destinations")
private List<MoveDestination> moveDestinations;

Expand Down Expand Up @@ -212,6 +220,35 @@ public void setSOPClasses(Collection<SOPClass> sopClasses) {
this.sopClasses = sopClasses;
}

@Override
@JsonGetter("additional-sop-classes")
public Collection<AdditionalSOPClass> getAdditionalSOPClasses() {
return this.additionalSOPClasses;
}

@Override
@JsonSetter("additional-sop-classes")
public void setAdditionalSOPClasses(Collection<AdditionalSOPClass> additionalSOPClasses) {
if (additionalSOPClasses == null)
return; // Keep default emptyList value

this.additionalSOPClasses = additionalSOPClasses;
}

@Override
@JsonGetter("additional-transfer-syntaxes")
public Collection<AdditionalTransferSyntax> getAdditionalTransferSyntaxes() {
return this.additionalTransferSyntaxes;
}

@Override
@JsonSetter("additional-transfer-syntaxes")
public void setAdditionalTransferSyntaxes(Collection<AdditionalTransferSyntax> additionalTransferSyntaxes) {
if (additionalTransferSyntaxes == null)
return; // Keep default emptyList value
this.additionalTransferSyntaxes = additionalTransferSyntaxes;
}

@Override
@JsonGetter("move-destinations")
public List<MoveDestination> getMoveDestinations() {
Expand Down Expand Up @@ -258,10 +295,14 @@ public boolean removeMoveDestination(String aetitle) {

@Override
public String toString() {
return "DicomServicesImpl{" + "aetitle='" + aetitle + '\'' + ", deviceDescription='" + deviceDescription + '\''
+ ", allowedAETitles=" + allowedAETitles + ", priorityAETitles=" + priorityAETitles
+ ", allowedLocalInterfaces=" + allowedLocalInterfaces + ", allowedHosts=" + allowedHosts
+ ", defaultTS=" + defaultTS + ", sopClasses=" + sopClasses + ", moveDestinations=" + moveDestinations
+ ", storage=" + storage + ", queryRetrieve=" + queryRetrieve + '}';
return new StringJoiner(", ", DicomServicesImpl.class.getSimpleName() + "[", "]")
.add("aetitle='" + aetitle + "'").add("deviceDescription='" + deviceDescription + "'")
.add("allowedAETitles=" + allowedAETitles).add("priorityAETitles=" + priorityAETitles)
.add("allowedLocalInterfaces=" + allowedLocalInterfaces).add("allowedHosts=" + allowedHosts)
.add("defaultTS=" + defaultTS).add("sopClasses=" + sopClasses)
.add("additionalSOPClasses=" + additionalSOPClasses)
.add("additionalTransferSyntaxes=" + additionalTransferSyntaxes)
.add("moveDestinations=" + moveDestinations).add("storage=" + storage)
.add("queryRetrieve=" + queryRetrieve).toString();
}
}
40 changes: 36 additions & 4 deletions dicoogle/src/main/java/pt/ua/dicoogle/server/SOPList.java
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@
import org.dcm4che2.data.UID;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import pt.ua.dicoogle.core.settings.ServerSettingsManager;
import pt.ua.dicoogle.sdk.datastructs.AdditionalSOPClass;
import pt.ua.dicoogle.sdk.datastructs.SOPClass;
import pt.ua.dicoogle.sdk.settings.server.ServerSettings;
import pt.ua.dicoogle.server.web.management.SOPClassSettings;

import java.util.*;
import java.util.stream.Collectors;

/**
* Support class for keeping SOPClass/TransferSyntax association
Expand Down Expand Up @@ -142,6 +146,7 @@ public static synchronized SOPList getInstance() {
private SOPList() {
table = new Hashtable<>();

// Hardcoded (pre-#498) SOPs
for (String sop : SOP) {
table.put(sop, new TransfersStorage());
}
Expand Down Expand Up @@ -206,7 +211,7 @@ public synchronized int updateTS(String UID, boolean[] p, boolean a) {


public int updateTSFieldByTsUID(String sopUID, String tsUID, boolean value) {
return updateTSField(sopUID, TransfersStorage.globalTransferUIDsMap.get(tsUID), value);
return updateTSField(sopUID, TransfersStorage.getGlobalTransferUIDsMap().get(tsUID), value);
}


Expand All @@ -224,8 +229,8 @@ public synchronized int updateTSField(String UID, String name, boolean value) {
TS = table.get(UID);

int index = -1;
for (int i = 0; i < TransfersStorage.globalTransferMap.size(); i++) {
if (TransfersStorage.globalTransferMap.get(i).equals(name)) {
for (int i = 0; i < TransfersStorage.getGlobalTransferMap().size(); i++) {
if (TransfersStorage.getGlobalTransferMap().get(i).equals(name)) {
index = i;
break;
}
Expand Down Expand Up @@ -332,7 +337,7 @@ public String getSOPList() {
TransfersStorage ts = getTS(uid);
for (int i = 0; i < ts.getTS().length; i++) {
JSONObject tsobj = new JSONObject();
String name = ts.globalTransferMap.get(i);
String name = TransfersStorage.getGlobalTransferMap().get(i);
boolean value = ts.getTS()[i];
tsobj.put("name", name);
tsobj.put("value", value);
Expand All @@ -354,4 +359,31 @@ public List<SOPClass> asSOPClassList() {
}
return l;
}

public void updateList() {

// Add the extras on SOP from getSettings()
ServerSettings settings = ServerSettingsManager.getSettings();
// Get all new SOP classes' UID (not existing in String[] SOP)
Collection<String> newSOPs = settings.getDicomServicesSettings().getAdditionalSOPClasses().stream()
.map(AdditionalSOPClass::getUid)
.filter(newSOPUID -> !Arrays.asList(SOP).contains(newSOPUID))
.collect(Collectors.toList());
// Refresh hardcoded SOPs (outdated TransfersStorage)
Arrays.asList(SOP).forEach(sop -> table.put(sop, new TransfersStorage()));
// Add "Additional" SOPs to table w/ default transfer syntaxes
newSOPs.forEach(sop -> {
TransfersStorage ts = new TransfersStorage();
ts.setDefaultSettings();
table.put(sop, ts);
});
// Add them to SOP
newSOPs.addAll(Arrays.asList(SOP));
SOP = newSOPs.toArray(new String[0]);
}

public void updateList(Collection<AdditionalSOPClass> additionalSOPClasses) {
additionalSOPClasses.forEach(elem -> table.put(elem.getUid(), new TransfersStorage()));
}

}
Loading

0 comments on commit 3a84aba

Please sign in to comment.