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.datamodel.metadata;
20  
21  import java.io.IOException;
22  import java.net.URI;
23  import java.util.HashMap;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Optional;
27  
28  import org.apache.logging.log4j.LogManager;
29  import org.apache.logging.log4j.Logger;
30  import org.jdom2.Document;
31  import org.jdom2.Element;
32  import org.jdom2.filter.Filters;
33  import org.jdom2.xpath.XPathExpression;
34  import org.jdom2.xpath.XPathFactory;
35  import org.mycore.common.MCRException;
36  import org.xml.sax.SAXParseException;
37  
38  import com.google.gson.JsonObject;
39  
40  /**
41   * This class holds all information of a derivate. For persistence operations
42   * see methods of {@link MCRMetadataManager}.
43   * 
44   * @author Jens Kupferschmidt
45   * @author Thomas Scheffler
46   * @version $Revision$ $Date: 2010-09-30 17:49:21 +0200 (Thu, 30 Sep
47   *          2010) $
48   */
49  public final class MCRDerivate extends MCRBase {
50  
51      private static final Logger LOGGER = LogManager.getLogger();
52  
53      public static final String ROOT_NAME = "mycorederivate";
54  
55      public static final int MAX_LABEL_LENGTH = 256;
56  
57      // the object content
58      private MCRObjectDerivate mcrDerivate;
59  
60      private int order;
61  
62      protected String mcrLabel = null;
63  
64      /**
65       * This is the constructor of the MCRDerivate class. It make an instance of
66       * the parser class and the metadata class.
67       * 
68       * @exception MCRException
69       *                general Exception of MyCoRe
70       */
71      public MCRDerivate() throws MCRException {
72          super();
73          mcrDerivate = new MCRObjectDerivate(getId());
74          order = 1;
75      }
76  
77      public MCRDerivate(byte[] bytes, boolean valid) throws SAXParseException {
78          this();
79          setFromXML(bytes, valid);
80      }
81  
82      public MCRDerivate(Document doc) {
83          this();
84          setFromJDOM(doc);
85      }
86  
87      public MCRDerivate(URI uri) throws SAXParseException, IOException {
88          this();
89          setFromURI(uri);
90      }
91  
92      /**
93       * This methode return the instance of the MCRObjectDerivate class. If this
94       * was not found, null was returned.
95       * 
96       * @return the instance of the MCRObjectDerivate class
97       */
98      public MCRObjectDerivate getDerivate() {
99          return mcrDerivate;
100     }
101 
102     /**
103      * The given DOM was convert into an internal view of metadata. This are the
104      * object ID and the object label, also the blocks structure, flags and
105      * metadata.
106      * 
107      * @exception MCRException
108      *                general Exception of MyCoRe
109      */
110     @Override
111     protected void setUp() throws MCRException {
112         super.setUp();
113         setLabel(jdomDocument.getRootElement().getAttributeValue("label"));
114 
115         // get the derivate data of the object
116         Element derivateElement = jdomDocument.getRootElement().getChild("derivate");
117         mcrDerivate = new MCRObjectDerivate(mcrId, derivateElement);
118     }
119 
120     /**
121      * This methode create a XML stream for all object data.
122      * 
123      * @exception MCRException
124      *                if the content of this class is not valid
125      * @return a JDOM Document with the XML data of the object as byte array
126      */
127     @Override
128     public Document createXML() throws MCRException {
129         Document doc = super.createXML();
130         Element elm = doc.getRootElement();
131         elm.setAttribute("order", String.valueOf(order));
132         if (mcrLabel != null) {
133             elm.setAttribute("label", mcrLabel);
134         }
135         elm.addContent(mcrDerivate.createXML());
136         elm.addContent(mcrService.createXML());
137         return doc;
138     }
139 
140     @Override
141     protected String getRootTagName() {
142         return ROOT_NAME;
143     }
144 
145     /**
146      * Reads all files and urns from the derivate.
147      * 
148      * @return A {@link Map} which contains the files as key and the urns as value.
149      * If no URN assigned the map will be empty.
150      */
151     public Map<String, String> getUrnMap() {
152         Map<String, String> fileUrnMap = new HashMap<>();
153 
154         XPathExpression<Element> filesetPath = XPathFactory.instance().compile("./mycorederivate/derivate/fileset",
155             Filters.element());
156 
157         Element result = filesetPath.evaluateFirst(this.createXML());
158         if (result == null) {
159             return fileUrnMap;
160         }
161         String urn = result.getAttributeValue("urn");
162 
163         if (urn != null) {
164             XPathExpression<Element> filePath = XPathFactory
165                 .instance()
166                 .compile("./mycorederivate/derivate/fileset[@urn='" + urn + "']/file", Filters.element());
167             List<Element> files = filePath.evaluate(this.createXML());
168 
169             for (Element currentFileElement : files) {
170                 String currentUrn = currentFileElement.getChildText("urn");
171                 String currentFile = currentFileElement.getAttributeValue("name");
172                 fileUrnMap.put(currentFile, currentUrn);
173             }
174         }
175         return fileUrnMap;
176     }
177 
178     /**
179      * This methode return the label or null if it was not set. 
180      * 
181      * @return the label as a string
182      */
183     public String getLabel() {
184         return mcrLabel;
185     }
186 
187     /**
188      * The method print all informations about this MCRObject.
189      */
190     public void debug() {
191         if (LOGGER.isDebugEnabled()) {
192             LOGGER.debug("MCRDerivate ID : {}", mcrId);
193             LOGGER.debug("MCRDerivate Schema : {}", mcrSchema);
194             LOGGER.debug("");
195         }
196     }
197 
198     /**
199      * Validates this MCRDerivate. This method throws an exception if:
200      *  <ul>
201      *  <li>the mcr_id is null</li>
202      *  <li>the XML schema is null or empty</li>
203      *  <li>the service part is null or invalid</li>
204      *  <li>the MCRObjectDerivate is null or invalid</li>
205      *  </ul>
206      * 
207      * @throws MCRException the MCRDerivate is invalid
208      */
209     @Override
210     public void validate() throws MCRException {
211         super.validate();
212         MCRObjectDerivate derivate = getDerivate();
213         if (derivate == null) {
214             throw new MCRException("The <derivate> part of '" + getId() + "' is undefined.");
215         }
216         try {
217             derivate.validate();
218         } catch (Exception exc) {
219             throw new MCRException("The <derivate> part of '" + getId() + "' is invalid.", exc);
220         }
221     }
222 
223     /**
224      * @return the {@link MCRObjectID} of the owner of the derivate
225      */
226     public MCRObjectID getOwnerID() {
227         return this.getDerivate().getMetaLink().getXLinkHrefID();
228     }
229 
230     @Override
231     public void setId(MCRObjectID id) {
232         super.setId(id);
233         this.mcrDerivate.setDerivateID(id);
234     }
235 
236     /**
237      * This method set the derivate label.
238      * 
239      * @param label - the derivate label
240      */
241     public void setLabel(String label) {
242         if (label == null) {
243             mcrLabel = label;
244         } else {
245             mcrLabel = label.trim();
246             if (mcrLabel.length() > MAX_LABEL_LENGTH) {
247                 mcrLabel = mcrLabel.substring(0, MAX_LABEL_LENGTH);
248             }
249         }
250     }
251 
252     public int getOrder() {
253         return order;
254     }
255 
256     public void setOrder(int order) {
257         this.order = order;
258     }
259 
260     @Override
261     protected void setFromJDOM(Document doc) {
262         super.setFromJDOM(doc);
263         this.order = Optional.ofNullable(doc.getRootElement().getAttributeValue("order"))
264             .map(Integer::valueOf)
265             .orElse(1);
266     }
267 
268     @Override
269     public JsonObject createJSON() {
270         JsonObject base = super.createJSON();
271         if (mcrLabel != null) {
272             base.addProperty("label", mcrLabel);
273         }
274         return base;
275     }
276 }