View Javadoc
1   /*
2    * This file is part of ***  M y C o R e  ***
3    * See http://www.mycore.de/ for details.
4    *
5    * MyCoRe is free software: you can redistribute it and/or modify
6    * it under the terms of the GNU General Public License as published by
7    * the Free Software Foundation, either version 3 of the License, or
8    * (at your option) any later version.
9    *
10   * MyCoRe is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with MyCoRe.  If not, see <http://www.gnu.org/licenses/>.
17   */
18  
19  package org.mycore.mets.frontend;
20  
21  import java.io.IOException;
22  import java.io.InputStream;
23  import java.io.OutputStream;
24  import java.nio.file.Files;
25  import java.text.MessageFormat;
26  import java.util.List;
27  import java.util.concurrent.ConcurrentLinkedQueue;
28  
29  import org.apache.logging.log4j.LogManager;
30  import org.apache.logging.log4j.Logger;
31  import org.jdom2.Document;
32  import org.jdom2.JDOMException;
33  import org.jdom2.input.SAXBuilder;
34  import org.jdom2.output.XMLOutputter;
35  import org.mycore.common.content.MCRContent;
36  import org.mycore.common.content.MCRPathContent;
37  import org.mycore.datamodel.common.MCRXMLMetadataManager;
38  import org.mycore.datamodel.metadata.MCRObjectID;
39  import org.mycore.datamodel.niofs.MCRPath;
40  import org.mycore.frontend.cli.MCRAbstractCommands;
41  import org.mycore.frontend.cli.MCRObjectCommands;
42  import org.mycore.frontend.cli.annotation.MCRCommand;
43  import org.mycore.frontend.cli.annotation.MCRCommandGroup;
44  import org.mycore.mets.model.MCRMETSGeneratorFactory;
45  import org.mycore.mets.model.converter.MCRSimpleModelXMLConverter;
46  import org.mycore.mets.model.converter.MCRXMLSimpleModelConverter;
47  import org.mycore.mets.model.simple.MCRMetsSimpleModel;
48  import org.mycore.mets.tools.MCRMetsSave;
49  import org.mycore.mets.validator.METSValidator;
50  import org.mycore.mets.validator.validators.ValidationException;
51  
52  @MCRCommandGroup(name = "Mets Commands")
53  public class MCRMetsCommands extends MCRAbstractCommands {
54  
55      private static final Logger LOGGER = LogManager.getLogger(MCRMetsCommands.class);
56  
57      public static ConcurrentLinkedQueue<String> invalidMetsQueue = new ConcurrentLinkedQueue<>();
58  
59      @MCRCommand(syntax = "validate selected mets", help = "validates all mets.xml of selected derivates", order = 10)
60      public static void validateSelectedMets() {
61          List<String> selectedObjectIDs = MCRObjectCommands.getSelectedObjectIDs();
62  
63          for (String objectID : selectedObjectIDs) {
64              LOGGER.info("Validate mets.xml of {}", objectID);
65              MCRPath metsFile = MCRPath.getPath(objectID, "/mets.xml");
66              if (Files.exists(metsFile)) {
67                  try {
68                      MCRContent content = new MCRPathContent(metsFile);
69                      InputStream metsIS = content.getInputStream();
70                      METSValidator mv = new METSValidator(metsIS);
71                      List<ValidationException> validationExceptionList = mv.validate();
72                      if (validationExceptionList.size() > 0) {
73                          invalidMetsQueue.add(objectID);
74                      }
75                      for (ValidationException validationException : validationExceptionList) {
76                          LOGGER.error(validationException.getMessage());
77                      }
78                  } catch (IOException e) {
79                      LOGGER.error("Error while reading mets.xml of {}", objectID, e);
80                  } catch (JDOMException e) {
81                      LOGGER.error("Error while parsing mets.xml of {}", objectID, e);
82                  }
83              }
84  
85          }
86      }
87  
88      @MCRCommand(syntax = "try fix invalid mets",
89          help = "This Command can be used to fix invalid mets files that was found in any validate selected mets runs.",
90          order = 15)
91      public static void fixInvalidMets() {
92          String selectedObjectID;
93          while ((selectedObjectID = invalidMetsQueue.poll()) != null) {
94              LOGGER.info("Try to fix METS of {}", selectedObjectID);
95              MCRPath metsFile = MCRPath.getPath(selectedObjectID, "/mets.xml");
96              SAXBuilder saxBuilder = new SAXBuilder();
97              Document metsDocument;
98              try (InputStream metsInputStream = Files.newInputStream(metsFile)) {
99                  metsDocument = saxBuilder.build(metsInputStream);
100             } catch (IOException | JDOMException e) {
101                 LOGGER.error(MessageFormat.format("Cannot fix METS of {0}. Can not parse mets.xml!", selectedObjectID),
102                     e);
103                 return;
104             }
105 
106             MCRMetsSimpleModel mcrMetsSimpleModel;
107             try {
108                 mcrMetsSimpleModel = MCRXMLSimpleModelConverter.fromXML(metsDocument);
109             } catch (Exception e) {
110                 LOGGER.error(
111                     MessageFormat.format("Cannot fix METS of {0}. Can not convert to SimpleModel!", selectedObjectID),
112                     e);
113                 return;
114             }
115 
116             Document newMets = MCRSimpleModelXMLConverter.toXML(mcrMetsSimpleModel);
117             XMLOutputter xmlOutputter = new XMLOutputter();
118             try (OutputStream os = Files.newOutputStream(metsFile)) {
119                 xmlOutputter.output(newMets, os);
120             } catch (IOException e) {
121                 LOGGER.error(
122                     MessageFormat.format("Cannot fix METS of {0}. Can not write mets to derivate.", selectedObjectID));
123             }
124         }
125     }
126 
127     @MCRCommand(syntax = "add mets files for derivate {0}", order = 20)
128     public static void addMetsFileForDerivate(String derivateID) {
129         MCRPath metsFile = MCRPath.getPath(derivateID, "/mets.xml");
130         if (!Files.exists(metsFile)) {
131             try {
132                 LOGGER.debug("Start MCRMETSGenerator for derivate {}", derivateID);
133                 Document mets = MCRMETSGeneratorFactory.create(MCRPath.getPath(derivateID, "/")).generate()
134                     .asDocument();
135                 MCRMetsSave.saveMets(mets, MCRObjectID.getInstance(derivateID));
136                 LOGGER.debug("Stop MCRMETSGenerator for derivate {}", derivateID);
137             } catch (Exception e) {
138                 LOGGER.error("Can't create mets file for derivate {}", derivateID);
139             }
140         }
141     }
142 
143     @MCRCommand(syntax = "add mets files for project id {0}", order = 30)
144     public static void addMetsFileForProjectID(String projectID) {
145         MCRXMLMetadataManager manager = MCRXMLMetadataManager.instance();
146         List<String> dervateList = manager.listIDsForBase(projectID + "_derivate");
147         for (String derivateID : dervateList) {
148             addMetsFileForDerivate(derivateID);
149         }
150     }
151 }