diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/app/ResipGraphicApp.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/app/ResipGraphicApp.java index 562e8677..40d0d93b 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/app/ResipGraphicApp.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/app/ResipGraphicApp.java @@ -53,6 +53,7 @@ import fr.gouv.vitam.tools.resip.threads.CleanThread; import fr.gouv.vitam.tools.resip.threads.ExportThread; import fr.gouv.vitam.tools.resip.threads.ImportThread; +import fr.gouv.vitam.tools.resip.threads.RecalculateDigestsThread; import fr.gouv.vitam.tools.resip.utils.ResipException; import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.seda.SedaVersion; @@ -128,7 +129,8 @@ public class ResipGraphicApp implements ActionListener, Runnable { // GUI elements. */ public static MainWindow mainWindow; - // MainWindow menu elements dis/enabled depending on work state and used by controller. */ + // MainWindow menu elements dis/enabled depending on work state and used by + // controller. */ private JMenuItem saveMenuItem, saveAsMenuItem, closeMenuItem; private JMenuItem sedaValidationMenuItem, sedaProfileValidationMenuItem; private JCheckBoxMenuItem structuredMenuItem, debugMenuItem, experimentalMenuItem; @@ -227,7 +229,7 @@ public ResipGraphicApp(CreationContext creationContext) throws ResipException { public void run() { try { - mainWindow = new MainWindow(this); //NOSONAR + mainWindow = new MainWindow(this); // NOSONAR mainWindow.setVisible(true); mainWindow.setLocationRelativeTo(null); this.searchDialog = new SearchDialog(mainWindow); @@ -437,6 +439,11 @@ public JMenuBar createMenu() { actionByMenuItem.put(menuItem, "RegenerateContinuousIds"); treatMenu.add(menuItem); + menuItem = new JMenuItem("Recalculer les empreintes"); + menuItem.addActionListener(this); + actionByMenuItem.put(menuItem, "RecalculateDigests"); + treatMenu.add(menuItem); + importMenu = new JMenu("Import"); menuBar.add(importMenu); @@ -600,6 +607,9 @@ else switch (action) { case "SortTreeViewer": doSortTreeViewer(); break; + case "RecalculateDigests": + recalculateDigests(); + break; // Context Menu case "SeeImportContext": seeImportContext(); @@ -934,6 +944,7 @@ void editPrefs() { preferencesDialog.ip.toPrefs(Preferences.getInstance()); Preferences.getInstance().save(); interfaceParameters = preferencesDialog.ip; + treatmentParameters = preferencesDialog.tp; debugMenuItem.setState(interfaceParameters.isDebugFlag()); experimentalMenuItem.setState(interfaceParameters.isExperimentalFlag()); structuredMenuItem.setState(interfaceParameters.isStructuredMetadataEditionFlag()); @@ -1155,6 +1166,20 @@ void doRegenerateContinuousIds() { if (currentWork != null) { currentWork.getDataObjectPackage().regenerateContinuousIds(); mainWindow.treePane.allTreeChanged(); + setModifiedContext(true); + } + } + + /** + * Recalculate digests. + */ + void recalculateDigests() { + if (currentWork != null) { + InOutDialog inOutDialog = new InOutDialog(mainWindow, "Recalcul des empreintes"); + RecalculateDigestsThread recalculateDigestsThread = new RecalculateDigestsThread(inOutDialog); + recalculateDigestsThread.execute(); + inOutDialog.setVisible(true); + setModifiedContext(true); } } @@ -1609,7 +1634,7 @@ private void about() { ); dialog.setVisible(true); } catch (Exception ignored) { - //no real case + // no real case } } @@ -1683,4 +1708,13 @@ private void toggleExperimentalMode() { ); } } + + /** + * Gets treatment parameters. + * + * @return the treatment parameters + */ + public static TreatmentParameters getTreatmentParameters() { + return getTheApp().treatmentParameters; + } } diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/event/DigestAlgorithmChangedEvent.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/event/DigestAlgorithmChangedEvent.java new file mode 100644 index 00000000..c559b468 --- /dev/null +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/event/DigestAlgorithmChangedEvent.java @@ -0,0 +1,51 @@ +/** + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to provide + * tools for construction and manipulation of SIP (Submission + * Information Package) conform to the SEDA (Standard d’Échange + * de données pour l’Archivage) standard. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package fr.gouv.vitam.tools.resip.event; + +public class DigestAlgorithmChangedEvent implements Event { + + private final String newDigestAlgorithm; + + public DigestAlgorithmChangedEvent(String newDigestAlgorithm) { + this.newDigestAlgorithm = newDigestAlgorithm; + } + + public String getNewDigestAlgorithm() { + return newDigestAlgorithm; + } +} diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/frame/preferences/PreferencesDialog.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/frame/preferences/PreferencesDialog.java index 72d7b474..c2d71655 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/frame/preferences/PreferencesDialog.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/frame/preferences/PreferencesDialog.java @@ -51,6 +51,7 @@ import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.DataObjectPackage; import fr.gouv.vitam.tools.sedalib.core.seda.SedaVersion; +import fr.gouv.vitam.tools.sedalib.utils.digest.DigestComputer; import javax.swing.*; import javax.swing.text.AbstractDocument; @@ -130,6 +131,7 @@ public class PreferencesDialog extends JDialog { private final JRadioButton structuredInterfaceRadioButton; private final JCheckBox debugModeCheckBox; private final JCheckBox experimentalModeCheckBox; + private final JComboBox digestAlgorithmComboBox; private final JFrame owner; @@ -222,7 +224,8 @@ public class PreferencesDialog extends JDialog { * * @param args the input arguments * @throws ClassNotFoundException the class not found exception - * @throws UnsupportedLookAndFeelException the unsupported look and feel exception + * @throws UnsupportedLookAndFeelException the unsupported look and feel + * exception * @throws InstantiationException the instantiation exception * @throws IllegalAccessException the illegal access exception * @throws NoSuchMethodException the no such method exception @@ -232,9 +235,9 @@ public class PreferencesDialog extends JDialog { */ public static void main(String[] args) throws ClassNotFoundException, UnsupportedLookAndFeelException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ResipException, InterruptedException { - ResipGraphicApp rga = new ResipGraphicApp(null); //NOSONAR used for debug run + ResipGraphicApp rga = new ResipGraphicApp(null); // NOSONAR used for debug run Thread.sleep(1000); - TestDialogWindow window = new TestDialogWindow(PreferencesDialog.class); //NOSONAR used for debug run + TestDialogWindow window = new TestDialogWindow(PreferencesDialog.class); // NOSONAR used for debug run } /** @@ -1411,6 +1414,26 @@ public PreferencesDialog(JFrame owner) { gbc.gridy = 5; treatmentParametersPanel.add(sedaVersionSelector, gbc); + gbc.gridy = 5; + treatmentParametersPanel.add(sedaVersionSelector, gbc); + + JLabel digestAlgorithmLabel = new JLabel("Algorithme de hachage par défaut:"); + gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.EAST; + gbc.insets = new Insets(0, 0, 5, 5); + gbc.gridx = 0; + gbc.gridy = 6; + treatmentParametersPanel.add(digestAlgorithmLabel, gbc); + + digestAlgorithmComboBox = new JComboBox<>(DigestComputer.ALGORITHMS.toArray(new String[0])); + digestAlgorithmComboBox.setSelectedItem(tp.getDigestAlgorithm()); + gbc = new GridBagConstraints(); + gbc.anchor = GridBagConstraints.WEST; + gbc.insets = new Insets(0, 0, 5, 5); + gbc.gridx = 1; + gbc.gridy = 6; + treatmentParametersPanel.add(digestAlgorithmComboBox, gbc); + JLabel interfaceLabel = new JLabel("Interface"); interfaceLabel.setFont(MainWindow.BOLD_LABEL_FONT); gbc = new GridBagConstraints(); @@ -1420,7 +1443,7 @@ public PreferencesDialog(JFrame owner) { gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridx = 0; - gbc.gridy = 6; + gbc.gridy = 7; treatmentParametersPanel.add(interfaceLabel, gbc); JLabel interfaceTypeLabel = new JLabel("Interface par défaut:"); @@ -1428,7 +1451,7 @@ public PreferencesDialog(JFrame owner) { gbc.anchor = GridBagConstraints.EAST; gbc.insets = new Insets(0, 0, 5, 5); gbc.gridx = 0; - gbc.gridy = 7; + gbc.gridy = 8; treatmentParametersPanel.add(interfaceTypeLabel, gbc); structuredInterfaceRadioButton = new JRadioButton("Structurée"); @@ -1436,7 +1459,7 @@ public PreferencesDialog(JFrame owner) { gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(0, 0, 5, 5); gbc.gridx = 1; - gbc.gridy = 7; + gbc.gridy = 8; treatmentParametersPanel.add(structuredInterfaceRadioButton, gbc); JRadioButton classicInterfaceRadioButton = new JRadioButton("XML-expert"); @@ -1444,7 +1467,7 @@ public PreferencesDialog(JFrame owner) { gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(0, 0, 5, 5); gbc.gridx = 2; - gbc.gridy = 7; + gbc.gridy = 8; treatmentParametersPanel.add(classicInterfaceRadioButton, gbc); ButtonGroup interfaceTypeButtonGroup = new ButtonGroup(); @@ -1459,7 +1482,7 @@ public PreferencesDialog(JFrame owner) { gbc.anchor = GridBagConstraints.NORTHEAST; gbc.insets = new Insets(0, 0, 5, 5); gbc.gridx = 0; - gbc.gridy = 8; + gbc.gridy = 9; treatmentParametersPanel.add(debugModeLabel, gbc); debugModeCheckBox = new JCheckBox("debug"); @@ -1468,7 +1491,7 @@ public PreferencesDialog(JFrame owner) { gbc.anchor = GridBagConstraints.NORTHWEST; gbc.insets = new Insets(0, 0, 5, 5); gbc.gridx = 1; - gbc.gridy = 8; + gbc.gridy = 9; treatmentParametersPanel.add(debugModeCheckBox, gbc); experimentalModeCheckBox = new JCheckBox("experimental"); @@ -1477,7 +1500,7 @@ public PreferencesDialog(JFrame owner) { gbc.anchor = GridBagConstraints.NORTHWEST; gbc.insets = new Insets(0, 0, 5, 5); gbc.gridx = 2; - gbc.gridy = 8; + gbc.gridy = 9; treatmentParametersPanel.add(experimentalModeCheckBox, gbc); // Buttons @@ -1741,6 +1764,7 @@ private boolean extractFromDialog() { return false; } tp.setDupMax(tmp); + tp.setDigestAlgorithm((String) digestAlgorithmComboBox.getSelectedItem()); SedaVersion selectedVersion = sedaVersionSelector.getSelectedVersion(); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/parameters/TreatmentParameters.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/parameters/TreatmentParameters.java index 1bff71d8..cd8347d2 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/parameters/TreatmentParameters.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/parameters/TreatmentParameters.java @@ -37,6 +37,7 @@ */ package fr.gouv.vitam.tools.resip.parameters; +import fr.gouv.vitam.tools.resip.event.DigestAlgorithmChangedEvent; import fr.gouv.vitam.tools.resip.event.EventBus; import fr.gouv.vitam.tools.resip.event.SedaVersionChangedEvent; import fr.gouv.vitam.tools.sedalib.core.seda.SedaVersion; @@ -68,6 +69,11 @@ public class TreatmentParameters { */ SedaVersion sedaVersion; + /** + * The digest algorithm. + */ + String digestAlgorithm; + /** * Instantiates a new creation context. */ @@ -75,6 +81,9 @@ public TreatmentParameters() { EventBus.subscribe(SedaVersionChangedEvent.class, event -> { this.sedaVersion = event.getNewVersion(); }); + EventBus.subscribe(DigestAlgorithmChangedEvent.class, event -> { + this.digestAlgorithm = event.getNewDigestAlgorithm(); + }); } private String canonizeCategoryName(String category) { @@ -90,6 +99,9 @@ public TreatmentParameters(Preferences preferences) { EventBus.subscribe(SedaVersionChangedEvent.class, event -> { this.sedaVersion = event.getNewVersion(); }); + EventBus.subscribe(DigestAlgorithmChangedEvent.class, event -> { + this.digestAlgorithm = event.getNewDigestAlgorithm(); + }); final String categoriesString = preferences .getPrefProperties() @@ -123,6 +135,8 @@ public TreatmentParameters(Preferences preferences) { .getProperty("treatmentParameters.seda2Version", defaultConfiguredSedaVersion); EventBus.publish(new SedaVersionChangedEvent(parseSedaVersion(configuredSedaVersion))); + + digestAlgorithm = preferences.getPrefProperties().getProperty("treatmentParameters.digestAlgorithm", "SHA-512"); } /** @@ -144,6 +158,7 @@ public void toPrefs(Preferences preferences) { } preferences.getPrefProperties().setProperty("treatmentParameters.dupMax", Integer.toString(dupMax)); preferences.getPrefProperties().setProperty("treatmentParameters.seda2Version", sedaVersion.toString()); + preferences.getPrefProperties().setProperty("treatmentParameters.digestAlgorithm", digestAlgorithm); } /** @@ -379,6 +394,7 @@ public void setDefaultPrefs() { formatByCategoryMap.put("Autres...", List.of("Other")); dupMax = 1000; sedaVersion = SedaVersion.V2_1; + digestAlgorithm = "SHA-512"; } // Getters and setters @@ -448,4 +464,23 @@ private SedaVersion parseSedaVersion(String version) { return SedaVersion.from(finalVersion); } + + /** + * Gets digest algorithm. + * + * @return the digest algorithm + */ + public String getDigestAlgorithm() { + return digestAlgorithm; + } + + /** + * Sets digest algorithm. + * + * @param digestAlgorithm the digest algorithm + */ + public void setDigestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + EventBus.publish(new DigestAlgorithmChangedEvent(digestAlgorithm)); + } } diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/components/viewers/DataObjectPackageTreeViewer.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/components/viewers/DataObjectPackageTreeViewer.java index 0987e462..b9291894 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/components/viewers/DataObjectPackageTreeViewer.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/components/viewers/DataObjectPackageTreeViewer.java @@ -387,6 +387,27 @@ public String convertValueToText( result = stn.getDataObject().getClass().getSimpleName() + " " + stn.getDataObject().getInDataObjectPackageId(); + + String algorithm = null; + if (stn.getDataObject() instanceof DataObjectGroup) { + DataObjectGroup dog = (DataObjectGroup) stn.getDataObject(); + for (BinaryDataObject bdo : dog.getBinaryDataObjectList()) { + if ( + bdo.getMetadataMessageDigest() != null && bdo.getMetadataMessageDigest().getAlgorithm() != null + ) { + algorithm = bdo.getMetadataMessageDigest().getAlgorithm(); + break; + } + } + } else if (stn.getDataObject() instanceof BinaryDataObject) { + BinaryDataObject bdo = (BinaryDataObject) stn.getDataObject(); + if (bdo.getMetadataMessageDigest() != null && bdo.getMetadataMessageDigest().getAlgorithm() != null) { + algorithm = bdo.getMetadataMessageDigest().getAlgorithm(); + } + } + if (algorithm != null) { + result += " (" + algorithm + ")"; + } } return result; } @@ -614,7 +635,7 @@ public void removeSubTree(TreePath removePath, boolean confirmFlag) { resetTouchedFromNode(childNode); countTouchedFromNode(childNode); removeNode(fatherNode, childNode, be); - //be.removeContentFromDataObjectPackage(fatherAU.getDataObjectPackage()); + // be.removeContentFromDataObjectPackage(fatherAU.getDataObjectPackage()); if (childAU != null) { fatherAU.removeChildArchiveUnit(childAU); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/BinaryDataObjectEditor.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/BinaryDataObjectEditor.java index a593ecc4..983979f4 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/BinaryDataObjectEditor.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/BinaryDataObjectEditor.java @@ -52,7 +52,7 @@ import fr.gouv.vitam.tools.sedalib.metadata.namedtype.*; import fr.gouv.vitam.tools.sedalib.utils.LocalDateTimeUtil; import fr.gouv.vitam.tools.sedalib.utils.SEDALibException; -import fr.gouv.vitam.tools.sedalib.utils.digest.DigestSha512; +import fr.gouv.vitam.tools.sedalib.utils.digest.DigestComputer; import uk.gov.nationalarchives.droid.core.interfaces.IdentificationResult; import javax.swing.*; @@ -115,6 +115,8 @@ else if (sm instanceof FileInfo) { } else if (sm instanceof FormatIdentification) { summaryList.add(getItOrUnknown(((FormatIdentification) sm).getSimpleMetadata("MimeType"))); summaryList.add(getItOrUnknown(((FormatIdentification) sm).getSimpleMetadata("FormatId"))); + } else if (sm instanceof DigestType) { + summaryList.add(getItOrUnknown(((DigestType) sm).getAlgorithm())); } } return String.join(", ", summaryList); @@ -159,7 +161,8 @@ public void createSEDAObjectEditorPanel() throws SEDALibException { private boolean setReadOnly(Path path) { try { // Office bug workaround - // This is a special patch to prevent Office to change a file when opening it to see the content... + // This is a special patch to prevent Office to change a file when opening it to + // see the content... if (System.getProperty("os.name").toLowerCase().contains("win")) Files.setAttribute( path, "dos:readonly", @@ -186,7 +189,7 @@ private void openButton() { if (editedOnDiskPath != null) { try { if (setReadOnly(editedOnDiskPath)) Desktop.getDesktop().open(editedOnDiskPath.toFile()); - } catch (IOException ignored) {} //NOSONAR + } catch (IOException ignored) {} // NOSONAR } } @@ -199,9 +202,10 @@ private SEDAObjectEditor getSEDAObjectEditor(String metadataName) { private void extractFileMetadataInEditors() { try { + String algorithm = ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm(); replaceOrAddObjectEditor( createSEDAObjectEditor( - new DigestType("MessageDigest", DigestSha512.compute(editedOnDiskPath), "SHA-512"), + new DigestType("MessageDigest", DigestComputer.compute(editedOnDiskPath, algorithm), algorithm), this ) ); @@ -296,7 +300,9 @@ private void defineButton() { /** * Create binary data object sample binary data object. * - * @param minimal the minimal flag, if true subfields are selected and values are empty, if false all subfields are added and values are default values + * @param minimal the minimal flag, if true subfields are selected and values + * are empty, if false all subfields are added and values are + * default values * @return the binary data object * @throws SEDALibException the seda lib exception */ diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/DataObjectGroupEditor.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/DataObjectGroupEditor.java index b26d79a0..18a2e73f 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/DataObjectGroupEditor.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/sedaobjecteditor/composite/DataObjectGroupEditor.java @@ -63,7 +63,7 @@ public class DataObjectGroupEditor extends CompositeEditor { * Instantiates a new DataObjectGroup editor. * * @param editedObject the DataObjectGroup editedObject - * @param father the father + * @param father the father */ public DataObjectGroupEditor(DataObjectGroup editedObject, SEDAObjectEditor father) { super(editedObject, father); @@ -80,15 +80,25 @@ public String getTag() { @Override public String getName() { - return ( + String name = translateTag("DataObjectGroup") + " - " + (editedObject == null ? translateTag("Unknown") : (getDataObjectGroupMetadata().getInDataObjectPackageId() == null ? "Tbd" - : getDataObjectGroupMetadata().getInDataObjectPackageId())) - ); + : getDataObjectGroupMetadata().getInDataObjectPackageId())); + if (editedObject != null) { + String algorithm = null; + for (BinaryDataObject bdo : getDataObjectGroupMetadata().getBinaryDataObjectList()) { + if (bdo.getMetadataMessageDigest() != null && bdo.getMetadataMessageDigest().getAlgorithm() != null) { + algorithm = bdo.getMetadataMessageDigest().getAlgorithm(); + break; + } + } + if (algorithm != null) name += " (" + algorithm + ")"; + } + return name; } private void removeDataObject(DataObject dataObject) { diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/AddThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/AddThread.java index 85c4f9a6..76c50813 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/AddThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/AddThread.java @@ -128,6 +128,10 @@ public AddThread(Work work, DataObjectPackageTreeNode targetNode, List fil this.inOutDialog = dialog; this.summary = null; this.exitThrowable = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); dialog.setThread(this); } @@ -152,30 +156,7 @@ public String doInBackground() { } inOutDialog.extProgressTextArea.setText("Import par glisser/déposer de fichiers\n"); ResipGraphicApp.getTheApp().addThreadRunning = true; - spl = null; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); DiskImportContext dic; diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ChangeSeda2VersionThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ChangeSeda2VersionThread.java index f5f474c8..6a9372d2 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ChangeSeda2VersionThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ChangeSeda2VersionThread.java @@ -41,7 +41,6 @@ import fr.gouv.vitam.tools.resip.data.Work; import fr.gouv.vitam.tools.resip.frame.InOutDialog; import fr.gouv.vitam.tools.resip.utils.ResipException; -import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.DataObjectPackage; import fr.gouv.vitam.tools.sedalib.core.seda.SedaVersion; import fr.gouv.vitam.tools.sedalib.core.seda.SedaVersionConverter; @@ -88,7 +87,10 @@ public ChangeSeda2VersionThread( this.dop = dop; this.inOutDialog = dialog; this.exitThrowable = null; - this.spl = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); dialog.setThread(this); } @@ -96,28 +98,6 @@ public ChangeSeda2VersionThread( public String doInBackground() { Work work = ResipGraphicApp.getTheApp().currentWork; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); if (work == null) throw new ResipException("Pas de contenu à transformer"); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckEndDateThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckEndDateThread.java index 880a5cc0..27905255 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckEndDateThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckEndDateThread.java @@ -42,7 +42,6 @@ import fr.gouv.vitam.tools.resip.frame.InOutDialog; import fr.gouv.vitam.tools.resip.frame.VerifyDateDialog; import fr.gouv.vitam.tools.resip.utils.ResipException; -import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.ArchiveUnit; import fr.gouv.vitam.tools.sedalib.utils.SEDALibProgressLogger; import org.joda.time.format.ISODateTimeFormat; @@ -74,7 +73,10 @@ public CheckEndDateThread(VerifyDateDialog dialog) { //input this.verifyDateDialog = dialog; this.exitThrowable = null; - this.spl = null; + this.spl = new ThreadLoggerFactory( + dialog.getExtProgressTextArea(), + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); } @Override @@ -83,27 +85,6 @@ public String doInBackground() { verifyDateDialog.getExtProgressTextArea().setText(""); Work work = ResipGraphicApp.getTheApp().currentWork; try { - int localLogLevel, localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = verifyDateDialog.getExtProgressTextArea().getText() + "\n" + log; - verifyDateDialog.getExtProgressTextArea().setText(newLog); - verifyDateDialog.getExtProgressTextArea().setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); if (work == null) throw new ResipException("Pas de contenu à valider"); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckProfileThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckProfileThread.java index 803c9e75..16b6c947 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckProfileThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CheckProfileThread.java @@ -41,7 +41,6 @@ import fr.gouv.vitam.tools.resip.data.Work; import fr.gouv.vitam.tools.resip.frame.InOutDialog; import fr.gouv.vitam.tools.resip.utils.ResipException; -import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.ArchiveTransfer; import fr.gouv.vitam.tools.sedalib.utils.SEDALibProgressLogger; @@ -73,7 +72,10 @@ public CheckProfileThread(String profileFileName, InOutDialog dialog) { this.profileFileName = profileFileName; this.inOutDialog = dialog; this.exitThrowable = null; - this.spl = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); dialog.setThread(this); } @@ -81,28 +83,6 @@ public CheckProfileThread(String profileFileName, InOutDialog dialog) { public String doInBackground() { Work work = ResipGraphicApp.getTheApp().currentWork; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); if (work == null) throw new ResipException("Pas de contenu à valider"); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CleanThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CleanThread.java index b0e59043..3191b35e 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CleanThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CleanThread.java @@ -39,7 +39,6 @@ import fr.gouv.vitam.tools.resip.app.ResipGraphicApp; import fr.gouv.vitam.tools.resip.frame.InOutDialog; -import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.utils.SEDALibProgressLogger; import javax.swing.*; @@ -72,6 +71,10 @@ public CleanThread(String workDir, InOutDialog dialog) { this.workDir = workDir; dialog.setThread(this); this.inOutDialog = dialog; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); } private void recursiveDelete(File inFile) throws IOException, InterruptedException { @@ -87,31 +90,8 @@ private void recursiveDelete(File inFile) throws IOException, InterruptedExcepti @Override public String doInBackground() { - spl = null; fileCounter = 0; try { - int localLogLevel, localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); - doProgressLog(spl, GLOBAL, "Nettoyage du répertoire: " + workDir, null); for (File f : new File(workDir).listFiles()) { if (f.isDirectory() && f.toString().endsWith("-tmpdir")) { diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CompactThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CompactThread.java index ae113f51..4b0105ec 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CompactThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/CompactThread.java @@ -116,6 +116,10 @@ public CompactThread(Work work, DataObjectPackageTreeNode targetNode, InOutDialo this.inOutDialog = dialog; this.summary = null; this.exitThrowable = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); dialog.setThread(this); } @@ -187,30 +191,7 @@ public String doInBackground() { } } ResipGraphicApp.getTheApp().addThreadRunning = true; - spl = null; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); ArchiveUnit targetArchiveUnit = targetNode.getArchiveUnit(); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DeCompactThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DeCompactThread.java index fe3dce4d..88c5f4e0 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DeCompactThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DeCompactThread.java @@ -118,6 +118,10 @@ public DeCompactThread(Work work, DataObjectPackageTreeNode targetNode, InOutDia this.inOutDialog = dialog; this.summary = null; this.exitThrowable = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); dialog.setThread(this); } @@ -189,30 +193,7 @@ public String doInBackground() { } } ResipGraphicApp.getTheApp().addThreadRunning = true; - spl = null; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); ArchiveUnit targetArchiveUnit = targetNode.getArchiveUnit(); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DuplicatesThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DuplicatesThread.java index 1fdffb25..5d6896c5 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DuplicatesThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/DuplicatesThread.java @@ -39,7 +39,6 @@ import fr.gouv.vitam.tools.resip.app.ResipGraphicApp; import fr.gouv.vitam.tools.resip.frame.DuplicatesWindow; -import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.*; import fr.gouv.vitam.tools.sedalib.metadata.data.FileInfo; import fr.gouv.vitam.tools.sedalib.metadata.namedtype.DigestType; @@ -102,6 +101,10 @@ public DuplicatesThread( this.binaryHash = binaryHash; this.binaryFilename = binaryFilename; this.physicalAllMD = physicalAllMD; + this.spl = new ThreadLoggerFactory( + null, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); } /** @@ -152,23 +155,6 @@ public String doInBackground() { String tmp; int counter = 0; try { - int localLogLevel, localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - null, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); dataObjectPackage = ResipGraphicApp.getTheApp().currentWork.getDataObjectPackage(); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExpandThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExpandThread.java index eb4dfb16..c3cf5c3c 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExpandThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExpandThread.java @@ -126,6 +126,10 @@ public ExpandThread( this.inOutDialog = dialog; this.summary = null; this.exitThrowable = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); dialog.setThread(this); } @@ -178,30 +182,7 @@ public String doInBackground() { } } ResipGraphicApp.getTheApp().addThreadRunning = true; - spl = null; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); doProgressLog( diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExportThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExportThread.java index cb379b06..09a055a4 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExportThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ExportThread.java @@ -43,7 +43,6 @@ import fr.gouv.vitam.tools.resip.parameters.CSVImportContext; import fr.gouv.vitam.tools.resip.parameters.Preferences; import fr.gouv.vitam.tools.resip.utils.ResipException; -import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.ArchiveTransfer; import fr.gouv.vitam.tools.sedalib.inout.exporter.ArchiveTransferToDiskExporter; import fr.gouv.vitam.tools.sedalib.inout.exporter.ArchiveTransferToSIPExporter; @@ -109,6 +108,10 @@ public ExportThread(Work work, int exportType, InOutDialog dialog) { dialog.setThread(this); this.inOutDialog = dialog; this.exitThrowable = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); } /** @@ -126,30 +129,7 @@ public static String readableFileSize(long size) { @Override public String doInBackground() { - spl = null; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); // first verify and reindex if neccesary diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ImportThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ImportThread.java index b175ec45..0e64def3 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ImportThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ImportThread.java @@ -68,10 +68,10 @@ */ public class ImportThread extends SwingWorker { - //input + // input private Work work; private InOutDialog inOutDialog; - //run output + // run output private String summary; private int fileCounter; private Throwable exitThrowable; @@ -89,7 +89,10 @@ public ImportThread(CreationContext cc, InOutDialog dialog) { this.inOutDialog = dialog; this.summary = null; this.exitThrowable = null; - this.spl = null; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); dialog.setThread(this); } @@ -124,9 +127,9 @@ private void setWorkFromArchiveDeliveryRequestReply(ArchiveDeliveryRequestReply private void recursiveDelete(File inFile) throws InterruptedException { if (inFile.isDirectory()) { for (File f : inFile.listFiles()) recursiveDelete(f); - inFile.delete(); //NOSONAR use the quickest method + inFile.delete(); // NOSONAR use the quickest method } else { - inFile.delete(); //NOSONAR use the quickest method + inFile.delete(); // NOSONAR use the quickest method fileCounter++; doProgressLogIfStep( spl, @@ -159,13 +162,18 @@ private String getTmpDirTarget(String workDir, String srcPathName) throws ResipE } private void doZipImport() throws ResipException, InterruptedException, SEDALibException { + String algorithm = ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm(); inOutDialog.extProgressTextArea.setText( - "Import depuis un fichier zip en " + work.getCreationContext().getOnDiskInput() + "\n" + "Import depuis un fichier zip en " + + work.getCreationContext().getOnDiskInput() + + " (algorithme: " + + algorithm + + ")\n" ); ZipImportContext zic = (ZipImportContext) work.getCreationContext(); String target = getTmpDirTarget(zic.getWorkDir(), zic.getOnDiskInput()); - //TODO add preferences for compressed filename import + // TODO add preferences for compressed filename import String encoding; if (work.getCreationContext().getOnDiskInput().endsWith("zip")) encoding = "CP850"; else encoding = "UTF8"; @@ -176,6 +184,7 @@ private void doZipImport() throws ResipException, InterruptedException, SEDALibE null, spl ); + zi.setDigestAlgorithm(algorithm); for (String ip : zic.getIgnorePatternList()) zi.addIgnorePattern(ip); zi.doImport(); setWorkFromArchiveTransfer(zi.getArchiveTransfer()); @@ -183,8 +192,13 @@ private void doZipImport() throws ResipException, InterruptedException, SEDALibE } private void doDiskImport() throws SEDALibException, InterruptedException { + String algorithm = ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm(); inOutDialog.extProgressTextArea.setText( - "Import depuis une hiérarchie disque en " + work.getCreationContext().getOnDiskInput() + "\n" + "Import depuis une hiérarchie disque en " + + work.getCreationContext().getOnDiskInput() + + " (algorithme: " + + algorithm + + ")\n" ); DiskImportContext diskImportContext = (DiskImportContext) work.getCreationContext(); DiskToArchiveTransferImporter di = new DiskToArchiveTransferImporter( @@ -193,6 +207,7 @@ private void doDiskImport() throws SEDALibException, InterruptedException { null, spl ); + di.setDigestAlgorithm(algorithm); for (String ip : diskImportContext.getIgnorePatternList()) di.addIgnorePattern(ip); di.doImport(); diskImportContext.setModelVersion(di.getModelVersion()); @@ -229,8 +244,13 @@ private void doDIPImport() throws ResipException, InterruptedException, SEDALibE } private void doCSVTreeImport() throws SEDALibException, InterruptedException { + String algorithm = ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm(); inOutDialog.extProgressTextArea.setText( - "Import depuis un csv d'arbre de classement en " + work.getCreationContext().getOnDiskInput() + "\n" + "Import depuis un csv d'arbre de classement en " + + work.getCreationContext().getOnDiskInput() + + " (algorithme: " + + algorithm + + ")\n" ); CSVTreeImportContext ctic = (CSVTreeImportContext) work.getCreationContext(); CSVTreeToDataObjectPackageImporter cti = new CSVTreeToDataObjectPackageImporter( @@ -239,6 +259,7 @@ private void doCSVTreeImport() throws SEDALibException, InterruptedException { ctic.getDelimiter(), spl ); + cti.setDigestAlgorithm(algorithm); cti.doImport(); work.setDataObjectPackage(cti.getDataObjectPackage()); work.setExportContext(new ExportContext(Preferences.getInstance())); @@ -246,8 +267,13 @@ private void doCSVTreeImport() throws SEDALibException, InterruptedException { } private void doCSVMetadataImportContext() throws SEDALibException, InterruptedException { + String algorithm = ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm(); inOutDialog.extProgressTextArea.setText( - "Import depuis un csv de métadonnées en " + work.getCreationContext().getOnDiskInput() + "\n" + "Import depuis un csv de métadonnées en " + + work.getCreationContext().getOnDiskInput() + + " (algorithme: " + + algorithm + + ")\n" ); CSVMetadataImportContext cmic = (CSVMetadataImportContext) work.getCreationContext(); CSVMetadataToDataObjectPackageImporter cmi = new CSVMetadataToDataObjectPackageImporter( @@ -256,6 +282,7 @@ private void doCSVMetadataImportContext() throws SEDALibException, InterruptedEx cmic.getDelimiter(), spl ); + cmi.setDigestAlgorithm(algorithm); cmi.doImport(); work.setDataObjectPackage(cmi.getDataObjectPackage()); work.setExportContext(new ExportContext(Preferences.getInstance())); @@ -265,8 +292,13 @@ private void doCSVMetadataImportContext() throws SEDALibException, InterruptedEx private void doMailImportContext() throws ResipException, InterruptedException, SEDALibException { int localLogLevel; int localLogStep; + String algorithm = ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm(); inOutDialog.extProgressTextArea.setText( - "Import depuis un conteneur courriel en " + work.getCreationContext().getOnDiskInput() + "\n" + "Import depuis un conteneur courriel en " + + work.getCreationContext().getOnDiskInput() + + " (algorithme: " + + algorithm + + ")\n" ); if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { localLogLevel = MailExtractProgressLogger.MESSAGE_DETAILS; @@ -309,6 +341,7 @@ private void doMailImportContext() throws ResipException, InterruptedException, List lp = new ArrayList<>(); lp.add(Paths.get(mi.getTarget())); DiskToArchiveTransferImporter di = new DiskToArchiveTransferImporter(lp, spl); + di.setDigestAlgorithm(ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm()); for (String ip : new DiskImportContext(Preferences.getInstance()).getIgnorePatternList()) di.addIgnorePattern( ip ); @@ -321,28 +354,6 @@ private void doMailImportContext() throws ResipException, InterruptedException, public String doInBackground() { ResipGraphicApp.getTheApp().importThreadRunning = true; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); if (work.getCreationContext() instanceof ZipImportContext) doZipImport(); else if (work.getCreationContext() instanceof DiskImportContext) doDiskImport(); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/MailExtractThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/MailExtractThread.java index 6c96f72f..6a8e0737 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/MailExtractThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/MailExtractThread.java @@ -89,6 +89,7 @@ public class MailExtractThread extends SwingWorker { private int fileCounter; // logger private SEDALibProgressLogger spl; + private final ThreadLoggerFactory threadLoggerFactory; /** * MailExtract a binary data object replacing it by the archive unit hierarchy, in a dedicated thread. @@ -142,6 +143,11 @@ public MailExtractThread( this.inOutDialog = dialog; this.summary = null; this.exitThrowable = null; + this.threadLoggerFactory = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ); + this.spl = threadLoggerFactory.getLogger(); dialog.setThread(this); } @@ -194,32 +200,7 @@ public String doInBackground() { } } ResipGraphicApp.getTheApp().addThreadRunning = true; - spl = null; try { - int localLogLevel; - int localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); - spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); - doProgressLog( spl, GLOBAL, @@ -233,13 +214,13 @@ public String doInBackground() { MailExtractProgressLogger mepl = new MailExtractProgressLogger( ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, + threadLoggerFactory.getLogLevel(), (count, log) -> { String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; inOutDialog.extProgressTextArea.setText(newLog); inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); }, - localLogStep, + threadLoggerFactory.localLogStep(), 2, MailExtractProgressLogger.MESSAGE_GROUP, 1000 diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/RecalculateDigestsThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/RecalculateDigestsThread.java new file mode 100644 index 00000000..2b795ed9 --- /dev/null +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/RecalculateDigestsThread.java @@ -0,0 +1,121 @@ +/** + * Copyright French Prime minister Office/SGMAP/DINSIC/Vitam Program (2019-2022) + * and the signatories of the "VITAM - Accord du Contributeur" agreement. + * + * contact@programmevitam.fr + * + * This software is a computer program whose purpose is to provide + * tools for construction and manipulation of SIP (Submission + * Information Package) conform to the SEDA (Standard d’Échange + * de données pour l’Archivage) standard. + * + * This software is governed by the CeCILL-C license under French law and + * abiding by the rules of distribution of free software. You can use, + * modify and/ or redistribute the software under the terms of the CeCILL-C + * license as circulated by CEA, CNRS and INRIA at the following URL + * "http://www.cecill.info". + * + * As a counterpart to the access to the source code and rights to copy, + * modify and redistribute granted by the license, users are provided only + * with a limited warranty and the software's author, the holder of the + * economic rights, and the successive licensors have only limited + * liability. + * + * In this respect, the user's attention is drawn to the risks associated + * with loading, using, modifying and/or developing or reproducing the + * software by the user in light of its specific status of free software, + * that may mean that it is complicated to manipulate, and that also + * therefore means that it is reserved for developers and experienced + * professionals having in-depth computer knowledge. Users are therefore + * encouraged to load and test the software's suitability as regards their + * requirements in conditions enabling the security of their systems and/or + * data to be ensured and, more generally, to use and operate it in the + * same conditions as regards security. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ +package fr.gouv.vitam.tools.resip.threads; + +import fr.gouv.vitam.tools.resip.app.ResipGraphicApp; +import fr.gouv.vitam.tools.resip.frame.InOutDialog; +import fr.gouv.vitam.tools.sedalib.core.BinaryDataObject; +import fr.gouv.vitam.tools.sedalib.utils.SEDALibException; +import fr.gouv.vitam.tools.sedalib.utils.SEDALibProgressLogger; + +import javax.swing.*; + +import static fr.gouv.vitam.tools.sedalib.utils.SEDALibProgressLogger.*; + +/** + * The type Recalculate digests thread. + */ +public class RecalculateDigestsThread extends SwingWorker { + + // input + private final InOutDialog inOutDialog; + // run output + private int counter; + private Throwable exitThrowable; + // logger + private final SEDALibProgressLogger spl; + + /** + * Instantiates a new Recalculate digests thread. + * + * @param dialog the dialog + */ + public RecalculateDigestsThread(InOutDialog dialog) { + dialog.setThread(this); + this.inOutDialog = dialog; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); + } + + @Override + public String doInBackground() { + counter = 0; + try { + String algorithm = ResipGraphicApp.getTreatmentParameters().getDigestAlgorithm(); + doProgressLog(spl, GLOBAL, "Recalcul des empreintes avec l'algorithme: " + algorithm, null); + + for (BinaryDataObject bdo : ResipGraphicApp.getTheApp() + .currentWork.getDataObjectPackage() + .getBdoInDataObjectPackageIdMap() + .values()) { + if (isCancelled()) break; + bdo.extractTechnicalElements(algorithm, spl); + counter++; + doProgressLogIfStep(spl, OBJECTS_GROUP, counter, counter + " empreintes recalculées"); + } + } catch (InterruptedException | SEDALibException e) { + exitThrowable = e; + return "KO"; + } + return "OK"; + } + + @Override + protected void done() { + inOutDialog.okButton.setEnabled(true); + inOutDialog.cancelButton.setEnabled(false); + if (isCancelled()) doProgressLogWithoutInterruption(spl, GLOBAL, "Recalcul des empreintes annulé", null); + else if (exitThrowable != null) doProgressLogWithoutInterruption( + spl, + GLOBAL, + "Erreur durant le recalcul des empreintes", + exitThrowable + ); + else { + doProgressLogWithoutInterruption( + spl, + GLOBAL, + "Recalcul des empreintes terminé: " + counter + " empreintes traitées", + null + ); + ResipGraphicApp.mainWindow.treePane.allTreeChanged(); + } + } +} diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/SeeManifestThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/SeeManifestThread.java index 7585f3bd..6a708748 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/SeeManifestThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/SeeManifestThread.java @@ -101,33 +101,16 @@ public SeeManifestThread(ManifestWindow manifestWindow, Work work, InOutDialog i this.manifestWindow = manifestWindow; this.work = work; this.inOutDialog = inOutDialog; + this.spl = new ThreadLoggerFactory( + inOutDialog.extProgressTextArea, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); } @Override public String doInBackground() { ArchiveTransfer archiveTransfer = new ArchiveTransfer(); try { - int localLogLevel, localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - (count, log) -> { - String newLog = inOutDialog.extProgressTextArea.getText() + "\n" + log; - inOutDialog.extProgressTextArea.setText(newLog); - inOutDialog.extProgressTextArea.setCaretPosition(newLog.length()); - }, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); work diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/StatisticThread.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/StatisticThread.java index 7d728fdf..82f61fce 100644 --- a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/StatisticThread.java +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/StatisticThread.java @@ -40,7 +40,6 @@ import fr.gouv.vitam.tools.resip.app.ResipGraphicApp; import fr.gouv.vitam.tools.resip.data.StatisticData; import fr.gouv.vitam.tools.resip.frame.StatisticWindow; -import fr.gouv.vitam.tools.resip.utils.ResipLogger; import fr.gouv.vitam.tools.sedalib.core.BinaryDataObject; import fr.gouv.vitam.tools.sedalib.core.DataObjectPackage; import fr.gouv.vitam.tools.sedalib.metadata.data.FormatIdentification; @@ -76,6 +75,10 @@ public class StatisticThread extends SwingWorker { */ public StatisticThread(StatisticWindow statisticWindow) { this.statisticWindow = statisticWindow; + this.spl = new ThreadLoggerFactory( + null, + ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag() + ).getLogger(); } private String findCategory(String formatId, LinkedHashMap> formatByCatgeoryMap) { @@ -88,23 +91,6 @@ private String findCategory(String formatId, LinkedHashMap> @Override public String doInBackground() { try { - int localLogLevel, localLogStep; - if (ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()) { - localLogLevel = SEDALibProgressLogger.OBJECTS_WARNINGS; - localLogStep = 1; - } else { - localLogLevel = SEDALibProgressLogger.OBJECTS_GROUP; - localLogStep = 1000; - } - spl = new SEDALibProgressLogger( - ResipLogger.getGlobalLogger().getLogger(), - localLogLevel, - null, - localLogStep, - 2, - SEDALibProgressLogger.OBJECTS_GROUP, - 1000 - ); spl.setDebugFlag(ResipGraphicApp.getTheApp().interfaceParameters.isDebugFlag()); DataObjectPackage dataObjectPackage = ResipGraphicApp.getTheApp().currentWork.getDataObjectPackage(); LinkedHashMap> sizeByCategoryMap = new LinkedHashMap>(); diff --git a/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ThreadLoggerFactory.java b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ThreadLoggerFactory.java new file mode 100644 index 00000000..0a97a531 --- /dev/null +++ b/resip/src/main/java/fr/gouv/vitam/tools/resip/threads/ThreadLoggerFactory.java @@ -0,0 +1,52 @@ +package fr.gouv.vitam.tools.resip.threads; + +import fr.gouv.vitam.tools.resip.utils.ResipLogger; +import fr.gouv.vitam.tools.sedalib.utils.SEDALibProgressLogger; + +import javax.swing.JTextArea; + +public class ThreadLoggerFactory { + + private final JTextArea loggingComponent; + private final boolean isDebugMode; + + public ThreadLoggerFactory(JTextArea loggingComponent, boolean isDebugMode) { + this.loggingComponent = loggingComponent; + this.isDebugMode = isDebugMode; + } + + public SEDALibProgressLogger getLogger() { + int localLogLevel = this.getLogLevel(); + int localLogStep = this.localLogStep(); + + return new SEDALibProgressLogger( + ResipLogger.getGlobalLogger().getLogger(), + localLogLevel, + (count, log) -> { + String newLog = loggingComponent.getText() + "\n" + log; + loggingComponent.setText(newLog); + loggingComponent.setCaretPosition(newLog.length()); + }, + localLogStep, + 2, + SEDALibProgressLogger.OBJECTS_GROUP, + 1000 + ); + } + + public int getLogLevel() { + if (isDebugMode) { + return SEDALibProgressLogger.OBJECTS_WARNINGS; + } + + return SEDALibProgressLogger.OBJECTS_GROUP; + } + + public int localLogStep() { + if (isDebugMode) { + return 1; + } + + return 1000; + } +} diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/BinaryDataObject.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/BinaryDataObject.java index 87347a69..f898839e 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/BinaryDataObject.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/BinaryDataObject.java @@ -48,7 +48,7 @@ import fr.gouv.vitam.tools.sedalib.metadata.namedtype.*; import fr.gouv.vitam.tools.sedalib.utils.SEDALibException; import fr.gouv.vitam.tools.sedalib.utils.SEDALibProgressLogger; -import fr.gouv.vitam.tools.sedalib.utils.digest.DigestSha512; +import fr.gouv.vitam.tools.sedalib.utils.digest.DigestComputer; import fr.gouv.vitam.tools.sedalib.xml.SEDAXMLEventReader; import fr.gouv.vitam.tools.sedalib.xml.SEDAXMLStreamWriter; import uk.gov.nationalarchives.droid.core.interfaces.IdentificationResult; @@ -333,6 +333,23 @@ private IdentificationResult identifyFormat(SEDALibProgressLogger logger, Path p * can't access file) */ public void extractTechnicalElements(SEDALibProgressLogger sedaLibProgressLogger) throws SEDALibException { + String algorithm = "SHA-512"; + if (getDataObjectPackage() != null) algorithm = getDataObjectPackage().getDigestAlgorithm(); + extractTechnicalElements(algorithm, sedaLibProgressLogger); + } + + /** + * Extract technical elements (lastmodified date, size, format, digest...) from + * file and complete the BinaryDataObject metadata. + * + * @param algorithm the hash algorithm + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected + * @throws SEDALibException if unable to get size or lastmodified date (probably + * can't access file) + */ + public void extractTechnicalElements(String algorithm, SEDALibProgressLogger sedaLibProgressLogger) + throws SEDALibException { long size; FileTime lastModifiedTime; try { @@ -347,7 +364,11 @@ public void extractTechnicalElements(SEDALibProgressLogger sedaLibProgressLogger updateFileInfo(lastModifiedTime); addMetadata( - new DigestType("MessageDigest", DigestSha512.compute(onDiskPath, sedaLibProgressLogger), "SHA-512") + new DigestType( + "MessageDigest", + DigestComputer.compute(onDiskPath, algorithm, sedaLibProgressLogger), + algorithm + ) ); addMetadata(new IntegerType("Size", size)); diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/DataObjectPackage.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/DataObjectPackage.java index d2cf0c66..c920811f 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/DataObjectPackage.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/core/DataObjectPackage.java @@ -59,9 +59,12 @@ * in tree structure ArchiveUnits and DataObjects. *

* It has also a specific exportMetadataList field which define the list - * of descriptive metadata elements kept in export to XML manifest or csv metadata file. This is used to restrict - * to the set of metadata that an archiving system can handle. This export filter do not apply to any other XML - * or csv format function (for example toString, toSedaXMLFragments, toCsvList...). + * of descriptive metadata elements kept in export to XML manifest or csv + * metadata file. This is used to restrict + * to the set of metadata that an archiving system can handle. This export + * filter do not apply to any other XML + * or csv format function (for example toString, toSedaXMLFragments, + * toCsvList...). */ public class DataObjectPackage { @@ -97,6 +100,11 @@ public class DataObjectPackage { */ private ArchiveUnit ghostRootAu; + /** + * The digest algorithm. + */ + private String digestAlgorithm; + // Inner objects /** @@ -163,7 +171,7 @@ public DataObjectPackage() { try { c.addNewMetadata("Title", "GhostRootAu"); } catch (SEDALibException ignored) { - //ignored + // ignored } this.ghostRootAu.setDataObjectPackage(this); @@ -173,6 +181,7 @@ public DataObjectPackage() { this.resetInOutCounter(); this.touchedInDataObjectPackageIdMap = new HashMap<>(); this.vitamNormalizationStatus = NORMALIZATION_STATUS_UNKNOWN; + this.digestAlgorithm = "SHA-512"; } // Methods @@ -191,14 +200,18 @@ private boolean isInDataObjectPackageIdUsed(String inDataPackageObjectId) { } /** - * Adds a DataObjectPackageIdElement (ArchiveUnit, BinaryDataObject, PhysicalDataObject, DataObjectGroup) as - * a DataObjectPackage element, defining a unique ID if not already defined (null). + * Adds a DataObjectPackageIdElement (ArchiveUnit, BinaryDataObject, + * PhysicalDataObject, DataObjectGroup) as + * a DataObjectPackage element, defining a unique ID if not already defined + * (null). *

- * This is only useful when creating a DataObjectPackageIdElement without providing an outer + * This is only useful when creating a DataObjectPackageIdElement without + * providing an outer * DataObjectPackage in constructor, for example during JSON deserialization. * * @param element the DataObjectPackageIdElement to add - * @throws SEDALibException if the element has a defined ID which is already present in the DataObjectPackage + * @throws SEDALibException if the element has a defined ID which is already + * present in the DataObjectPackage */ public void addDataObjectPackageIdElement(DataObjectPackageIdElement element) throws SEDALibException { if (element.inDataPackageObjectId == null) element.inDataPackageObjectId = getNextInDataObjectPackageID(); @@ -314,7 +327,7 @@ public void incTouchedInDataObjectPackageId(String inDataObjectPackageId) { * * @param inDataObjectPackageId the id in DataObjectPackage * @return the count value for the touched id in DataObjectPackage, or null if - * not touched + * not touched */ public Integer getTouchedInDataObjectPackageId(String inDataObjectPackageId) { return touchedInDataObjectPackageIdMap.get(inDataObjectPackageId); @@ -496,6 +509,24 @@ public String getDescription() { return result; } + /** + * Gets digest algorithm. + * + * @return the digest algorithm + */ + public String getDigestAlgorithm() { + return digestAlgorithm; + } + + /** + * Sets digest algorithm. + * + * @param digestAlgorithm the digest algorithm + */ + public void setDigestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + } + /** * Sets the all references by objects. *

@@ -580,7 +611,7 @@ public void moveContentFromDataObjectPackage(DataObjectPackage childDataObjectPa try { c.addNewMetadata("Title", "GhostRootAu"); } catch (SEDALibException ignored) { - //ignored + // ignored } childDataObjectPackage.getGhostRootAu().setDataObjectPackage(this); childDataObjectPackage.getGhostRootAu().setContent(c); @@ -732,7 +763,8 @@ public void normalizeUniqDataObjectGroup() throws SEDALibException { } /** - * Remove from DataObjectPackage lists all DataObjects (DataObjectGroup, BinaryDataObject, + * Remove from DataObjectPackage lists all DataObjects (DataObjectGroup, + * BinaryDataObject, * PhysicalDataObject) not used by an ArchiveUnit * * @param spl the SEDALib progress logger @@ -923,7 +955,8 @@ else if (dataObject instanceof PhysicalDataObject) pdoInDataObjectPackageIdMap.p } /** - * Actualise ArchiveUnit in maps and maintain an ordered list of all DataObjects to + * Actualise ArchiveUnit in maps and maintain an ordered list of all DataObjects + * to * reindex. * * @param archiveUnit the archive unit @@ -942,10 +975,12 @@ private void actualiseArchiveUnitId(ArchiveUnit archiveUnit, List or } /** - * Actualise all maps used to reference oll ArchiveUnits, DataObjectGroup, BinaryDataObject and + * Actualise all maps used to reference oll ArchiveUnits, DataObjectGroup, + * BinaryDataObject and * PhysicalDataObject IDs. *

- * This is usefull when an ArchiveUnit is removed, as the non more usefull reference is kept in the maps, + * This is usefull when an ArchiveUnit is removed, as the non more usefull + * reference is kept in the maps, * and so all ArchiveUnit defining the object can't be garbage collected. */ public void actualiseIdMaps() { @@ -978,7 +1013,8 @@ public void actualiseIdMaps() { * and set the vitamNormalizationStatus value. * * @param spl the SEDALib progress logger - * @throws SEDALibException if one verification fail. Important: nothing has been modified in the DataObjectPackage. + * @throws SEDALibException if one verification fail. Important: nothing has + * been modified in the DataObjectPackage. * @throws InterruptedException if interrupted */ public void vitamNormalize(SEDALibProgressLogger spl) throws SEDALibException, InterruptedException { @@ -990,10 +1026,12 @@ public void vitamNormalize(SEDALibProgressLogger spl) throws SEDALibException, I } /** - * Remove empty (no child archive unit, no data object) archive unit from all it's fathers and from the data object package. + * Remove empty (no child archive unit, no data object) archive unit from all + * it's fathers and from the data object package. * * @param archiveUnit the empty archive unit - * @return true if it's done, false if it's not possible (not empty or not found) + * @return true if it's done, false if it's not possible (not empty or not + * found) */ public boolean removeEmptyArchiveUnit(ArchiveUnit archiveUnit) { if (archiveUnit.getChildrenAuList().getCount() != 0) return false; @@ -1018,7 +1056,7 @@ public boolean removeEmptyArchiveUnit(ArchiveUnit archiveUnit) { num2 = Integer.parseInt(id2.substring(2)); return num1 - num2; } catch (NumberFormatException ignored) { - //ignored + // ignored } } return id1.compareTo(id2); @@ -1027,8 +1065,10 @@ public boolean removeEmptyArchiveUnit(ArchiveUnit archiveUnit) { /** * Export data object package, DataObjects part, of SEDA DataObjectPackage XML. * - * @param xmlWriter the SEDAXMLStreamWriter generating the SEDA manifest - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param xmlWriter the SEDAXMLStreamWriter generating the SEDA + * manifest + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws InterruptedException if export process is interrupted * @throws SEDALibException if the XML can't be written */ @@ -1097,11 +1137,14 @@ public void exportDataObjectPackageObjects( * Export data object package, ArchiveUnits and global metadata part, of SEDA * DataObjectPackage XML. * - * @param xmlWriter the SEDAXMLStreamWriter generating the SEDA manifest + * @param xmlWriter the SEDAXMLStreamWriter generating the SEDA + * manifest * @param imbricateFlag indicates if the manifest ArchiveUnits are to be - * exported in imbricate mode (true) or in flat mode + * exported in imbricate mode (true) or in flat + * mode * (false) - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws SEDALibException if the XML can't be written * @throws InterruptedException if export process is interrupted */ @@ -1149,11 +1192,14 @@ public void exportDataObjectPackageMetadata( /** * Export the whole structure in XML SEDA Manifest. * - * @param xmlWriter the SEDAXMLStreamWriter generating the SEDA manifest + * @param xmlWriter the SEDAXMLStreamWriter generating the SEDA + * manifest * @param imbricateFlag indicates if the manifest ArchiveUnits are to be - * exported in imbricate mode (true) or in flat mode + * exported in imbricate mode (true) or in flat + * mode * (false) - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws SEDALibException if the XML can't be written * @throws InterruptedException if export process is interrupted */ @@ -1177,7 +1223,8 @@ public void toSedaXml( * @param xmlReader the SEDAXMLEventReader reading the SEDA manifest * @param dataObjectPackage the DataObjectPackage to be completed * @param rootDir the directory of the BinaryDataObject files - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws SEDALibException if the XML can't be read or SEDA scheme is not * respected * @throws InterruptedException if export process is interrupted @@ -1256,7 +1303,8 @@ public static void importDataObjectPackageObjects( * * @param xmlReader the SEDAXMLEventReader reading the SEDA manifest * @param dataObjectPackage the DataObjectPackage to be completed - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws SEDALibException if the XML can't be read or SEDA scheme is not * respected * @throws InterruptedException if export process is interrupted @@ -1308,9 +1356,11 @@ public static void importDataObjectPackageMetadata( * Import the whole structure in XML SEDA Manifest. * * @param xmlReader the SEDAXMLEventReader reading the SEDA manifest - * @param rootDir the directory where the BinaryDataObject files are + * @param rootDir the directory where the BinaryDataObject files + * are * exported - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @return the read DataObjectPackage * @throws SEDALibException if the XML can't be read or SEDA scheme is not * respected @@ -1466,7 +1516,8 @@ public void setGhostRootAu(ArchiveUnit ghostRootAu) { } /** - * Replace an archive unit by another, everywhere possible in the DataObjectPackage + * Replace an archive unit by another, everywhere possible in the + * DataObjectPackage * and purge all archive units no more linked to root. * * @param originArchiveUnit the origin archive unit diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVMetadataToDataObjectPackageImporter.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVMetadataToDataObjectPackageImporter.java index 0a9a72c4..46c688c3 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVMetadataToDataObjectPackageImporter.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVMetadataToDataObjectPackageImporter.java @@ -67,41 +67,67 @@ /** * The Class CSVMetadataToDataObjectPackageImporter. *

- * It will import a DataObjectPackage from metadata being defined in a csv file and files on disk. + * It will import a DataObjectPackage from metadata being defined in a csv file + * and files on disk. *

* The csv has one header line. At the beginning there must be either: *

    - *
  • only one column with 'File': then this column contains the file (or directory) path which is also used as uniq ID and which defines the hierarchy as the file hierarchy;
  • - *
  • two columns with 'File' and 'ParentFile': then the 'File' column contains the file (or directory) path which is also used as uniq ID and - * the 'ParentFile' column contains the file (or directory )name of the parent ArchiveUnit;
  • - *
  • three columns with 'ID', 'File' and 'ParentFile': then the 'File' column contains the file (or directory) path which is also used as uniq ID and - * the 'ParentFile' column contains the file (or directory )name of the parent ArchiveUnit. ID is ignored;
  • - *
  • three columns with 'ID', 'ParentID' and 'File' : then the 'File' column contains the file (or directory) path, - * the 'ID' column is used as uniq ID and the 'ParentID' column contains the ID of the parent ArchiveUnit.
  • - *
  • three columns with 'ID', 'ParentID' and 'ObjectFiles' : then the 'ObjectFiles' column contains the concatenated - * binary data objects files path with '|' joiner, the 'ID' column is used as uniq ID and the 'ParentID' column contains the ID of the parent ArchiveUnit.
  • - *
  • four columns with 'ID', 'ParentID', 'File' and 'ObjectFiles' : then the 'File' column contains the file - * (or directory) path for ArchiveUnit (only given for easy human reading), the 'ObjectFiles' column contains the concatenated + *
  • only one column with 'File': then this column contains the file (or + * directory) path which is also used as uniq ID and which defines the hierarchy + * as the file hierarchy;
  • + *
  • two columns with 'File' and 'ParentFile': then the 'File' column contains + * the file (or directory) path which is also used as uniq ID and + * the 'ParentFile' column contains the file (or directory )name of the parent + * ArchiveUnit;
  • + *
  • three columns with 'ID', 'File' and 'ParentFile': then the 'File' column + * contains the file (or directory) path which is also used as uniq ID and + * the 'ParentFile' column contains the file (or directory )name of the parent + * ArchiveUnit. ID is ignored;
  • + *
  • three columns with 'ID', 'ParentID' and 'File' : then the 'File' column + * contains the file (or directory) path, + * the 'ID' column is used as uniq ID and the 'ParentID' column contains the ID + * of the parent ArchiveUnit.
  • + *
  • three columns with 'ID', 'ParentID' and 'ObjectFiles' : then the + * 'ObjectFiles' column contains the concatenated + * binary data objects files path with '|' joiner, the 'ID' column is used as + * uniq ID and the 'ParentID' column contains the ID of the parent + * ArchiveUnit.
  • + *
  • four columns with 'ID', 'ParentID', 'File' and 'ObjectFiles' : then the + * 'File' column contains the file + * (or directory) path for ArchiveUnit (only given for easy human reading), the + * 'ObjectFiles' column contains the concatenated * binary data objects files path with '|' joiner, - * the 'ID' column is used as uniq ID and the 'ParentID' column contains the ID of the parent ArchiveUnit. - * This is the extended format written by csv exporter {@link fr.gouv.vitam.tools.sedalib.inout.exporter.DataObjectPackageToCSVMetadataExporter}.
  • + * the 'ID' column is used as uniq ID and the 'ParentID' column contains the ID + * of the parent ArchiveUnit. + * This is the extended format written by csv exporter + * {@link fr.gouv.vitam.tools.sedalib.inout.exporter.DataObjectPackageToCSVMetadataExporter}. *
- * Paths are absolute or if relative this is from the metadata csv file directory. + * Paths are absolute or if relative this is from the metadata csv file + * directory. *

- * After that the columns defines metadata path, each tag being separeted by a dot, or an attribute ('attr' column) of the metadata in the previous colum. + * After that the columns defines metadata path, each tag being separeted by a + * dot, or an attribute ('attr' column) of the metadata in the previous colum. *

- * For example: Writer.FullName|Description|attr defines first colum of values to put in - * <Writer><FullName>VALUE</FullName></Writer>, then values to put in <Description>VALUE</Description> + * For example: Writer.FullName|Description|attr defines first colum of values + * to put in + * <Writer><FullName>VALUE</FullName></Writer>, then + * values to put in <Description>VALUE</Description> * and finally attributes to put in <Description> if any. - * If many values of a tag has to be defined in csv, for example 2 Writers, then it's defined has Writer.0 and Writer.1, and FullName is Writer.0.FullName. + * If many values of a tag has to be defined in csv, for example 2 Writers, then + * it's defined has Writer.0 and Writer.1, and FullName is Writer.0.FullName. *

* The importer imports objects: *

    - *
  • For the non extended formats, the importer try to integrate all files in the ArchiveUnits directories defined on disk.
  • - *
  • For the extended format, the importer simply try to import in the DataObjectPackage all files defined in ObjectFiles.
  • + *
  • For the non extended formats, the importer try to integrate all files in + * the ArchiveUnits directories defined on disk.
  • + *
  • For the extended format, the importer simply try to import in the + * DataObjectPackage all files defined in ObjectFiles.
  • *
* The file name are analysed to extract Usage Version if encoded like in - * {@link fr.gouv.vitam.tools.sedalib.inout.importer.DiskToDataObjectPackageImporter} (filename formatted __Usage_Version__originalfilename or by default considered as BinaryMaster_1). If the file doesn't exist, this is only logged (no import fail) and the object is not imported. + * {@link fr.gouv.vitam.tools.sedalib.inout.importer.DiskToDataObjectPackageImporter} + * (filename formatted __Usage_Version__originalfilename or by default + * considered as BinaryMaster_1). If the file doesn't exist, this is only logged + * (no import fail) and the object is not imported. */ public class CSVMetadataToDataObjectPackageImporter { @@ -209,14 +235,24 @@ public Line( private SEDALibProgressLogger sedaLibProgressLogger; /** - * Instantiates a new DataObjectPackage importer from a csv metadata file with associated file collection. + * The digest algorithm. + */ + private String digestAlgorithm; + + /** + * Instantiates a new DataObjectPackage importer from a csv metadata file with + * associated file collection. *

- * It will analyse the csv metadata file, verify that described files exist and associates metadata and file. + * It will analyse the csv metadata file, verify that described files exist and + * associates metadata and file. * * @param csvMetadataFileName the csv metadata file name - * @param encoding the encoding format string (most of the time UTF8 or Cp1252) - * @param separator the char used as column separator (; or , or \t...) - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param encoding the encoding format string (most of the time + * UTF8 or Cp1252) + * @param separator the char used as column separator (; or , or + * \t...) + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws SEDALibException if file doesn't exist */ public CSVMetadataToDataObjectPackageImporter( @@ -236,13 +272,16 @@ public CSVMetadataToDataObjectPackageImporter( this.sedaLibProgressLogger = sedaLibProgressLogger; this.encoding = encoding; this.separator = separator; + this.digestAlgorithm = "SHA-512"; } /** - * Read csv file and construct the map with all parsed csv lines by GUID either ID or file name + * Read csv file and construct the map with all parsed csv lines by GUID either + * ID or file name * * @return the need ID regeneration flag - * @throws SEDALibException if csv file can't be accessed or is badly formatted + * @throws SEDALibException if csv file can't be accessed or is badly + * formatted * @throws InterruptedException if import process is interrupted */ private boolean readCSVFile() throws SEDALibException, InterruptedException { @@ -273,7 +312,7 @@ private boolean readCSVFile() throws SEDALibException, InterruptedException { try { currentLine = new Line( metadataFormatter.getGUID(row), - metadataFormatter.getParentGUID(row), //NOSONAR + metadataFormatter.getParentGUID(row), // NOSONAR metadataFormatter.getFile(row), metadataFormatter.getObjectFiles(row), metadataFormatter.doFormatAndExtractContentXML(row), @@ -294,7 +333,7 @@ private boolean readCSVFile() throws SEDALibException, InterruptedException { throw new SEDALibException("Le fichier csv [" + csvMetadataFileName + "] n'est pas accessible"); } if (metadataFormatter != null) return metadataFormatter.needIdRegeneration(); - else return false; //if file empty... + else return false; // if file empty... } private Path getAbsolutePath(String file) { @@ -431,6 +470,7 @@ public void doImport() throws SEDALibException, InterruptedException { boolean needIdRegeneration = readCSVFile(); dataObjectPackage = new DataObjectPackage(); + dataObjectPackage.setDigestAlgorithm(digestAlgorithm); int lineCount = 0; for (Map.Entry e : linesMap.entrySet()) { @@ -483,6 +523,15 @@ public void doImport() throws SEDALibException, InterruptedException { ); } + /** + * Sets the digest algorithm. + * + * @param digestAlgorithm the digest algorithm + */ + public void setDigestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + } + /** * Gets the data object package. * diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVTreeToDataObjectPackageImporter.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVTreeToDataObjectPackageImporter.java index 24d3ceb1..0e038652 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVTreeToDataObjectPackageImporter.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CSVTreeToDataObjectPackageImporter.java @@ -72,11 +72,13 @@ *

  • id : uniq number
  • *
  • nom : ArchiveUnit "title" metadata
  • *
  • observations : ArchiveUnit "description"
  • - *
  • cote : specific suffix for this ArchiveUnit in the hierarchic cotation id
  • + *
  • cote : specific suffix for this ArchiveUnit in the hierarchic cotation + * id
  • *
  • série : "mother" ArchiveUnit cotation id
  • *
  • ... : any other not used content
  • * - * Lines without "série" field are supposed to represent an ArchiveUnit at description level + * Lines without "série" field are supposed to represent an ArchiveUnit at + * description level * "Series" others are at "Subseries" description level. */ public class CSVTreeToDataObjectPackageImporter { @@ -136,13 +138,21 @@ protected Line(String uniqId, String title, String description, String suffix, S */ private SEDALibProgressLogger sedaLibProgressLogger; + /** + * The digest algorithm. + */ + private String digestAlgorithm; + /** * Instantiates a new csv tree file importer. * * @param csvFileName the csv file name - * @param encoding the encoding format string (most of the time UTF8 or Cp1252) - * @param separator the char used as column separator (; or , or \t...) - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param encoding the encoding format string (most of the time + * UTF8 or Cp1252) + * @param separator the char used as column separator (; or , or + * \t...) + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws SEDALibException if file doesn't exist */ public CSVTreeToDataObjectPackageImporter( @@ -162,13 +172,15 @@ public CSVTreeToDataObjectPackageImporter( this.sedaLibProgressLogger = sedaLibProgressLogger; this.encoding = encoding; this.separator = separator; + this.digestAlgorithm = "SHA-512"; } /** * Read csv file and construct the map with all parsed csv lines by cotation * and series root lines list * - * @throws SEDALibException if csv file can't be accessed or is badly formatted + * @throws SEDALibException if csv file can't be accessed or is badly + * formatted * @throws InterruptedException if import process is interrupted */ private void readCSVFile() throws SEDALibException, InterruptedException { @@ -227,7 +239,7 @@ private ArchiveUnit addLineAndChildren(Line line) throws InterruptedException { else content.addNewMetadata("DescriptionLevel", "Subseries"); content.addNewMetadata("OriginatingAgencyArchiveUnitIdentifier", line.motherId + line.suffix); } catch (Exception ignored) { - //ignored + // ignored } au.setContent(content); List childLines = linesMap.get(line.motherId + line.suffix); @@ -250,7 +262,8 @@ private ArchiveUnit addLineAndChildren(Line line) throws InterruptedException { /** * Do import the csv tree to ArchiveTransfer. * - * @throws SEDALibException if the csv can't be accessed or is badly formatted + * @throws SEDALibException if the csv can't be accessed or is badly + * formatted * @throws InterruptedException if export process is interrupted */ public void doImport() throws SEDALibException, InterruptedException { @@ -263,6 +276,7 @@ public void doImport() throws SEDALibException, InterruptedException { readCSVFile(); dataObjectPackage = new DataObjectPackage(); + dataObjectPackage.setDigestAlgorithm(digestAlgorithm); dataObjectPackage.resetInOutCounter(); List rootLines = linesMap.get(""); @@ -294,6 +308,15 @@ public void doImport() throws SEDALibException, InterruptedException { ); } + /** + * Sets the digest algorithm. + * + * @param digestAlgorithm the digest algorithm + */ + public void setDigestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + } + /** * Gets the data object pacakge. * diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CompressedFileToArchiveTransferImporter.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CompressedFileToArchiveTransferImporter.java index 068f0283..6a62e661 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CompressedFileToArchiveTransferImporter.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/CompressedFileToArchiveTransferImporter.java @@ -74,14 +74,16 @@ /** * The Class CompressedFileToArchiveTransferImporter. *

    - * Class for compressed file (zip, tar...) import in ArchiveTransfer object, similar to disk hierarchy import. + * Class for compressed file (zip, tar...) import in ArchiveTransfer object, + * similar to disk hierarchy import. *

    * Known compression format are zip, tar, tar.gz, bzip */ public class CompressedFileToArchiveTransferImporter { /** - * Wrap org.apache.commons.compress SevenZFile to have same ArchiveInputStream behavior + * Wrap org.apache.commons.compress SevenZFile to have same ArchiveInputStream + * behavior */ private static class SevenZWrapper extends ArchiveInputStream { @@ -182,6 +184,11 @@ public void close() throws IOException { */ private final SEDALibProgressLogger sedaLibProgressLogger; + /** + * The digest algorithm. + */ + private String digestAlgorithm; + /** * The constant ZIP. */ @@ -260,7 +267,7 @@ private ArchiveInputStream createArchiveInputStream() throws SEDALibException { try { fis.close(); } catch (IOException ex) { - //ignore + // ignore } } throw new SEDALibException("Impossible d'ouvrir le fichier compressé [" + onDiskPath.toString() + "]", e); @@ -323,11 +330,15 @@ private void unCompressContainer() throws SEDALibException, InterruptedException * Instantiates a new compressed file importer. * * @param compressedFile the compressed file - * @param unCompressDirectory the directory where the compressedfile is uncompressed - * @param encoding the filename encoding charset, if null will be determine considering + * @param unCompressDirectory the directory where the + * compressedfile is uncompressed + * @param encoding the filename encoding charset, if + * null will be determine considering * the compressed file format - * @param extractTitleFromFileNameFunction the extract title from file name function - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param extractTitleFromFileNameFunction the extract title from file name + * function + * @param sedaLibProgressLogger the progress logger or null if no + * progress log expected * @throws SEDALibException if file or directory doesn't exist */ public CompressedFileToArchiveTransferImporter( @@ -369,6 +380,7 @@ public CompressedFileToArchiveTransferImporter( ) throw new SEDALibException( "Le chemin [" + unCompressDirectory + "] pointant le répertoire d'extraction ne désigne pas un répertoire" ); + this.digestAlgorithm = "SHA-512"; } /** @@ -403,8 +415,9 @@ private GlobalMetadata processGlobalMetadata(Path path) throws SEDALibException /** * Do import the compressed file to ArchiveTransfer. * - * @throws SEDALibException if the XML manifest can't be read or is not in expected - * form, or compressed file can't be uncompressed + * @throws SEDALibException if the XML manifest can't be read or is not in + * expected + * form, or compressed file can't be uncompressed * @throws InterruptedException if export process is interrupted */ public void doImport() throws SEDALibException, InterruptedException { @@ -458,6 +471,7 @@ public void doImport() throws SEDALibException, InterruptedException { for (String patternString : ignorePatternStrings) diskToDataObjectPackageImporter.addIgnorePattern( patternString ); + diskToDataObjectPackageImporter.setDigestAlgorithm(digestAlgorithm); diskToDataObjectPackageImporter.doImport(); archiveTransfer.setDataObjectPackage(diskToDataObjectPackageImporter.getDataObjectPackage()); @@ -470,6 +484,15 @@ public void doImport() throws SEDALibException, InterruptedException { ); } + /** + * Sets the digest algorithm. + * + * @param digestAlgorithm the digest algorithm + */ + public void setDigestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + } + /** * Gets the archive transfer. * diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToArchiveTransferImporter.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToArchiveTransferImporter.java index 6361e24a..17b85e9a 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToArchiveTransferImporter.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToArchiveTransferImporter.java @@ -70,7 +70,8 @@ *

  • GlobalMetadata XML fragments from the __GlobalMetadata.xml file
  • *
  • ManagementMetadata XML element at the end of DataObjectPackage from the * __ManagementMetadata.xml file
  • - *
  • each root ArchiveUnit from a sub directory or other file, and recursively all the + *
  • each root ArchiveUnit from a sub directory or other file, and recursively + * all the * DataObjectPackage structure (see {@link DiskToDataObjectPackageImporter} for * details)
  • * @@ -108,6 +109,11 @@ public class DiskToArchiveTransferImporter { */ private SEDALibProgressLogger sedaLibProgressLogger; + /** + * The digest algorithm. + */ + private String digestAlgorithm; + /** * Instantiates a new ArchiveTransfer importer from a single directory name. *

    @@ -115,7 +121,8 @@ public class DiskToArchiveTransferImporter { * ArchiveUnit or a special metadata file * * @param directory the directory name - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected * @throws SEDALibException if not a directory */ public DiskToArchiveTransferImporter(String directory, SEDALibProgressLogger sedaLibProgressLogger) @@ -131,14 +138,18 @@ public DiskToArchiveTransferImporter(String directory, SEDALibProgressLogger sed *

    * It will take into account two options: *

      - *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic link are ignored
    • - *
    • extractTitleFromFileNameFunction: define the function used to extract Title from file name (if null simpleCopy is used)
    • + *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic + * link are ignored
    • + *
    • extractTitleFromFileNameFunction: define the function used to extract + * Title from file name (if null simpleCopy is used)
    • *
    * * @param directory the directory name * @param noLinkFlag the no link flag - * @param extractTitleFromFileNameFunction the extract title from file name function - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param extractTitleFromFileNameFunction the extract title from file name + * function + * @param sedaLibProgressLogger the progress logger or null if no + * progress log expected * @throws SEDALibException if not a directory */ public DiskToArchiveTransferImporter( @@ -176,6 +187,7 @@ public DiskToArchiveTransferImporter( extractTitleFromFileNameFunction, sedaLibProgressLogger ); + this.digestAlgorithm = "SHA-512"; } /** @@ -185,7 +197,8 @@ public DiskToArchiveTransferImporter( * ArchiveUnit or a special metadata file * * @param paths the paths - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected */ public DiskToArchiveTransferImporter(List paths, SEDALibProgressLogger sedaLibProgressLogger) { this(paths, false, simpleCopy, sedaLibProgressLogger); @@ -199,14 +212,18 @@ public DiskToArchiveTransferImporter(List paths, SEDALibProgressLogger sed *

    * It will take into account two options: *

      - *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic link are ignored
    • - *
    • extractTitleFromFileNameFunction: define the function used to extract Title from file name (if null simpleCopy is used)
    • + *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic + * link are ignored
    • + *
    • extractTitleFromFileNameFunction: define the function used to extract + * Title from file name (if null simpleCopy is used)
    • *
    * * @param paths the paths * @param noLinkFlag the no link flag - * @param extractTitleFromFileNameFunction the extract title from file name function - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param extractTitleFromFileNameFunction the extract title from file name + * function + * @param sedaLibProgressLogger the progress logger or null if no + * progress log expected */ public DiskToArchiveTransferImporter( List paths, @@ -230,6 +247,7 @@ public DiskToArchiveTransferImporter( extractTitleFromFileNameFunction, sedaLibProgressLogger ); + this.digestAlgorithm = "SHA-512"; } /** @@ -295,6 +313,7 @@ public void doImport() throws SEDALibException, InterruptedException { if (onDiskGlobalMetadataPath != null) archiveTransfer.setGlobalMetadata( processGlobalMetadata(onDiskGlobalMetadataPath) ); + diskToDataObjectPackageImporter.setDigestAlgorithm(digestAlgorithm); diskToDataObjectPackageImporter.doImport(); archiveTransfer.setDataObjectPackage(diskToDataObjectPackageImporter.getDataObjectPackage()); @@ -307,6 +326,15 @@ public void doImport() throws SEDALibException, InterruptedException { ); } + /** + * Sets the digest algorithm. + * + * @param digestAlgorithm the digest algorithm + */ + public void setDigestAlgorithm(String digestAlgorithm) { + this.digestAlgorithm = digestAlgorithm; + } + /** * Gets the ArchiveTransfer * diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToDataObjectPackageImporter.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToDataObjectPackageImporter.java index ee57e205..2d71d79a 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToDataObjectPackageImporter.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/inout/importer/DiskToDataObjectPackageImporter.java @@ -76,7 +76,8 @@ * file itself, being the BinaryMaster_1 and with format identification * compliant to PRONOM register *
  • the title of ArchiveUnit is the directory/file name, if no other metadata - * is defined. A lambda function can also be defined to derive the title from directory/file name.
  • + * is defined. A lambda function can also be defined to derive the title from + * directory/file name. * * For example, if you import this disk hierarchy: *

    @@ -125,7 +126,8 @@ *

    * Model V2-Extended model *

      - *
    • in a directory when there is a __ArchiveUnitMetadata.xml file, it's used to + *
    • in a directory when there is a __ArchiveUnitMetadata.xml file, it's used + * to * define the generated ArchiveUnit metadata. At root level you can have one or * more XML elements that define metadata but not structure that is to say * >ArchiveUnitProfile<, >Management< or >Content<
    • @@ -148,10 +150,13 @@ * reference to the ArchiveUnit or the DataObjectGroup represented by the * target *
    - * There are also two options in any model, that can be added to the constructors: + * There are also two options in any model, that can be added to the + * constructors: *
      - *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic link are ignored (default false)
    • - *
    • extractTitleFromFileNameFunction: define the function used to extract Title from file name (default simple copy)
    • + *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic + * link are ignored (default false)
    • + *
    • extractTitleFromFileNameFunction: define the function used to extract + * Title from file name (default simple copy)
    • *
    */ public class DiskToDataObjectPackageImporter { @@ -256,14 +261,18 @@ private DiskToDataObjectPackageImporter( *

    * It will take into account two options: *

      - *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic link are ignored
    • - *
    • extractTitleFromFileNameFunction: define the function used to extract Title from file name (if null simpleCopy is used)
    • + *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic + * link are ignored
    • + *
    • extractTitleFromFileNameFunction: define the function used to extract + * Title from file name (if null simpleCopy is used)
    • *
    * * @param directory the directory * @param noLinkFlag the no link flag - * @param extractTitleFromFileNameFunction the extract title from file name function - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param extractTitleFromFileNameFunction the extract title from file name + * function + * @param sedaLibProgressLogger the progress logger or null if no + * progress log expected * @throws SEDALibException if not a directory */ public DiskToDataObjectPackageImporter( @@ -296,7 +305,8 @@ public DiskToDataObjectPackageImporter( * ArchiveUnit or the management metadata file * * @param paths the paths - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param sedaLibProgressLogger the progress logger or null if no progress log + * expected */ public DiskToDataObjectPackageImporter(List paths, SEDALibProgressLogger sedaLibProgressLogger) { this(paths, false, simpleCopy, sedaLibProgressLogger); @@ -310,14 +320,18 @@ public DiskToDataObjectPackageImporter(List paths, SEDALibProgressLogger s *

    * It will take into account two options: *

      - *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic link are ignored
    • - *
    • extractTitleFromFileNameFunction: define the function used to extract Title from file name (if null simpleCopy is used)
    • + *
    • noLinkFlag: determine if the windows shortcut or windows/linux symbolic + * link are ignored
    • + *
    • extractTitleFromFileNameFunction: define the function used to extract + * Title from file name (if null simpleCopy is used)
    • *
    * * @param paths the paths * @param noLinkFlag the no link flag - * @param extractTitleFromFileNameFunction the extract title from file name function - * @param sedaLibProgressLogger the progress logger or null if no progress log expected + * @param extractTitleFromFileNameFunction the extract title from file name + * function + * @param sedaLibProgressLogger the progress logger or null if no + * progress log expected */ public DiskToDataObjectPackageImporter( List paths, @@ -376,7 +390,7 @@ private boolean analyzeLink(Path path) { return true; } } catch (IOException | ParseException ignored) { - //ignored + // ignored } lastAnalyzedLinkTarget = null; return false; @@ -485,7 +499,8 @@ private ArchiveUnit processSymbolicLink(Path path) throws SEDALibException, Inte } /** - * Extract data object version string either usage or usage_version from file name. + * Extract data object version string either usage or usage_version from file + * name. * * @param filename the filename * @return the data object version string @@ -506,9 +521,12 @@ public static String extractDataObjectVersion(String filename) { * @param path the path * @param filename the file name * @param au the au - * @param dog the DataObjectGroup containing this DataObject, if null has to be created + * @param dog the DataObjectGroup containing this DataObject, if null has + * to be created * @return the data object group containing this DataObject - * @throws SEDALibException if there's a usage_version problem (coherence between file content and file name), or access problem to metadata file + * @throws SEDALibException if there's a usage_version problem (coherence + * between file content and file name), or access + * problem to metadata file */ private DataObjectGroup addPhysicalDataObjectMetadata( Path path, @@ -549,9 +567,12 @@ else if (!pdoDataObjectVersion.getValue().equals(dataObjectVersion)) throw new S * @param path the path * @param filename the file name * @param au the au - * @param dog the DataObjectGroup containing this DataObject, if null has to be created + * @param dog the DataObjectGroup containing this DataObject, if null has + * to be created * @return the data object group containing this DataObject - * @throws SEDALibException if there's a usage_version problem (coherence between file content and file name), or access problem to metadata file + * @throws SEDALibException if there's a usage_version problem (coherence + * between file content and file name), or access + * problem to metadata file */ private DataObjectGroup addBinaryDataObjectMetadata( Path path, @@ -608,7 +629,8 @@ else if (!bdoDataObjectVersion.getValue().equals(dataObjectVersion)) throw new S * @param path the path * @param filename the file name * @param au the au - * @param dog the DataObjectGroup containing this DataObject, if null has to be created + * @param dog the DataObjectGroup containing this DataObject, if null has + * to be created * @return the data object group containing this DataObject * @throws SEDALibException if there's an access problem to binary file */ @@ -1007,6 +1029,15 @@ private DataObjectGroup getDataObjectGroup(Path path) { return dogPathStringMap.get(path.toAbsolutePath().normalize().toString()); } + /** + * Sets the digest algorithm. + * + * @param algorithm the algorithm + */ + public void setDigestAlgorithm(String algorithm) { + dataObjectPackage.setDigestAlgorithm(algorithm); + } + /** * Gets the summary of the import process. * diff --git a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestSha512.java b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestComputer.java similarity index 73% rename from sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestSha512.java rename to sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestComputer.java index 06d58f69..2ac9a788 100644 --- a/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestSha512.java +++ b/sedalib/src/main/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestComputer.java @@ -43,46 +43,64 @@ import java.nio.file.Path; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.List; /** * Utility class for computing file digests using optimized methods. */ -public class DigestSha512 { +public class DigestComputer { - private static final String SHA512_ALGORITHM = "SHA-512"; + /** + * The constant ALGORITHMS. + */ + public static final List ALGORITHMS = Arrays.asList( + "SHA-512", + "SHA-384", + "SHA-256", + "SHA-1", + "SHA3-512", + "SHA3-384", + "SHA3-256", + "SHA3-224", + "MD5", + "MD2" + ); // Private constructor to hide the implicit public one - private DigestSha512() {} + private DigestComputer() {} /** - * compute SHA-512 digest for a file. + * Compute digest for a file with a specific algorithm. * Automatically switches between standard IO and parallel prefetching based on * file size. * - * @param path the file path - * @param logger the logger (can be null) + * @param path the file path + * @param algorithm the hash algorithm (e.g., "SHA-512", "SHA-256") + * @param logger the logger (can be null) * @return the hex string of the digest * @throws SEDALibException if an error occurs */ - public static String compute(Path path, SEDALibProgressLogger logger) throws SEDALibException { + public static String compute(Path path, String algorithm, SEDALibProgressLogger logger) throws SEDALibException { try { - MessageDigest digest = MessageDigest.getInstance(SHA512_ALGORITHM); + MessageDigest digest = MessageDigest.getInstance(algorithm); byte[] hash = new NioDigestComputer().compute(digest, path, logger); return bytesToHex(hash); } catch (NoSuchAlgorithmException e) { - throw new SEDALibException("Impossible de mobiliser l'algorithme de hashage " + SHA512_ALGORITHM, e); + throw new SEDALibException("Impossible de mobiliser l'algorithme de hashage " + algorithm, e); } } /** - * compute SHA-512 digest for a file (no logger). + * Compute digest for a file with a specific algorithm (no logger). * - * @param path the file path + * @param path the file path + * @param algorithm the hash algorithm * @return the hex string of the digest * @throws SEDALibException if an error occurs */ - public static String compute(Path path) throws SEDALibException { - return compute(path, null); + public static String compute(Path path, String algorithm) throws SEDALibException { + return compute(path, algorithm, null); } private static String bytesToHex(byte[] bytes) { diff --git a/sedalib/src/test/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestSha512Test.java b/sedalib/src/test/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestComputerTest.java similarity index 85% rename from sedalib/src/test/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestSha512Test.java rename to sedalib/src/test/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestComputerTest.java index a29e1d6c..67bda4de 100644 --- a/sedalib/src/test/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestSha512Test.java +++ b/sedalib/src/test/java/fr/gouv/vitam/tools/sedalib/utils/digest/DigestComputerTest.java @@ -50,7 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat; -class DigestSha512Test { +class DigestComputerTest { @TempDir Path tempDir; @@ -63,7 +63,7 @@ void testComputeDigestSmallFile() throws IOException, SEDALibException, NoSuchAl Files.writeString(file, content); // When - String digest = DigestSha512.compute(file); + String digest = DigestComputer.compute(file, "SHA-512"); // Then MessageDigest md = MessageDigest.getInstance("SHA-512"); @@ -73,6 +73,24 @@ void testComputeDigestSmallFile() throws IOException, SEDALibException, NoSuchAl assertThat(digest).isEqualTo(expected); } + @Test + void testComputeDigestSHA256() throws IOException, SEDALibException, NoSuchAlgorithmException { + // Given + Path file = tempDir.resolve("sha256.txt"); + String content = "SHA-256 test"; + Files.writeString(file, content); + + // When + String digest = DigestComputer.compute(file, "SHA-256"); + + // Then + MessageDigest md = MessageDigest.getInstance("SHA-256"); + byte[] expectedBytes = md.digest(content.getBytes()); + String expected = bytesToHex(expectedBytes); + + assertThat(digest).isEqualTo(expected); + } + @Test void testComputeDigestEmptyFile() throws IOException, SEDALibException, NoSuchAlgorithmException { // Given @@ -80,7 +98,7 @@ void testComputeDigestEmptyFile() throws IOException, SEDALibException, NoSuchAl Files.createFile(file); // When - String digest = DigestSha512.compute(file); + String digest = DigestComputer.compute(file, "SHA-512"); // Then MessageDigest md = MessageDigest.getInstance("SHA-512"); @@ -103,7 +121,7 @@ void testComputeDigestLargeFile() throws IOException, SEDALibException, NoSuchAl Files.write(file, data); // When - String digest = DigestSha512.compute(file); + String digest = DigestComputer.compute(file, "SHA-512"); // Then MessageDigest md = MessageDigest.getInstance("SHA-512"); @@ -125,14 +143,10 @@ void testComputeDigestFileLargerThan2GB() throws IOException, SEDALibException, } // When - String digest = DigestSha512.compute(file); + String digest = DigestComputer.compute(file, "SHA-512"); // Then // We know a sparse file reads as zeros. - // To verify, we can either hardcode the hash of 2.5GB of zeros or compute it. - // Computing it in the test ensures correctness but takes time. - // 2.5GB read ~ 5-10s at 500MB/s. - MessageDigest md = MessageDigest.getInstance("SHA-512"); byte[] buffer = new byte[64 * 1024]; // 64KB of zeros long remaining = size;