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.ifs2;
20  
21  import java.io.IOException;
22  import java.nio.file.Files;
23  import java.nio.file.Path;
24  import java.util.Optional;
25  
26  import org.apache.logging.log4j.LogManager;
27  import org.apache.logging.log4j.Logger;
28  import org.jdom2.JDOMException;
29  import org.mycore.common.MCRException;
30  import org.mycore.common.config.MCRConfiguration2;
31  import org.mycore.common.content.MCRContent;
32  
33  /**
34   * Stores XML metadata documents (or optionally any other BLOB data) in a
35   * persistent filesystem structure
36   * 
37   * For each object type, a store must be defined as follows:
38   * 
39   * MCR.IFS2.Store.DocPortal_document.Class=org.mycore.datamodel.ifs2.MCRMetadataStore 
40   * MCR.IFS2.Store.DocPortal_document.BaseDir=/foo/bar
41   * MCR.IFS2.Store.DocPortal_document.SlotLayout=4-2-2 
42   * MCR.IFS2.Store.DocPortal_document.ForceXML=true (which is default)
43   * 
44   * @author Frank Lützenkirchen
45   */
46  public class MCRMetadataStore extends MCRStore {
47  
48      public static final Logger LOGGER = LogManager.getLogger();
49  
50      /**
51       * If true (which is default), store will enforce it gets
52       * XML to store, otherwise any binary content can be stored here.
53       * 
54       * Override with MCR.IFS2.Store.&lt;ObjectType&gt;.ForceXML=true|false
55       */
56      protected boolean forceXML = true;
57  
58      protected String forceDocType;
59  
60      /**
61       * Initializes a new metadata store instance.
62       * 
63       * @param type
64       *            the document type that is stored in this store
65       */
66      @Override
67      protected void init(String type) {
68          super.init(type);
69          prefix = MCRConfiguration2.getString("MCR.IFS2.Store." + type + ".Prefix").orElse(type + "_");
70          suffix = ".xml";
71          forceXML = MCRConfiguration2.getBoolean("MCR.IFS2.Store." + type + ".ForceXML").orElse(true);
72          if (forceXML) {
73              forceDocType = MCRConfiguration2.getString("MCR.IFS2.Store." + type + ".ForceDocType").orElse(null);
74              LOGGER.debug("Set doctype for {} to {}", type, forceDocType);
75          }
76      }
77  
78      /**
79       * Initializes a new metadata store instance.
80       * 
81       * @param config
82       *            the configuration for the store
83       */
84      @Override
85      protected void init(MCRStoreConfig config) {
86          super.init(config);
87          prefix = Optional.ofNullable(config.getPrefix()).orElseGet(() -> config.getID() + "_");
88          suffix = ".xml";
89          forceXML = MCRConfiguration2.getBoolean("MCR.IFS2.Store." + config.getID() + ".ForceXML").orElse(true);
90          if (forceXML) {
91              forceDocType = MCRConfiguration2.getString("MCR.IFS2.Store." + config.getID() + ".ForceDocType")
92                  .orElse(null);
93              LOGGER.debug("Set doctype for {} to {}", config.getID(), forceDocType);
94          }
95      }
96  
97      protected boolean shouldForceXML() {
98          return forceXML;
99      }
100 
101     /**
102      * Stores a newly created document, using the next free ID.
103      * 
104      * @param xml
105      *            the XML document to be stored
106      * @return the stored metadata object
107      */
108     public MCRStoredMetadata create(MCRContent xml) throws IOException, JDOMException {
109         int id = getNextFreeID();
110         return create(xml, id);
111     }
112 
113     /**
114      * Stores a newly created document under the given ID.
115      * 
116      * @param xml
117      *            the XML document to be stored
118      * @param id
119      *            the ID under which the document should be stored
120      * @return the stored metadata object
121      */
122     public MCRStoredMetadata create(MCRContent xml, int id) throws IOException, JDOMException {
123         if (id <= 0) {
124             throw new MCRException("ID of metadata object must be a positive integer");
125         }
126         Path path = getSlot(id);
127         if (Files.exists(path)) {
128             String msg = "Metadata object with ID " + id + " already exists in store";
129             throw new MCRException(msg);
130         }
131         if (!Files.exists(path.getParent())) {
132             Files.createDirectories(path.getParent());
133         }
134         MCRStoredMetadata meta = buildMetadataObject(path, id);
135         meta.create(xml);
136         return meta;
137     }
138 
139     /**
140      * Returns the metadata stored under the given ID, or null
141      * 
142      * @param id
143      *            the ID of the XML document
144      * @return the metadata stored under that ID, or null when there is no such
145      *         metadata object
146      */
147     public MCRStoredMetadata retrieve(int id) throws IOException {
148         Path path = getSlot(id);
149         if (!Files.exists(path)) {
150             return null;
151         } else {
152             return buildMetadataObject(path, id);
153         }
154     }
155 
156     /**
157      * Builds a new stored metadata object in this store
158      * 
159      * @param fo
160      *            the FileObject that stores the data
161      * @param id
162      *            the ID of the metadata object
163      */
164     protected MCRStoredMetadata buildMetadataObject(Path fo, int id) {
165         return new MCRStoredMetadata(this, fo, id, forceDocType);
166     }
167 }