1.1 restoration
[mir.git] / source / mir / storage / store / ObjectStore.java
1 /*
2  * Copyright (C) 2001, 2002 The Mir-coders group
3  *
4  * This file is part of Mir.
5  *
6  * Mir is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Mir is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Mir; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  * In addition, as a special exception, The Mir-coders gives permission to link
21  * the code of this program with  any library licensed under the Apache Software License,
22  * The Sun (tm) Java Advanced Imaging library (JAI), The Sun JIMI library
23  * (or with modified versions of the above that use the same license as the above),
24  * and distribute linked combinations including the two.  You must obey the
25  * GNU General Public License in all respects for all of the code used other than
26  * the above mentioned libraries.  If you modify this file, you may extend this
27  * exception to your version of the file, but you are not obligated to do so.
28  * If you do not wish to do so, delete this exception statement from your version.
29  */
30 package mir.storage.store;
31
32 /**
33  * Title:         ObjectStore for StorableObjects
34  * Description:   ObjectStore holds a Map of @see StoreContainer for all possible
35  *                @see StoreIdentifier.
36  *
37  *                @see StorageIdentifier - identitfies one object in the ObjectStore
38  *                      i.e. in its apropriate bucket. It holds a unique identifier
39  *                      of a StorableObject and a reference on the StorableObject.
40  *
41  *                @see StoreContainer - "Buckets" to store different types of Objects
42  *                      in one Container. These buckets are cofigurable via
43  *                      config.properties.
44  *
45  *                @see StoreContainerType - is a signature for all StoreContainer
46  *                      and StoreIdentifier.
47  *
48  *                @see StorableObjects - Interface Object have to implement to
49  *                      be handled by the ObjectStore
50  *
51  *                @see ServletStoreInfo - Maintenance Servlet for ObjectStore.
52  *                      Displays information about current content of the
53  *                      ObjectStore.
54  *
55  *
56  * Copyright:     Copyright (c) 2002
57  * Company:       indy
58  * @author        rk
59  * @version 1.0
60  */
61
62 import java.util.HashMap;
63 import java.util.Iterator;
64 import java.util.Map;
65 import java.util.MissingResourceException;
66 import javax.servlet.http.HttpServletRequest;
67
68 import mir.config.MirPropertiesConfiguration;
69 import mir.log.LoggerWrapper;
70
71 public class ObjectStore {
72
73   private final static ObjectStore INSTANCE = new ObjectStore();
74   private final static Map containerMap = new HashMap(); // StoreContainerType/StoreContainer
75   private static long storeHit = 0, storeMiss = 0;
76   private MirPropertiesConfiguration configuration;
77   private LoggerWrapper logger;
78
79   private ObjectStore() {
80     logger = new LoggerWrapper("Database.ObjectStore");
81     configuration = MirPropertiesConfiguration.instance();
82   }
83
84   public static ObjectStore getInstance() {
85     return INSTANCE;
86   }
87
88   /**
89    *  Method:       use
90    *  Description:  The ObjectStore tries to find the @see StoreIdentifier sid
91    *                and returns the stored Object.
92    *
93    *  @return       StorableObject is null when no StorableObject for the
94    *                StoreIdentifier sid is found.
95    */
96   public StorableObject use(StoreIdentifier sid) {
97     if (sid != null) {
98       StorableObject storeObject = null;
99       StoreContainer stoc = getStoreContainerForSid(sid);
100       if (stoc != null)
101         storeObject = stoc.use(sid);
102       else
103         logger.warn("container not found for: " + sid.toString());
104       if (storeObject != null) {
105         storeHit++;
106         return storeObject;
107       }
108     }
109     storeMiss++;
110     return null;
111
112   }
113
114   /**
115    *  Method:       add
116    *  Description:  A StoreIdentifier is added to the ObjectStore, if it
117    *                contains a reference to a @see StorableObject.
118    */
119   public void add(StoreIdentifier sid) {
120     if (sid != null && sid.hasReference()) {
121       // find the right StoreContainer for sid
122       StoreContainer stoc = getStoreContainerForSid(sid);
123       if (stoc == null) {
124         // we have to make new StoreContainer
125         StoreContainerType stocType = sid.getStoreContainerType();
126         stoc = new StoreContainer(stocType);
127         containerMap.put(stocType, stoc);
128       }
129       stoc.add(sid);
130     }
131   }
132
133   /**
134    *  Method:       invalidate(StorableObject sto)
135    *  Description:  ObjectStore is notified of change of a @see StorableObject
136    *                sto and invalidates all relevant cache entries.
137    */
138
139   public void invalidate(StoreIdentifier sid) {
140     // propagate invalidation to StoreContainer
141     if (sid != null) {
142       StoreContainer stoc = getStoreContainerForSid(sid);
143       stoc.invalidate(sid);
144     }
145   }
146
147   /**
148    * serves to invalidate a whole StoreContainer
149    */
150   public void invalidate(StoreContainerType stoc_type) {
151     if (stoc_type != null) {
152       /*  @todo invalidates too much:
153        *  improvement: if instanceof StoreContainerEntity && EntityList
154        *  then invalidate only StoreIdentifier matching the right table
155        */
156       StoreContainer stoc = getStoreContainerForStocType(stoc_type);
157       if (stoc != null)
158         stoc.invalidate();
159     }
160
161   }
162
163   // internal methods for StoreContainer managment
164
165   /**
166    *  Method:       getStoreContainerForSid
167    *  Description:  private method to find the right @see StoreContainer for
168    *                the @see StoreIdentifier sid.
169    *
170    *  @return       StoreContainer is null when no Container is found.
171    */
172   private StoreContainer getStoreContainerForSid(StoreIdentifier sid) {
173     // find apropriate container for a specific sid
174     if (sid != null) {
175       StoreContainerType stoc_type = sid.getStoreContainerType();
176       return getStoreContainerForStocType(stoc_type);
177     }
178     return null;
179   }
180
181   private StoreContainer getStoreContainerForStocType(StoreContainerType
182       stoc_type) {
183     if (stoc_type != null && containerMap.containsKey(stoc_type))
184       return (StoreContainer) containerMap.get(stoc_type);
185     return null;
186   }
187
188   private boolean has(StoreIdentifier sid) {
189     StoreContainer stoc = getStoreContainerForSid(sid);
190     return (stoc != null && stoc.has(sid)) ? true : false;
191   }
192
193   public String getConfProperty(String name) {
194     if (name != null) {
195       try {
196         return configuration.getString(name);
197       }
198       catch (MissingResourceException e) {
199         logger.error("getConfProperty: " + e.toString());
200       }
201     }
202     return null;
203   }
204
205   /**
206    *  Method:       toString()
207    *  Description:  Displays statistical information about the ObjectStore.
208        *                Further information is gathered from all @see StoreContainer
209    *
210    *  @return       String
211    */
212   public String toString() {
213     return toHtml(null);
214   }
215
216   public String toHtml(HttpServletRequest req) {
217     float hitRatio = 0;
218     long divisor = storeHit + storeMiss;
219     if (divisor > 0)
220       hitRatio = (float) storeHit / (float) divisor;
221     hitRatio *= 100;
222
223     StringBuffer sb = new StringBuffer("Mir-ObjectStore ");
224     sb.append( ( (req != null) ? html_version() : version())).append("\n");
225     sb.append("ObjectStore overall hits/misses/ratio: ").append(storeHit);
226     sb.append("/").append(storeMiss).append("/").append(hitRatio);
227     sb.append("%\nCurrently ").append(containerMap.size());
228     sb.append(" StoreContainer in use - listing information:\n");
229
230     // ask container for information
231     StoreContainer currentStoc;
232     for (Iterator it = containerMap.keySet().iterator(); it.hasNext(); ) {
233       currentStoc = (StoreContainer) containerMap.get(it.next());
234       sb.append(currentStoc.toHtml(req));
235     }
236
237     return sb.toString();
238   }
239
240   /**
241    *  Method:       html_version()
242        *  Description:  returns ObjectStore version as String for HTML representation
243    *
244    *  @return       String
245    */
246   private String html_version() {
247     return "<i>" + version() + "</i>";
248   }
249
250   /**
251    *  Method:       version()
252    *  Description:  returns ObjectStore version as String
253    *
254    *  @return       String
255    */
256   private String version() {
257     return "v_sstart3__1.0";
258   }
259
260 }