001 /*
002 *
003 * $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
004 *
005 * This file is part of *** M y C o R e ***
006 * See http://www.mycore.de/ for details.
007 *
008 * This program is free software; you can use it, redistribute it
009 * and / or modify it under the terms of the GNU General Public License
010 * (GPL) as published by the Free Software Foundation; either version 2
011 * of the License or (at your option) any later version.
012 *
013 * This program is distributed in the hope that it will be useful, but
014 * WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program, in a file called gpl.txt or license.txt.
020 * If not, write to the Free Software Foundation Inc.,
021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
022 */
023
024 package org.mycore.backend.jdom;
025
026 import java.util.Enumeration;
027 import java.util.Hashtable;
028 import java.util.List;
029
030 import org.apache.log4j.Logger;
031 import org.jdom.Document;
032
033 import org.mycore.common.MCRConfiguration;
034 import org.mycore.common.MCRPersistenceException;
035 import org.mycore.datamodel.metadata.MCRNormalizeText;
036 import org.mycore.datamodel.metadata.MCRObjectID;
037 import org.mycore.datamodel.common.MCRXMLTableManager;
038
039 /**
040 * This class implements the memory store based on JDOM documents.
041 *
042 * @author Jens Kupferschmidt
043 * @author Frank L�tzenkirchen
044 *
045 * @version $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
046 */
047 public class MCRJDOMMemoryStore {
048 /** The connection pool singleton */
049 private static MCRJDOMMemoryStore singleton;
050
051 /** The logger */
052 private static Logger logger = Logger.getLogger("org.mycore.backend.jdom");
053
054 /** A hashtable of the JDOM trees */
055 private Hashtable trees = new Hashtable();
056
057 /** Timestamp of the last SQL read and the default reload time in seconds */
058 private long tslast = 0;
059
060 private long tsdiff = 0;
061
062 private static final long tsdiffdefault = 3600; // 1
063
064 // hour
065
066 /**
067 * Returns the singleton.
068 */
069 public static synchronized MCRJDOMMemoryStore instance() {
070 if (singleton == null) {
071 singleton = new MCRJDOMMemoryStore();
072 }
073
074 return singleton;
075 }
076
077 /**
078 * Creates a new JDOM memory store
079 */
080 private MCRJDOMMemoryStore() {
081 // set the start time and the diff from the config
082 MCRConfiguration config = MCRConfiguration.instance();
083 tslast = System.currentTimeMillis();
084 tsdiff = (config.getLong("MCR.persistence_jdom_reload", tsdiffdefault)) * 1000;
085 }
086
087 /**
088 * Returns a list of all object metadata for a given object type
089 */
090 Hashtable getObjects(String type) {
091 // return the JDOM tree if it is in the store
092 if ((type == null) || ((type = type.trim()).length() == 0)) {
093 throw new MCRPersistenceException("The type is null or empty.");
094 }
095
096 // check the reload
097 Hashtable store = null;
098
099 if (System.currentTimeMillis() <= (tslast + tsdiff)) {
100 store = (Hashtable) trees.get(type);
101 }
102
103 if (store != null) {
104 return store;
105 }
106
107 tslast = System.currentTimeMillis();
108
109 // fill the store form the SQL store of the type
110 store = readObjectsFromPersistentStore(type);
111 trees.put(type, store);
112
113 return store;
114 }
115
116 /**
117 * Reads all objects metadata from the persistent store into memory
118 */
119 private Hashtable readObjectsFromPersistentStore(String type) {
120 long startdate = System.currentTimeMillis();
121 MCRXMLTableManager mcr_xml = MCRXMLTableManager.instance();
122 List<String> ar = mcr_xml.retrieveAllIDs(type);
123 Hashtable objects = new Hashtable();
124 int size = ar.size();
125
126 for (int i = 0; i < size; i++) {
127 String stid = (String) ar.get(i);
128 MCRObjectID mid = new MCRObjectID(stid);
129 Document jdom_document = (Document)( mcr_xml.readDocument(mid).clone() );
130 MCRNormalizeText.normalizeJDOM(jdom_document);
131 objects.put(mid, jdom_document.detachRootElement());
132 logger.debug("Load to JDOM tree " + stid);
133 }
134
135 long stopdate = System.currentTimeMillis();
136 double diff = (stopdate - startdate) / 1000.0;
137 logger.debug("Read " + Integer.toString(ar.size()) + " SQL data sets for type " + type + " in " + diff + " seconds");
138
139 return objects;
140 }
141
142 /**
143 * Adds an objects xml metadata to the memory store.
144 */
145 void addElement(MCRObjectID id, Document doc) {
146 Document jdom_document = (Document)doc.clone();
147 MCRNormalizeText.normalizeJDOM(jdom_document);
148 getObjects(id.getTypeId()).put(id, jdom_document.detachRootElement());
149 logger.debug("MRJDOMMemoryStore addElement " + id.getTypeId());
150 debug(id.getTypeId());
151 }
152
153 /**
154 * Removes an object from the memory store.
155 */
156 void removeElement(MCRObjectID id) {
157 getObjects(id.getTypeId()).remove(id);
158 logger.debug("MRJDOMMemoryStore removeElement " + id.getTypeId());
159 debug(id.getTypeId());
160 }
161
162 /**
163 * Debug the content of the Hashtable.
164 */
165 void debug(String type) {
166 Hashtable h = getObjects(type);
167
168 for (Enumeration e = h.keys(); e.hasMoreElements();) {
169 logger.info(e.nextElement().toString());
170 }
171 }
172 }