Bundletool dev
[mir.git] / source / mir / storage / store / ObjectStore.java
1 /*\r
2  * Copyright (C) 2001, 2002  The Mir-coders group\r
3  *\r
4  * This file is part of Mir.\r
5  *\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
10  *\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
15  *\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
19  *\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
30  */\r
31 \r
32 package mir.storage.store;\r
33 \r
34 /**\r
35  * Title:         ObjectStore for StorableObjects\r
36  * Description:   ObjectStore holds a Map of @see StoreContainer for all possible\r
37  *                @see StoreIdentifier.\r
38  *\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
42  *\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
46  *\r
47  *                @see StoreContainerType - is a signature for all StoreContainer\r
48  *                      and StoreIdentifier.\r
49  *\r
50  *                @see StorableObjects - Interface Object have to implement to\r
51  *                      be handled by the ObjectStore\r
52  *\r
53  *                @see ServletStoreInfo - Maintenance Servlet for ObjectStore.\r
54  *                      Displays information about current content of the\r
55  *                      ObjectStore.\r
56  *\r
57  *\r
58  * Copyright:     Copyright (c) 2002\r
59  * Company:       indy\r
60  * @author        rk\r
61  * @version 1.0\r
62  */\r
63 \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
71 \r
72 import javax.servlet.http.HttpServletRequest;\r
73 \r
74 import mir.config.MirPropertiesConfiguration;\r
75 import mir.log.LoggerWrapper;\r
76 \r
77 public class ObjectStore {\r
78 \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
84 \r
85   private ObjectStore() {\r
86     String confName = null;\r
87 \r
88     logger = new LoggerWrapper("Database.ObjectStore");\r
89     Properties conf = new Properties();\r
90 \r
91     try {\r
92       confName =\r
93           MirPropertiesConfiguration.instance().getString("Home") +\r
94           "etc/objectstore.properties";\r
95       conf.load(new BufferedInputStream(new FileInputStream(confName)));\r
96     }\r
97     catch (java.io.FileNotFoundException fnfe) {\r
98       logger.error("could not read config file. not found: " + confName);\r
99     }\r
100     catch (Throwable t) {\r
101       logger.error("could not get config: " + t.getMessage());\r
102     }\r
103     ostoreConf = conf;\r
104   }\r
105 \r
106   public static ObjectStore getInstance() {\r
107     return INSTANCE;\r
108   }\r
109 \r
110   /**\r
111    *  Method:       use\r
112    *  Description:  The ObjectStore tries to find the @see StoreIdentifier sid\r
113    *                and returns the stored Object.\r
114    *\r
115    *  @return       StorableObject is null when no StorableObject for the\r
116    *                StoreIdentifier sid is found.\r
117    */\r
118   public StorableObject use(StoreIdentifier sid) {\r
119     if (sid != null) {\r
120       StorableObject storeObject = null;\r
121       StoreContainer stoc = getStoreContainerForSid(sid);\r
122       if (stoc != null)\r
123         storeObject = stoc.use(sid);\r
124       else\r
125         logger.warn("container not found for: " + sid.toString());\r
126       if (storeObject != null) {\r
127         storeHit++;\r
128         return storeObject;\r
129       }\r
130     }\r
131     storeMiss++;\r
132     return null;\r
133 \r
134   }\r
135 \r
136   /**\r
137    *  Method:       add\r
138    *  Description:  A StoreIdentifier is added to the ObjectStore, if it\r
139    *                contains a reference to a @see StorableObject.\r
140    */\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
150       }\r
151       stoc.add(sid);\r
152     }\r
153   }\r
154 \r
155   /**\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
159    */\r
160 \r
161   public void invalidate(StoreIdentifier sid) {\r
162     // propagate invalidation to StoreContainer\r
163     if (sid != null) {\r
164       StoreContainer stoc = getStoreContainerForSid(sid);\r
165       stoc.invalidate(sid);\r
166     }\r
167   }\r
168 \r
169   /**\r
170    *  Method:       invalidate(StoreContainerType)\r
171    *  Description:  serves to invalidate a whole StoreContainer\r
172    *\r
173    *  @return\r
174    */\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
180        */\r
181       StoreContainer stoc = getStoreContainerForStocType(stoc_type);\r
182       if (stoc != null)\r
183         stoc.invalidate();\r
184     }\r
185 \r
186   }\r
187 \r
188   // internal methods for StoreContainer managment\r
189 \r
190   /**\r
191    *  Method:       getStoreContainerForSid\r
192    *  Description:  private method to find the right @see StoreContainer for\r
193    *                the @see StoreIdentifier sid.\r
194    *\r
195    *  @return       StoreContainer is null when no Container is found.\r
196    */\r
197   private StoreContainer getStoreContainerForSid(StoreIdentifier sid) {\r
198     // find apropriate container for a specific sid\r
199     if (sid != null) {\r
200       StoreContainerType stoc_type = sid.getStoreContainerType();\r
201       return getStoreContainerForStocType(stoc_type);\r
202     }\r
203     return null;\r
204   }\r
205 \r
206   private StoreContainer getStoreContainerForStocType(StoreContainerType\r
207       stoc_type) {\r
208     if (stoc_type != null && containerMap.containsKey(stoc_type))\r
209       return (StoreContainer) containerMap.get(stoc_type);\r
210     return null;\r
211   }\r
212 \r
213   private boolean has(StoreIdentifier sid) {\r
214     StoreContainer stoc = getStoreContainerForSid(sid);\r
215     return (stoc != null && stoc.has(sid)) ? true : false;\r
216   }\r
217 \r
218   public String getConfProperty(String name) {\r
219     if (name != null) {\r
220       String returnValue = "";\r
221       try {\r
222         return ostoreConf.getProperty(name);\r
223       }\r
224       catch (MissingResourceException e) {\r
225         logger.error("getConfProperty: " + e.toString());\r
226       }\r
227     }\r
228     return null;\r
229   }\r
230 \r
231   /**\r
232    *  Method:       toString()\r
233    *  Description:  Displays statistical information about the ObjectStore.\r
234        *                Further information is gathered from all @see StoreContainer\r
235    *\r
236    *  @return       String\r
237    */\r
238   public String toString() {\r
239     return toHtml(null);\r
240   }\r
241 \r
242   public String toHtml(HttpServletRequest req) {\r
243     float hitRatio = 0;\r
244     long divisor = storeHit + storeMiss;\r
245     if (divisor > 0)\r
246       hitRatio = (float) storeHit / (float) divisor;\r
247     hitRatio *= 100;\r
248 \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
255 \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
261     }\r
262 \r
263     return sb.toString();\r
264   }\r
265 \r
266   /**\r
267    *  Method:       html_version()\r
268        *  Description:  returns ObjectStore version as String for HTML representation\r
269    *\r
270    *  @return       String\r
271    */\r
272   private String html_version() {\r
273     return "<i>" + version() + "</i>";\r
274   }\r
275 \r
276   /**\r
277    *  Method:       version()\r
278    *  Description:  returns ObjectStore version as String\r
279    *\r
280    *  @return       String\r
281    */\r
282   private String version() {\r
283     return "v_sstart3__1.0";\r
284   }\r
285 \r
286 }