diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java index 36df0a9f0cd3d56bc29490f2af27df829b8b76b7..019cbcebf4622b398c1f4b04adff7d05f293d113 100644 --- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java +++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/adapters/analysis/gui/AnalysisBeanGui.java @@ -86,6 +86,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; +import java.util.WeakHashMap; public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, AnalysisManager> @@ -128,6 +129,7 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi private boolean editMessageInGui; + private transient WeakHashMap<Analysis,GazelleTreeNodeImpl<AnalysisPart>> nodes; public AnalysisBeanGui(AnalysisManager analysisManager, AnalysisPartManager analysisPartManager, McaConfigManager mcaConfigManager, @@ -181,6 +183,7 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi } defineMessagePart(part, selectedObject); } + this.nodes = new WeakHashMap<>(); } private void defineMessagePart(AnalysisPart part, Analysis analysis) { @@ -236,7 +239,14 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi } public GazelleTreeNodeImpl<AnalysisPart> buildTree() { + if (selectedObject==null) { + return new GazelleTreeNodeImpl<>(); + } + if (nodes.containsKey(selectedObject)) { + return nodes.get(selectedObject); + } final GazelleTreeNodeImpl<AnalysisPart> tree = new GazelleTreeNodeImpl<>(); + nodes.put(selectedObject,tree); tree.setData(selectedObject.getRootAnalysisPart()); int index = 0; for (final AnalysisPart analysisPart : selectedObject.getRootAnalysisPart().getChildPart()) { @@ -301,19 +311,17 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi setDocumentText(displayedMessagePart); } + public boolean isDisplayablePart(AnalysisPart part) { + return part!=null && !isFolder(part); + } + private void setEnhancedDocumentContent(byte[] content) { setDocumentContent(content); - if ((analysisPartToDisplay.getDocType().equals(DocType.ZIP.getValue()) - || (analysisPartToDisplay.getDocType().equals(DocType.DOCUMENT.getValue()) - && !analysisPartToDisplay.getChildPart().isEmpty() - && analysisPartToDisplay.getChildPart().get(0).getDocType().equals("ZIP"))) - || (mcaConfigManager.getZipStructureWithDocType(analysisPartToDisplay.getDocType()) != null - || (analysisPartToDisplay.getDocType().equals(DocType.DOCUMENT.getValue()) - && !analysisPartToDisplay.getChildPart().isEmpty() - && mcaConfigManager.getZipStructureWithDocType(analysisPartToDisplay.getChildPart().get(0).getDocType()) != null))) { + if (isZipPart(analysisPartToDisplay)) { getDocument().setSyntax(HandledDocument.Syntax.ZIP); - } else if (analysisPartToDisplay.getDocType().endsWith("/")) { + } else if (isFolder(analysisPartToDisplay)) { GuiMessage.logMessage(StatusMessage.Severity.INFO, "net.ihe.gazelle.mca.ThisIsADirectory"); + return; } else if (isDisplayedPartXml() && !HandledDocument.Syntax.XML.equals(getDocument().getSyntax())) { getDocument().setSyntax(HandledDocument.Syntax.XML); } @@ -332,8 +340,19 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi } } - - + private boolean isZipPart(AnalysisPart node) { + return node!=null && StringUtils.isNotEmpty(node.getDocType()) + && ( + (node.getDocType().equals(DocType.ZIP.getValue()) + || (node.getDocType().equals(DocType.DOCUMENT.getValue()) + && !node.getChildPart().isEmpty() + && node.getChildPart().get(0).getDocType().equals("ZIP"))) + || (mcaConfigManager.getZipStructureWithDocType(node.getDocType()) != null + || (node.getDocType().equals(DocType.DOCUMENT.getValue()) + && !node.getChildPart().isEmpty() + && mcaConfigManager.getZipStructureWithDocType(node.getChildPart().get(0).getDocType()) != null)) + ); + } @Override public String performAnotherValidation() { @@ -469,7 +488,7 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi byte[] bytes; - if (node.getDocType().startsWith(MimeTypeDetector.FOLDER_PREFIX)) { + if (!isDownloadable(node)) { logFolderDownloadError(); return; } else { @@ -517,6 +536,14 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi } } + public boolean isDownloadable(AnalysisPart node) { + return node!=null && StringUtils.isNotEmpty(node.getDocType()) && !isFolder(node); + } + + public boolean isFolder(AnalysisPart node) { + return node.getDocType().endsWith("/") || node.getDocType().startsWith(MimeTypeDetector.FOLDER_PREFIX); + } + public String getIconForNode(final AnalysisPart node) { if (node == null || StringUtils.isEmpty(node.getDocType()) || StringUtils.isEmpty(node.getOid())) { return "gzl-icon-globe"; @@ -613,18 +640,9 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi String validate(final String objectPath, final AnalysisPart node) { try { - if ((node.getDocType().equals("ZIP") - || (node.getDocType().equals("DOCUMENT") - && !node.getChildPart().isEmpty() - && node.getChildPart().get(0).getDocType().equals("ZIP"))) - || (mcaConfigManager.getZipStructureWithDocType(node.getDocType()) != null - || (node.getDocType().equals("DOCUMENT") - && !node.getChildPart().isEmpty() - && mcaConfigManager.getZipStructureWithDocType(node.getChildPart().get(0).getDocType()) != null - ))) { + if (!isValidable(node)) { GuiMessage.logMessage(StatusMessage.Severity.ERROR, "net.ihe.gazelle.mca.CannotValidateAZipFile"); - return McaVueFileNaming.DETAILED_RESULT.getMenuLink() + "?" + QueryParam.PROCESSING_OID + "=" + findAnalysisOid( - node); + return McaVueFileNaming.DETAILED_RESULT.getMenuLink() + "?" + QueryParam.PROCESSING_OID + "=" + findAnalysisOid(node); } if (node.getDecodedPartFilePath() != null) { @@ -779,6 +797,20 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi } } + public boolean isValidable(AnalysisPart node) { + return node!=null && StringUtils.isNotEmpty(node.getDocType()) && !( + "ZIP".equals(node.getDocType()) + || ("DOCUMENT".equals(node.getDocType()) + && !node.getChildPart().isEmpty() + && "ZIP".equals(node.getChildPart().get(0).getDocType())) + || mcaConfigManager.getZipStructureWithDocType(node.getDocType()) != null + || ("DOCUMENT".equals(node.getDocType()) + && !node.getChildPart().isEmpty() + && mcaConfigManager.getZipStructureWithDocType(node.getChildPart().get(0).getDocType()) != null) + || (node.getDecodedPartFilePath() == null && EncodedType.ZIP_ENCODED.equals(node.getEncodedType()) && node.getDocType().contains(MimeTypeDetector.FOLDER_PREFIX)) + ); + } + private String readFileContent(String path) throws UnexpectedAnalysisException { try { return new ContentConverter().toString(FileUtils.readFileToByteArray(new File(path)), @@ -858,11 +890,16 @@ public class AnalysisBeanGui extends AbstractProcessingBeanGui<Analysis, Analysi List<EVSClientCrossValidatedObject> crossValidationInputList = new ArrayList<>(); for (AnalysisPart l_o_input : xValInputsList) { try { - crossValidationInputList.add(new CrossValidationInput(l_o_input.getxValInputType(), - mcaApi.getOriginalPartContent( - ((HandledObjectFile) analysisPart.getAnalysis().getObject()).getFilePath(), l_o_input), - "xml")); - } catch (UnexpectedAnalysisException e) { + Analysis analysis = findAnalysis(analysisPart); + HandledObjectFile file = ((HandledObjectFile) analysis.getObject()); + crossValidationInputList.add( + new CrossValidationInput( + l_o_input.getxValInputType(), + mcaApi.getOriginalPartContent( + file.getFilePath(), + l_o_input), + "xml")); + } catch (Exception e) { logUnexpectedException(e); } } diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java index e6cbfbe9d3a9a2641154727c648ec5e7bca30b49..66c737a7f3c1774c2554920f3fc4d35b0fb53b69 100644 --- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java +++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/McaApi.java @@ -177,7 +177,7 @@ public class McaApi implements Serializable { bytes = dicomToTxtConverter.dicom2txt(bytes); return bytes; } - } else if (node.getDocType().equals(MimeTypeConfigEnum.ZIP.getDocType())) { + } else if (isZipPart(node)) { try { return FileUtils.readFileToByteArray(file); @@ -198,4 +198,12 @@ public class McaApi implements Serializable { } return "Error retrieving string content".getBytes(StandardCharsets.UTF_8); } + + private boolean isZipPart(AnalysisPart node) { + return node.getDocType().equals(MimeTypeConfigEnum.ZIP.getDocType()) + || messageContentAnalyzer.isZipDocType(node.getDocType()) + || (node.getDocType().equals(DocType.DOCUMENT.getValue()) + && !node.getChildPart().isEmpty() + && messageContentAnalyzer.isZipDocType(node.getChildPart().get(0).getDocType())); + } } diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java index 17ec8bdb0cd4e3fcdfd06ad3673dcb2efc5d0b87..ddddf42b6d97beb796a16080b903fae29b8d341a 100644 --- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java +++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MessageContentAnalyzer.java @@ -8,7 +8,6 @@ import net.ihe.gazelle.mca.contentanalyzer.business.model.EncodedType; import java.io.Serializable; import java.nio.charset.StandardCharsets; -import java.nio.file.Files; public class MessageContentAnalyzer implements Serializable { private static final long serialVersionUID = -333802749228093354L; @@ -32,6 +31,10 @@ public class MessageContentAnalyzer implements Serializable { this(xmlAnalyzer, contentAnalysisTypeDetector, mimeTypeDetector, b64Analyzer, null); } + public boolean isZipDocType(String docType) { + return ((MimeTypeDetector)mimeTypeDetector).getZipStructureWithDocType(docType)!=null; + } + public MessageContentAnalyzer(Analyzer xmlAnalyzer, Analyzer contentAnalysisTypeDetector, Analyzer mimeTypeDetector, Analyzer b64Analyzer, byte[] messageName) { this.xmlAnalyzer = xmlAnalyzer; diff --git a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java index 17b1a2a44c0b0b3f433f2f1558176a1a5c1e36bd..e1efcab8fda5cdc1500baf3baf484cdcd52fbd19 100644 --- a/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java +++ b/MessageContentAnalyzer-ejb/src/main/java/net/ihe/gazelle/mca/contentanalyzer/application/analyzers/MimeTypeDetector.java @@ -373,4 +373,8 @@ public class MimeTypeDetector implements Analyzer { } return prefixInPart; } + + public ZipStructureInterface getZipStructureWithDocType(String docType) { + return mcaConfigDao.getZipStructureWithDocType(docType); + } } diff --git a/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties b/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties index 96064ae9357fb91bac87c9ae4166f0b79a6efd53..e5ed7aa5b07e812da13c33354a1489f24d7c1303 100644 --- a/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties +++ b/MessageContentAnalyzer-war/src/main/messages/MessageContentAnalyzer.properties @@ -129,4 +129,9 @@ net.ihe.gazelle.document.invalid-file-type=Invalid file type. Expected file type net.ihe.gazelle.document.prettify-content=Prettify content net.ihe.gazelle.document.view-lines-numbers=View lines numbers net.ihe.gazelle.document.prettified-content=The following content has been modified for better visualization. Validation will be performed on original content -net.ihe.gazelle.document.emptyContent=Content object must be defined and not empty \ No newline at end of file +net.ihe.gazelle.document.emptyContent=Content object must be defined and not empty + +net.ihe.gazelle.document.download-fragment=Download +net.ihe.gazelle.document.view-fragment=View +net.ihe.gazelle.document.cant-download-fragment=Fragment download failed. +net.ihe.gazelle.document.cant-show-fragment=Unable to show fragment. diff --git a/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml b/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml index bfcb32104ee587db92163f217757cae61a705eae..74a2c6e5098d522a8c3878fc23a216403d4f0074 100644 --- a/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml +++ b/MessageContentAnalyzer-war/src/main/webapp/common/_messageContentAnalyzerResultDiv.xhtml @@ -53,10 +53,14 @@ title="#{messages['net.ihe.gazelle.evs.ViewPart']}" ignoreDupResponses="true" action="#{analysisBeanGui.setMessagePart(analysisBeanGui.selectedObject.object.filePath, node.data)}" - render="panelPartArea"> + render="panelPartArea" + rendered="#{analysisBeanGui.isDisplayablePart(node.data)}"> <h:outputText value="#{node.data.docType}"/> <s:span styleClass="gzl-icon-eye"/> </a4j:commandLink> + <s:span rendered="#{not analysisBeanGui.isDisplayablePart(node.data)}"> + <h:outputText value="#{node.data.docType}"/> + </s:span> <h:outputLink value="#{analysisBeanGui.getValidationPermanentLinkFromDb(node.data.oid)}" @@ -65,15 +69,6 @@ <s:span title="#{messages['gazelle.evs.ClickToViewValidationOutcome']}" styleClass="#{analysisBeanGui.getIconForNode(node.data)}"/> </h:outputLink> - <!--XVal result--> - <h:outputLink - value="#{analysisBeanGui.getCrossValidationPermanentLink(node.data.oid)}" - target="_blank" - rendered="#{node.data.xValMatch.xValidatorOid != null and not empty node.data.xValMatch.xValidatorOid}"> - <s:span title="#{messages['net.ihe.gazelle.mca.ClickToViewCrossValidationOutcome']}" styleClass="#{analysisBeanGui.getIconForXNode(node.data.oid)}"/> - </h:outputLink> - - <a4j:commandLink action="#{analysisBeanGui.validate(node.data)}" target="_blank" @@ -86,34 +81,43 @@ action="#{analysisBeanGui.validate(node.data)}" target="_blank" execute="resultFormTokenId" - rendered="#{empty node.data.validationType}"> + rendered="#{empty node.data.validationType and analysisBeanGui.isValidable(node.data)}"> <span class="gzl-icon-stack" title="#{messages['net.ihe.gazelle.xval.Validate']}"> <em class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/> <em class="gzl-icon-question-circle gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/> </span> </a4j:commandLink> - <h:commandLink actionListener="#{analysisBeanGui.sendToXValidation(node.data)}" - rendered="#{node.data.xValidatorOid != null and not empty node.data.xValidatorOid and - analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}"> - <span class="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.SendToCrossValidation']}"> - <em class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/> - <em class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/> - </span> - </h:commandLink> - - <s:span styleClass="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.CrossValidatorNotAvailable']}" - rendered="#{node.data.xValidatorOid != null and not empty node.data.xValidatorOid and - not analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}"> - <em style="color:C6C6C6" class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/> - <em style="color:C6C6C6" class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/> + <!-- XVal --> + <s:span rendered="#{node.data.xValMatch.xValidatorOid != null and not empty node.data.xValMatch.xValidatorOid}"> + <s:span rendered="#{analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}"> + <h:commandLink actionListener="#{analysisBeanGui.sendToXValidation(node.data)}"> + <span class="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.SendToCrossValidation']}"> + <em class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/> + <em class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/> + </span> + </h:commandLink> + </s:span> + <s:span rendered="#{not analysisBeanGui.crossValidatorAvailable(node.data.xValidatorOid)}"> + <h:outputLink + value="#{analysisBeanGui.getCrossValidationPermanentLink(node.data.oid)}" + target="_blank"> + <s:span title="#{messages['net.ihe.gazelle.mca.ClickToViewCrossValidationOutcome']}" styleClass="#{analysisBeanGui.getIconForXNode(node.data.oid)}"/> + </h:outputLink> + <s:span styleClass="gzl-icon-stack" title="#{messages['net.ihe.gazelle.mca.CrossValidatorNotAvailable']}"> + <em style="color:C6C6C6" class="gzl-icon-play gzl-icon-stack-1x gzl-icon-stack-up "/> + <em style="color:C6C6C6" class="gzl-icon-times-blue gzl-icon-stack-1x gzl-icon-stack-small-bottom-right"/> + </s:span> + </s:span> </s:span> + + <h:commandLink title="#{messages['net.ihe.gazelle.evs.DownloadPart']}" ignoreDupResponses="true" action="#{analysisBeanGui.downloadFile(node.data, false)}" - rendered="#{analysisBeanGui.getNameSpaces().isEmpty()}"> + rendered="#{analysisBeanGui.getNameSpaces().isEmpty() and analysisBeanGui.isDownloadable(node.data)}"> <s:span title="#{messages['net.ihe.gazelle.xval.Download']}" styleClass="gzl-icon-download"/> </h:commandLink>