Skip to content

Commit

Permalink
Fixes PR #601 Add override code with a another valid code feature (in…
Browse files Browse the repository at this point in the history
…stead of arbitary pick) feature to CodesUpdater tool
  • Loading branch information
Bhaskarla authored and Bhaskarla committed May 30, 2024
1 parent 62499b7 commit cf69956
Show file tree
Hide file tree
Showing 17 changed files with 190 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,67 @@ public class CodesUpdater {
private String out=new String();
private boolean error;

private List<Code> overrideCodes;
/**
* Reset the class variable to their initial state before the algorithm is run again.
* goes by the index of overrideCodes. If index value is null or empty, all files are affected.
*/
private List<String> targetFileByOverrideCodeIndex;
private boolean backupReplacedFiles = true;
private boolean dryRun = false;

/**
* Normal mode to be used with the run method (replaces bad a Code by picking a new Code by an arbitrary index)
*/
public CodesUpdater() {
}

/**
* Alternate mode to replacing Code with a supplied replacement
* @param overrideCodes
* @param replacementMap
* @param backupReplacedFiles
*/
public CodesUpdater(List<String> targetFileByOverrideCodeIndex, List<Code> overrideCodes, Map<String, Code> replacementMap, boolean backupReplacedFiles, boolean dryRun) {
this.targetFileByOverrideCodeIndex = targetFileByOverrideCodeIndex;
this.overrideCodes = overrideCodes;
this.replacementMap = replacementMap;
this.backupReplacedFiles = backupReplacedFiles;
this.dryRun = dryRun;
}

public static void main(String[] args) {

// "C:\\Users\\skb1\\myprojects\\iheos-toolkit2\\xdstools2\\src\\main\\webapp\\toolkitx\\environment\\default";
String codesXmlFileParent = "c:\\temp\\xdscodesupdatertool\\toolkitx\\environment\\default";
String testkitSourceLocation = "C:\\Users\\skb1\\myprojects\\iheos-toolkit2\\xdstools2\\src\\main\\webapp\\toolkitx\\testkit";
TestSession testSession = TestSession.DEFAULT_TEST_SESSION;

List<Code> overrideCodes = Arrays.asList(
new Code("urn:connectathon:bppc:foundational:policy", "1.3.6.1.4.1.21367.2017.3", "Foundational Connectathon Read-Access Policy")
);
List<String> targetFileByOverrideCodeIndex = Arrays.asList(
"\\idc_init\\XDS-I-idc-a"
);

CodesUpdater tool = new CodesUpdater(
targetFileByOverrideCodeIndex,
overrideCodes,
new HashMap<String, Code>() {{
/* key Is code + "^" + display + "^" + scheme; */
put(overrideCodes.get(0).toString(), new Code("CT", "1.2.840.10008.2.16.4", "Computed Tomography"));
}},
false, // false=no bak files
false); // false=perform update, true=does not update update files
tool.run(codesXmlFileParent, testkitSourceLocation, testSession);
}

/**
* Reset the class variable to their initial state before the algorithm is run again.
*/
void reset(){
filesTreated=new ArrayList<String>();
replacementMap=new HashMap<String,Code>();
overrideCodes = null;
}

/**
Expand Down Expand Up @@ -195,18 +250,25 @@ private void processQueryFile(File folderPath, String fileName) {
if (!badCodes.isEmpty()) {
LOGGER.info(badCodes.size() + " codes to update in query file: " + filePath);
out += badCodes.size() + " codes to update in query file: " + filePath + "\n";
File backupFile = new File(file.toString() + ".bak");
if (!backupFile.exists()) {
// backup the unmodified file before updating
FileUtils.copyFile(file, backupFile);
if (!dryRun && backupReplacedFiles) {
File backupFile = new File(file.toString() + ".bak");
if (!backupFile.exists()) {
// backup the unmodified file before updating
FileUtils.copyFile(file, backupFile);
}
}

// update bad codes
updateCode(badCodes);
// update the file itself
String returnType = queryElement.getFirstElement().getAttributeValue(new QName("returnType"));
Io.stringToFile(file, new OMFormatter(StoredQueryGenerator.generateQueryFile(returnType, params)).toString());

if (! dryRun) {
// update the file itself
String returnType = queryElement.getFirstElement().getAttributeValue(new QName("returnType"));
Io.stringToFile(file, new OMFormatter(StoredQueryGenerator.generateQueryFile(returnType, params)).toString());
}
} else {
out += "No codes to update in query file: " + filePath + "\n";
if (! dryRun && overrideCodes == null)
out += "No codes to update in query file: " + filePath + "\n";
}
}
} else {
Expand Down Expand Up @@ -243,21 +305,31 @@ private void processMetadataFile(File folderPath, String fileName) {
if (file.exists()) {
// read the file
OMElement metadataElement = Util.parse_xml(file);
List<OMElement> badCodes = findNonConformingCodes(metadataElement);
// if (file.toString().contains("IDCDEPT012-a")) {
// out += "found the target file.\n";
// }
List<OMElement> badCodes = findNonConformingCodes(file.toString(), metadataElement);
if (!badCodes.isEmpty()) {
LOGGER.info(badCodes.size() + " codes to update in " + filePath);
out += badCodes.size() + " codes to update in " + filePath + '\n';
File backupFile = new File(file.toString() + ".bak");
if (!backupFile.exists()) {
// backup the unmodified file before updating
FileUtils.copyFile(file, backupFile);
if (!dryRun && backupReplacedFiles) {
File backupFile = new File(file.toString() + ".bak");
if (!backupFile.exists()) {
// backup the unmodified file before updating
FileUtils.copyFile(file, backupFile);
}
}

// update bad codes
updateCodes(badCodes);
// update the file itself
Io.stringToFile(file, new OMFormatter(metadataElement).toString());

if (! dryRun) {
// update the file itself
Io.stringToFile(file, new OMFormatter(metadataElement).toString());
}
} else {
out += "No codes to update in " + filePath + '\n';
if (! dryRun && overrideCodes == null)
out += "No codes to update in " + filePath + '\n';
}
} else {
LOGGER.warning("WARNING: " + filePath + " file referenced in test does not exist.");
Expand Down Expand Up @@ -375,7 +447,7 @@ void updateCodes(List<OMElement> badCodes) throws XdsInternalException, FactoryC
OMElement localizedStringElement = MetadataSupport.firstChildWithLocalName(nameElement, "LocalizedString");
if (localizedStringElement == null) return;
OMAttribute nameToReplace = localizedStringElement.getAttribute(MetadataSupport.value_qname);
Code oldCode=new Code(codeToReplace.getAttributeValue(),valueToReplace.getText(),""/*nameToReplace.getAttributeValue()*/);
Code oldCode = asCode(codeToReplace.getAttributeValue(), valueToReplace.getText(), nameToReplace.getAttributeValue());
// check if the code to be replaced as already been changed before.
Code replacementCode=replacementMap.get(oldCode.toString());
if (replacementCode==null){
Expand All @@ -387,6 +459,13 @@ void updateCodes(List<OMElement> badCodes) throws XdsInternalException, FactoryC
replacementMap.put(oldCode.toString(),replacementCode);
out += "New mapping: " + oldCode + " --> " + replacementCode + "\n";
} else {
if (overrideCodes != null && ! overrideCodes.isEmpty()) {
String classificationScheme = classification.getAttributeValue(MetadataSupport.classificationscheme_qname);
Uuid classificationUuid = new Uuid(classificationScheme);
if (! allCodes.exists(classificationUuid, replacementCode)) {
throw new RuntimeException("Override replacement code does not exist in the loaded code map: " + replacementCode.toString());
}
}
out += "Old mapping: " + oldCode + " --> " + replacementCode + "\n";
}
// replace the code
Expand All @@ -396,13 +475,20 @@ void updateCodes(List<OMElement> badCodes) throws XdsInternalException, FactoryC
}
}

