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 static org.mycore.common.MCRConstants.DEFAULT_ENCODING;
22  import static org.mycore.common.MCRConstants.XLINK_NAMESPACE;
23  import static org.mycore.common.MCRConstants.XSI_NAMESPACE;
24  
25  import java.io.IOException;
26  import java.net.URI;
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.mycore.common.MCRCoreVersion;
33  import org.mycore.common.MCRException;
34  import org.mycore.common.config.MCRConfiguration2;
35  import org.mycore.common.content.MCRByteContent;
36  import org.mycore.common.content.MCRURLContent;
37  import org.mycore.common.xml.MCRXMLParserFactory;
38  import org.xml.sax.SAXParseException;
39  
40  import com.google.gson.JsonObject;
41  
42  /**
43   * This class is a abstract basic class for objects in the MyCoRe Project. It is
44   * the frame to produce a full functionality object.
45   * 
46   * @author Jens Kupferschmidt
47   * @version $Revision$ $Date$
48   */
49  public abstract class MCRBase {
50  
51      protected static final String MCR_ENCODING;
52  
53      // the DOM document
54      protected Document jdomDocument = null;
55  
56      // the object content
57      protected MCRObjectID mcrId = null;
58  
59      protected String mcrVersion = null;
60  
61      protected String mcrSchema = null;
62  
63      protected final MCRObjectService mcrService;
64  
65      // other
66      protected static final String NL;
67  
68      protected static final String SLASH;
69  
70      protected boolean importMode = false;
71  
72      // logger
73      private static final Logger LOGGER = LogManager.getLogger();
74  
75      static {
76          NL = System.getProperty("line.separator");
77          SLASH = System.getProperty("file.separator");
78          // Default Encoding
79          MCR_ENCODING = MCRConfiguration2.getString("MCR.Metadata.DefaultEncoding").orElse(DEFAULT_ENCODING);
80          if (LOGGER.isDebugEnabled()) {
81              LOGGER.debug("Encoding = {}", MCR_ENCODING);
82          }
83      }
84  
85      /**
86       * This is the constructor of the MCRBase class. It make an instance of the
87       * parser class and the metadata class. <br>
88       * 
89       * @exception MCRException
90       *                general Exception of MyCoRe
91       */
92      public MCRBase() throws MCRException {
93          mcrVersion = MCRCoreVersion.getVersion();
94          mcrSchema = "";
95  
96          // Service class
97          mcrService = new MCRObjectService();
98      }
99  
100     protected void setFromJDOM(Document doc) {
101         jdomDocument = doc;
102         setUp();
103     }
104 
105     protected void setUp() {
106         if (jdomDocument == null) {
107             throw new MCRException("The JDOM document is null or empty.");
108         }
109 
110         Element rootElement = jdomDocument.getRootElement();
111         setId(MCRObjectID.getInstance(rootElement.getAttributeValue("ID")));
112         setVersion(rootElement.getAttributeValue("version"));
113         setSchema(rootElement.getAttribute("noNamespaceSchemaLocation", XSI_NAMESPACE).getValue());
114 
115         // get the service data of the object
116         Element serviceElement = rootElement.getChild("service");
117         if (serviceElement != null) {
118             mcrService.setFromDOM(serviceElement);
119         }
120     }
121 
122     /**
123      * This methode return the object id. If this is not set, null was returned.
124      * 
125      * @return the id as MCRObjectID
126      */
127     public final MCRObjectID getId() {
128         return mcrId;
129     }
130 
131     /**
132      * This methode return the MyCoRe version of the data structure.
133      * 
134      * @return the version as a string
135      */
136     public final String getVersion() {
137         return mcrVersion;
138     }
139 
140     /**
141      * Method returns the object schema. If the schema is not set <code>null</code> will be returned.
142      * 
143      * @return the schema as a string
144      */
145     public final String getSchema() {
146         return mcrSchema;
147     }
148 
149     /**
150      * This methode return the instance of the MCRObjectService class. If this
151      * was not found, null was returned.
152      * 
153      * @return the instance of the MCRObjectService class
154      */
155     public final MCRObjectService getService() {
156         return mcrService;
157     }
158 
159     /**
160      * This method read the XML input stream from an URI to build up the
161      * MyCoRe-Object.
162      * 
163      * @param uri
164      *            an URI
165      * @exception MCRException
166      *                general Exception of MyCoRe
167      */
168     protected final void setFromURI(URI uri) throws MCRException, SAXParseException, IOException {
169         Document jdom = MCRXMLParserFactory.getParser().parseXML(new MCRURLContent(uri.toURL()));
170         setFromJDOM(jdom);
171     }
172 
173     /**
174      * This method read the XML input stream from a byte array to build up the
175      * MyCoRe-Object.
176      * 
177      * @param xml
178      *            a XML string
179      * @exception MCRException
180      *                general Exception of MyCoRe
181      */
182     protected final void setFromXML(byte[] xml, boolean valid) throws MCRException, SAXParseException {
183         Document jdom = MCRXMLParserFactory.getParser(valid).parseXML(new MCRByteContent(xml));
184         setFromJDOM(jdom);
185     }
186 
187     /**
188      * This method set the object ID.
189      * 
190      * @param id
191      *            the object ID
192      */
193     public void setId(MCRObjectID id) {
194         mcrId = id;
195     }
196 
197     /**
198      * This methods set the MyCoRe version to the string 'Version 1.3'.
199      */
200     public final void setVersion(String version) {
201         mcrVersion = version != null ? version : MCRCoreVersion.getVersion();
202     }
203 
204     /**
205      * This methode set the object schema.
206      * 
207      * @param schema
208      *            the object schema
209      */
210     public final void setSchema(String schema) {
211         if (schema == null) {
212             mcrSchema = "";
213 
214             return;
215         }
216 
217         mcrSchema = schema.trim();
218     }
219 
220     /**
221      * This method create a XML stream for all object data.
222      * 
223      * @exception MCRException
224      *                if the content of this class is not valid
225      * @return a JDOM Document with the XML data of the object as byte array
226      */
227     public Document createXML() throws MCRException {
228         validate();
229         Element elm = new Element(getRootTagName());
230         Document doc = new Document(elm);
231         elm.addNamespaceDeclaration(XSI_NAMESPACE);
232         elm.addNamespaceDeclaration(XLINK_NAMESPACE);
233         elm.setAttribute("noNamespaceSchemaLocation", mcrSchema, XSI_NAMESPACE);
234         elm.setAttribute("ID", mcrId.toString());
235         elm.setAttribute("version", mcrVersion);
236         return doc;
237     }
238 
239     /**
240      * Creates the JSON representation of this object.
241      * 
242      * <pre>
243      *   {
244      *     id: "mycore_project_00000001",
245      *     version: "3.0"
246      *   }
247      * </pre>
248      * 
249      */
250     public JsonObject createJSON() {
251         JsonObject object = new JsonObject();
252         object.addProperty("id", mcrId.toString());
253         object.addProperty("version", mcrVersion);
254         return object;
255     }
256 
257     protected abstract String getRootTagName();
258 
259     /**
260      * This method check the validation of the content of this class. The method
261      * returns <em>true</em> if
262      * <ul>
263      * <li>the mcr_id value is valid
264      * </ul>
265      * otherwise the method return <em>false</em>
266      * 
267      * @return a boolean value
268      */
269     public boolean isValid() {
270         try {
271             validate();
272             return true;
273         } catch (MCRException exc) {
274             LOGGER.warn("The content of this object '{}' is invalid.", mcrId, exc);
275         }
276         return false;
277     }
278 
279     /**
280      * Validates the content of this class. This method throws an exception if:
281      *  <ul>
282      *  <li>the mcr_id is null</li>
283      *  <li>the XML schema is null or empty</li>
284      *  <li>the service part is null or invalid</li>
285      *  </ul>
286      * 
287      * @throws MCRException the content is invalid
288      */
289     public void validate() throws MCRException {
290         if (mcrId == null) {
291             throw new MCRException("MCRObjectID is undefined.");
292         }
293         if (getSchema() == null || getSchema().length() == 0) {
294             throw new MCRException("XML Schema of '" + mcrId + "' is undefined.");
295         }
296         MCRObjectService service = getService();
297         if (service == null) {
298             throw new MCRException("The <service> part of '" + mcrId + "' is undefined.");
299         }
300         try {
301             service.validate();
302         } catch (MCRException exc) {
303             throw new MCRException("The <service> part of '" + mcrId + "' is invalid.", exc);
304         }
305     }
306 
307     public boolean isImportMode() {
308         return importMode;
309     }
310 
311     public void setImportMode(boolean importMode) {
312         this.importMode = importMode;
313     }
314 
315     @Override
316     public String toString() {
317         return this.mcrId.toString();
318     }
319 }