2 * Copyright (C) 2001, 2002 The Mir-coders group
\r
4 * This file is part of Mir.
\r
6 * Mir is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 2 of the License, or
\r
9 * (at your option) any later version.
\r
11 * Mir is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with Mir; if not, write to the Free Software
\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
20 * In addition, as a special exception, The Mir-coders gives permission to link
\r
21 * the code of this program with the com.oreilly.servlet library, any library
\r
22 * licensed under the Apache Software License, The Sun (tm) Java Advanced
\r
23 * Imaging library (JAI), The Sun JIMI library (or with modified versions of
\r
24 * the above that use the same license as the above), and distribute linked
\r
25 * combinations including the two. You must obey the GNU General Public
\r
26 * License in all respects for all of the code used other than the above
\r
27 * mentioned libraries. If you modify this file, you may extend this exception
\r
28 * to your version of the file, but you are not obligated to do so. If you do
\r
29 * not wish to do so, delete this exception statement from your version.
\r
32 package mir.storage.store;
\r
35 * Title: ObjectStore for StorableObjects
\r
36 * Description: ObjectStore holds a Map of @see StoreContainer for all possible
\r
37 * @see StoreIdentifier.
\r
39 * @see StorageIdentifier - identitfies one object in the ObjectStore
\r
40 * i.e. in its apropriate bucket. It holds a unique identifier
\r
41 * of a StorableObject and a reference on the StorableObject.
\r
43 * @see StoreContainer - "Buckets" to store different types of Objects
\r
44 * in one Container. These buckets are cofigurable via
\r
45 * config.properties.
\r
47 * @see StoreContainerType - is a signature for all StoreContainer
\r
48 * and StoreIdentifier.
\r
50 * @see StorableObjects - Interface Object have to implement to
\r
51 * be handled by the ObjectStore
\r
53 * @see ServletStoreInfo - Maintenance Servlet for ObjectStore.
\r
54 * Displays information about current content of the
\r
58 * Copyright: Copyright (c) 2002
\r
64 import java.io.BufferedInputStream;
\r
65 import java.io.FileInputStream;
\r
66 import java.util.HashMap;
\r
67 import java.util.Iterator;
\r
68 import java.util.Map;
\r
69 import java.util.MissingResourceException;
\r
70 import java.util.Properties;
\r
72 import javax.servlet.http.HttpServletRequest;
\r
74 import mir.config.MirPropertiesConfiguration;
\r
75 import mir.log.LoggerWrapper;
\r
77 public class ObjectStore {
\r
79 private final static ObjectStore INSTANCE = new ObjectStore();
\r
80 private final static Map containerMap = new HashMap(); // StoreContainerType/StoreContainer
\r
81 private static long storeHit = 0, storeMiss = 0;
\r
82 private Properties ostoreConf;
\r
83 private LoggerWrapper logger;
\r
85 private ObjectStore() {
\r
86 String confName = null;
\r
88 logger = new LoggerWrapper("Database.ObjectStore");
\r
89 Properties conf = new Properties();
\r
93 MirPropertiesConfiguration.instance().getString("Home") +
\r
94 "etc/objectstore.properties";
\r
95 conf.load(new BufferedInputStream(new FileInputStream(confName)));
\r
97 catch (java.io.FileNotFoundException fnfe) {
\r
98 logger.error("could not read config file. not found: " + confName);
\r
100 catch (Throwable t) {
\r
101 logger.error("could not get config: " + t.getMessage());
\r
106 public static ObjectStore getInstance() {
\r
112 * Description: The ObjectStore tries to find the @see StoreIdentifier sid
\r
113 * and returns the stored Object.
\r
115 * @return StorableObject is null when no StorableObject for the
\r
116 * StoreIdentifier sid is found.
\r
118 public StorableObject use(StoreIdentifier sid) {
\r
120 StorableObject storeObject = null;
\r
121 StoreContainer stoc = getStoreContainerForSid(sid);
\r
123 storeObject = stoc.use(sid);
\r
125 logger.warn("container not found for: " + sid.toString());
\r
126 if (storeObject != null) {
\r
128 return storeObject;
\r
138 * Description: A StoreIdentifier is added to the ObjectStore, if it
\r
139 * contains a reference to a @see StorableObject.
\r
141 public void add(StoreIdentifier sid) {
\r
142 if (sid != null && sid.hasReference()) {
\r
143 // find the right StoreContainer for sid
\r
144 StoreContainer stoc = getStoreContainerForSid(sid);
\r
145 if (stoc == null) {
\r
146 // we have to make new StoreContainer
\r
147 StoreContainerType stocType = sid.getStoreContainerType();
\r
148 stoc = new StoreContainer(stocType);
\r
149 containerMap.put(stocType, stoc);
\r
156 * Method: invalidate(StorableObject sto)
\r
157 * Description: ObjectStore is notified of change of a @see StorableObject
\r
158 * sto and invalidates all relevant cache entries.
\r
161 public void invalidate(StoreIdentifier sid) {
\r
162 // propagate invalidation to StoreContainer
\r
164 StoreContainer stoc = getStoreContainerForSid(sid);
\r
165 stoc.invalidate(sid);
\r
170 * Method: invalidate(StoreContainerType)
\r
171 * Description: serves to invalidate a whole StoreContainer
\r
175 public void invalidate(StoreContainerType stoc_type) {
\r
176 if (stoc_type != null) {
\r
177 /** @todo invalidates too much:
\r
178 * improvement: if instanceof StoreContainerEntity && EntityList
\r
179 * then invalidate only StoreIdentifier matching the right table
\r
181 StoreContainer stoc = getStoreContainerForStocType(stoc_type);
\r
188 // internal methods for StoreContainer managment
\r
191 * Method: getStoreContainerForSid
\r
192 * Description: private method to find the right @see StoreContainer for
\r
193 * the @see StoreIdentifier sid.
\r
195 * @return StoreContainer is null when no Container is found.
\r
197 private StoreContainer getStoreContainerForSid(StoreIdentifier sid) {
\r
198 // find apropriate container for a specific sid
\r
200 StoreContainerType stoc_type = sid.getStoreContainerType();
\r
201 return getStoreContainerForStocType(stoc_type);
\r
206 private StoreContainer getStoreContainerForStocType(StoreContainerType
\r
208 if (stoc_type != null && containerMap.containsKey(stoc_type))
\r
209 return (StoreContainer) containerMap.get(stoc_type);
\r
213 private boolean has(StoreIdentifier sid) {
\r
214 StoreContainer stoc = getStoreContainerForSid(sid);
\r
215 return (stoc != null && stoc.has(sid)) ? true : false;
\r
218 public String getConfProperty(String name) {
\r
219 if (name != null) {
\r
220 String returnValue = "";
\r
222 return ostoreConf.getProperty(name);
\r
224 catch (MissingResourceException e) {
\r
225 logger.error("getConfProperty: " + e.toString());
\r
232 * Method: toString()
\r
233 * Description: Displays statistical information about the ObjectStore.
\r
234 * Further information is gathered from all @see StoreContainer
\r
238 public String toString() {
\r
239 return toHtml(null);
\r
242 public String toHtml(HttpServletRequest req) {
\r
243 float hitRatio = 0;
\r
244 long divisor = storeHit + storeMiss;
\r
246 hitRatio = (float) storeHit / (float) divisor;
\r
249 StringBuffer sb = new StringBuffer("Mir-ObjectStore ");
\r
250 sb.append( ( (req != null) ? html_version() : version())).append("\n");
\r
251 sb.append("ObjectStore overall hits/misses/ratio: ").append(storeHit);
\r
252 sb.append("/").append(storeMiss).append("/").append(hitRatio);
\r
253 sb.append("%\nCurrently ").append(containerMap.size());
\r
254 sb.append(" StoreContainer in use - listing information:\n");
\r
256 // ask container for information
\r
257 StoreContainer currentStoc;
\r
258 for (Iterator it = containerMap.keySet().iterator(); it.hasNext(); ) {
\r
259 currentStoc = (StoreContainer) containerMap.get(it.next());
\r
260 sb.append(currentStoc.toHtml(req));
\r
263 return sb.toString();
\r
267 * Method: html_version()
\r
268 * Description: returns ObjectStore version as String for HTML representation
\r
272 private String html_version() {
\r
273 return "<i>" + version() + "</i>";
\r
277 * Method: version()
\r
278 * Description: returns ObjectStore version as String
\r
282 private String version() {
\r
283 return "v_sstart3__1.0";
\r