private Code asCode(String attributeValue, String text, String display) {
if (overrideCodes != null && ! overrideCodes.isEmpty()) {
return new Code(attributeValue, text, display);
}
return new Code(attributeValue, text, "");
}


/**
* This method explore a parsed document and looks for non-conforming codes with codes.xml file.
* @param metadataElement parsed document to analyze
* @return list of non-confirming code elements
*/
private List<OMElement> findNonConformingCodes(OMElement metadataElement) {
private List<OMElement> findNonConformingCodes(String file, OMElement metadataElement) {
List<OMElement> badCodes = new ArrayList<OMElement>();
List<OMElement> classifications = MetadataSupport.decendentsWithLocalName(metadataElement, "Classification");
for (OMElement classification : classifications) {
Expand All @@ -414,8 +500,15 @@ private List<OMElement> findNonConformingCodes(OMElement metadataElement) {
// Check if the type of code exists.
if (allCodes.isKnownClassification(classificationUuid)) {
Code code = getCode(classification);
if (overrideCodes != null && ! overrideCodes.isEmpty()) {
int oCodeIndex = overrideCodes.indexOf(code);
if (oCodeIndex > -1 && file.contains(targetFileByOverrideCodeIndex.get(oCodeIndex))) {
out += "Overriding code: " + code.getCode() + ". ";
badCodes.add(classification);
}
}
// check if the code exists in the environment codes.xml file
if (!allCodes.exists(classificationUuid, code)) {
else if (!allCodes.exists(classificationUuid, code)) {
// if it does not add the code to the list of bad codes.
badCodes.add(classification);
}
Expand Down Expand Up @@ -491,19 +584,22 @@ public void run(String pathToEnvironment, String pathToTestkit, TestSession test
String to = replacementMap.get(from).toString();
out += (from + " ===> " + to + "\n");
}
reset();
out += outputSeparator + "\n";
out += "Pass 2\n\n";
execute();
if (error) return;
out = outputSeparator + outputSeparator + "\n" + " SUCCESS on generating testkit in environment in " +
pathToEnvironment.split("/")[pathToEnvironment.split("/").length - 1] + "\n" +
outputSeparator + outputSeparator + "\n\n" + out;
out += outputSeparator + "\n";
out += "Mappings\n\n";
for (String from : replacementMap.keySet()) {
String to = replacementMap.get(from).toString();
out += (from + " ===> " + to + "\n");
if (! dryRun) {
// Check own work
reset();
out += outputSeparator + "\n";
out += "Pass 2\n\n";
execute();
if (error) return;
out = outputSeparator + outputSeparator + "\n" + " SUCCESS on generating testkit in environment in " +
pathToEnvironment.split("/")[pathToEnvironment.split("/").length - 1] + "\n" +
outputSeparator + outputSeparator + "\n\n" + out;
out += outputSeparator + "\n";
out += "Mappings\n\n";
for (String from : replacementMap.keySet()) {
String to = replacementMap.get(from).toString();
out += (from + " ===> " + to + "\n");
}
}
try {
SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyyMMddHHmmss");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package gov.nist.toolkit.valregmetadata.coding;

import java.util.Objects;

public class Code {
private String code;
private String scheme;
Expand All @@ -22,14 +24,21 @@ public String getScheme() {
public String getDisplay() {
return display;
}

public boolean equals(Code c) {
if (c == null) return false;
if (!c.getCode().equals(code)) return false;
if (!c.getScheme().equals(scheme)) return false;
return true;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Code code1 = (Code) o;
return code.equals(code1.code) &&
scheme.equals(code1.scheme);
}


@Override
public int hashCode() {
return Objects.hash(code, scheme);
}

public String toString() {
return code + "^" + display + "^" + scheme;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,16 @@
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
classifiedObject="Document01" nodeRepresentation="urn:connectathon:bppc:foundational:policy"
classifiedObject="Document01" nodeRepresentation="CT"
objectType="urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Classification"
id="id_8">
<rim:Slot name="codingScheme">
<rim:ValueList>
<rim:Value>1.3.6.1.4.1.21367.2017.3</rim:Value>
<rim:Value>1.2.840.10008.2.16.4</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Name>
<rim:LocalizedString value="Foundational Connectathon Read-Access Policy"/>
<rim:LocalizedString value="Computed Tomography"/>
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,16 @@
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
classifiedObject="Document01" nodeRepresentation="urn:connectathon:bppc:foundational:policy"
classifiedObject="Document01" nodeRepresentation="CT"
objectType="urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Classification"
id="id_8">
<rim:Slot name="codingScheme">
<rim:ValueList>
<rim:Value>1.3.6.1.4.1.21367.2017.3</rim:Value>
<rim:Value>1.2.840.10008.2.16.4</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Name>
<rim:LocalizedString value="Foundational Connectathon Read-Access Policy"/>
<rim:LocalizedString value="Computed Tomography"/>
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,16 @@
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
classifiedObject="Document01" nodeRepresentation="urn:connectathon:bppc:foundational:policy"
classifiedObject="Document01" nodeRepresentation="CT"
objectType="urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Classification"
id="id_8">
<rim:Slot name="codingScheme">
<rim:ValueList>
<rim:Value>1.3.6.1.4.1.21367.2017.3</rim:Value>
<rim:Value>1.2.840.10008.2.16.4</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Name>
<rim:LocalizedString value="Foundational Connectathon Read-Access Policy"/>
<rim:LocalizedString value="Computed Tomography"/>
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,16 @@
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
classifiedObject="Document01" nodeRepresentation="urn:connectathon:bppc:foundational:policy"
classifiedObject="Document01" nodeRepresentation="CT"
objectType="urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Classification"
id="id_8">
<rim:Slot name="codingScheme">
<rim:ValueList>
<rim:Value>1.3.6.1.4.1.21367.2017.3</rim:Value>
<rim:Value>1.2.840.10008.2.16.4</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Name>
<rim:LocalizedString value="Foundational Connectathon Read-Access Policy"/>
<rim:LocalizedString value="Computed Tomography"/>
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,16 +159,16 @@
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
classifiedObject="Document01" nodeRepresentation="urn:connectathon:bppc:foundational:policy"
classifiedObject="Document01" nodeRepresentation="CT"
objectType="urn:oasis:names:tc:ebxml-regrep:ObjectType:RegistryObject:Classification"
id="id_8">
<rim:Slot name="codingScheme">
<rim:ValueList>
<rim:Value>1.3.6.1.4.1.21367.2017.3</rim:Value>
<rim:Value>1.2.840.10008.2.16.4</rim:Value>
</rim:ValueList>
</rim:Slot>
<rim:Name>
<rim:LocalizedString value="Foundational Connectathon Read-Access Policy"/>
<rim:LocalizedString value="Computed Tomography"/>
</rim:Name>
</rim:Classification>
<rim:Classification classificationScheme="urn:uuid:2c6b8cb7-8b2a-4051-b291-b1ae6a575ef4"
Expand Down
Loading

0 comments on commit cf69956

Please sign in to comment.