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.datamodel.ifs;
025
026 import java.util.Hashtable;
027
028 import org.apache.log4j.Logger;
029 import org.mycore.common.MCRArgumentChecker;
030 import org.mycore.common.MCRConfiguration;
031 import org.mycore.common.MCRConfigurationException;
032 import org.mycore.common.MCRException;
033
034 /**
035 * This class manages instances of MCRContentStore and MCRAudioVideoExtender and
036 * provides methods to get these for a given Store ID or MCRFile instance. The
037 * class is responsible for looking up, loading, instantiating and remembering
038 * the implementations of MCRContentStore and MCRAudioVideoExtender that are
039 * used in the system.
040 *
041 * @author Frank Lützenkirchen
042 * @author Thomas Scheffler (yagee)
043 * @version $Revision: 13085 $ $Date: 2008-02-06 18:27:24 +0100 (Mi, 06 Feb 2008) $
044 */
045 public class MCRContentStoreFactory {
046 /** Hashtable StoreID to MCRContentStore instance */
047 protected static Hashtable STORES;
048
049 /** Hashtable StoreID to Class that implements MCRAudioVideoExtender */
050 protected static Hashtable EXTENDER_CLASSES;
051
052 /**
053 * Hashtable StoreID to MCRContentStore implementing
054 * {@link org.mycore.services.query.MCRTextSearchInterface}
055 */
056 protected static Hashtable INDEX_STORES;
057
058 /** The MCRContentStoreSelector implementation that will be used */
059 protected static MCRContentStoreSelector STORE_SELECTOR;
060
061 private static final Logger LOGGER = Logger.getLogger(MCRContentStoreFactory.class);
062
063 /**
064 * Returns the MCRContentStore instance that is configured for this StoreID.
065 * The instance that is returned is configured by the property
066 * <tt>MCR.IFS.ContentStore.<StoreID>.Class</tt> in mycore.properties.
067 *
068 * @param storeID
069 * the non-null ID of the MCRContentStore implementation
070 * @return the MCRContentStore instance that uses this storeID
071 * @throws MCRConfigurationException
072 * if no MCRContentStore implementation is configured for this
073 * storeID
074 */
075 public static MCRContentStore getStore(String storeID) {
076 if (STORES == null) {
077 STORES = new Hashtable();
078 }
079
080 if (INDEX_STORES == null) {
081 INDEX_STORES = new Hashtable();
082 }
083
084 MCRArgumentChecker.ensureNotEmpty(storeID, "Store ID");
085
086 if (!STORES.containsKey(storeID)) {
087 try {
088 String storeClass = "MCR.IFS.ContentStore." + storeID + ".Class";
089 LOGGER.debug("getting StoreClass: " + storeClass);
090
091 Object obj = MCRConfiguration.instance().getInstanceOf(storeClass);
092 MCRContentStore s = (MCRContentStore) (obj);
093 s.init(storeID);
094 STORES.put(storeID, s);
095
096 } catch (Exception ex) {
097 String msg = "Could not load MCRContentStore with store ID = " + storeID;
098 throw new MCRConfigurationException(msg, ex);
099 }
100 }
101
102 return (MCRContentStore) (STORES.get(storeID));
103 }
104
105 /**
106 * Returns the MCRContentStore instance that should be used to store the
107 * content of the given file. The configured MCRContentStoreSelector is used
108 * to make this decision.
109 *
110 * @see MCRContentStoreSelector
111 * @see MCRContentStore
112 */
113 public static MCRContentStore selectStore(MCRFile file) {
114 if (STORE_SELECTOR == null) {
115 initStoreSelector();
116 }
117
118 String store = STORE_SELECTOR.selectStore(file);
119
120 return getStore(store);
121 }
122
123 private static void initStoreSelector() {
124 String property = "MCR.IFS.ContentStoreSelector.Class";
125 Object obj = MCRConfiguration.instance().getInstanceOf(property);
126 STORE_SELECTOR = (MCRContentStoreSelector) obj;
127 }
128
129 /**
130 * Returns the Class instance that implements the MCRAudioVideoExtender for
131 * the MCRContentStore with the given ID. That class is configured by the
132 * property <tt>MCR.IFS.AVExtender.<StoreID>.Class</tt> in
133 * mycore.properties.
134 *
135 * @param storeID
136 * the non-null StoreID of the MCRContentStore
137 * @return the Class that implements MCRAudioVideoExtender for the StoreID
138 * given, or null
139 * @throws MCRConfigurationException
140 * if the MCRAudioVideoExtender implementation class could not
141 * be loaded
142 */
143 protected static Class getExtenderClass(String storeID) {
144 if (EXTENDER_CLASSES == null) {
145 EXTENDER_CLASSES = new Hashtable();
146 }
147
148 MCRArgumentChecker.ensureNotNull(storeID, "store ID");
149
150 String storeClass = "MCR.IFS.AVExtender." + storeID + ".Class";
151
152 String value = MCRConfiguration.instance().getString(storeClass, "");
153
154 if (value.equals("")) {
155 return null;
156 }
157
158 if (!EXTENDER_CLASSES.containsKey(storeID)) {
159 try {
160 Class cl = Class.forName(value);
161 EXTENDER_CLASSES.put(storeID, cl);
162 } catch (Exception ex) {
163 String msg = "Could not load AudioVideoExtender class " + value;
164 throw new MCRConfigurationException(msg, ex);
165 }
166 }
167
168 return (Class) (EXTENDER_CLASSES.get(storeID));
169 }
170
171 /**
172 * Returns true if the MCRContentStore with the given StoreID provides an
173 * MCRAudioVideoExtender implementation, false otherwise. The
174 * MCRAudioVideoExtender for a certain MCRContentStore is configured by the
175 * property <tt>MCR.IFS.AVExtender.<StoreID>.Class</tt> in
176 * mycore.properties.
177 *
178 * @param storeID
179 * the non-null StoreID of the MCRContentStore
180 * @return the MCRAudioVideoExtender for the StoreID given, or null
181 * @throws MCRConfigurationException
182 * if the MCRAudioVideoExtender implementation class could not
183 * be loaded
184 */
185 static boolean providesAudioVideoExtender(String storeID) {
186 return (getExtenderClass(storeID) != null);
187 }
188
189 /**
190 * If the MCRContentStore of the MCRFile given provides an
191 * MCRAudioVideoExtender implementation, this method creates and initializes
192 * the MCRAudioVideoExtender instance for the MCRFile. The instance that is
193 * returned is configured by the property
194 * <tt>MCR.IFS.AVExtender.<StoreID>.Class</tt> in mycore.properties.
195 *
196 * @param file
197 * the non-null MCRFile that should get an MCRAudioVideoExtender
198 * @return the MCRAudioVideoExtender for the MCRFile given, or null
199 * @throws MCRConfigurationException
200 * if the MCRAudioVideoExtender implementation class could not
201 * be loaded
202 */
203 static MCRAudioVideoExtender buildExtender(MCRFileReader file) {
204 MCRArgumentChecker.ensureNotNull(file, "file");
205
206 if (!providesAudioVideoExtender(file.getStoreID())) {
207 return null;
208 }
209
210 Class cl = getExtenderClass(file.getStoreID());
211
212 try {
213 Object obj = cl.newInstance();
214 MCRAudioVideoExtender ext = (MCRAudioVideoExtender) obj;
215 ext.init(file);
216
217 return ext;
218 } catch (Exception exc) {
219 if (exc instanceof MCRException) {
220 throw (MCRException) exc;
221 }
222
223 String msg = "Could not build MCRAudioVideoExtender instance";
224 throw new MCRConfigurationException(msg, exc);
225 }
226 }
227 }