some small changes delting unneeded imports. two new exceptions in mir.storage. usage...
[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 the com.oreilly.servlet library, any library
22  * licensed under the Apache Software License, The Sun (tm) Java Advanced
23  * Imaging library (JAI), The Sun JIMI library (or with modified versions of
24  * the above that use the same license as the above), and distribute linked
25  * combinations including the two.  You must obey the GNU General Public
26  * License in all respects for all of the code used other than the above
27  * mentioned libraries.  If you modify this file, you may extend this exception
28  * to your version of the file, but you are not obligated to do so.  If you do
29  * not wish to do so, delete this exception statement from your version.
30  */
31
32 package mir.storage.store;
33
34 /**
35  * Title:         ObjectStore for StorableObjects
36  * Description:   ObjectStore holds a Map of @see StoreContainer for all possible
37  *                @see StoreIdentifier.
38  *
39  *                @see StorageIdentifier - identitfies one object in the ObjectStore
40  *                      i.e. in its apropriate bucket. It holds a unique identifier
41  *                      of a StorableObject and a reference on the StorableObject.
42  *
43  *                @see StoreContainer - "Buckets" to store different types of Objects
44  *                      in one Container. These buckets are cofigurable via
45  *                      config.properties.
46  *
47  *                @see StoreContainerType - is a signature for all StoreContainer
48  *                      and StoreIdentifier.
49  *
50  *                @see StorableObjects - Interface Object have to implement to
51  *                      be handled by the ObjectStore
52  *
53  *                @see ServletStoreInfo - Maintenance Servlet for ObjectStore.
54  *                      Displays information about current content of the
55  *                      ObjectStore.
56  *
57  *
58  * Copyright:     Copyright (c) 2002
59  * Company:       indy
60  * @author        rk
61  * @version 1.0
62  */
63
64 import java.io.BufferedInputStream;
65 import java.io.FileInputStream;
66 import java.util.HashMap;
67 import java.util.Iterator;
68 import java.util.MissingResourceException;
69 import java.util.Properties;
70
71 import javax.servlet.http.HttpServletRequest;
72
73 import mir.config.MirPropertiesConfiguration;
74 import mir.config.MirPropertiesConfiguration.PropertiesConfigExc;
75 import mir.misc.Logfile;
76
77 public class ObjectStore {
78
79         private final static ObjectStore    INSTANCE=new ObjectStore();
80         private final static HashMap        containerMap=new HashMap(); // StoreContainerType/StoreContainer
81         private static Logfile              storeLog;
82         private static long                 storeHit=0,storeMiss=0;
83   private Properties              ostoreConf;
84
85         private ObjectStore() {
86     String confName = null;
87     try {
88       confName =
89         MirPropertiesConfiguration.instance().getString("Home")
90           + "etc/objectstore.properties";
91     } catch (PropertiesConfigExc e) {
92       e.printStackTrace(System.err);
93     }
94     Properties conf = new Properties();
95     try {
96         conf.load( new BufferedInputStream(new FileInputStream(confName)));
97     }
98     catch ( java.io.FileNotFoundException fnfe ) {
99         System.err.println("could not read config file. not found: "+confName);
100     }
101     catch ( java.io.IOException ioex ) {
102         System.err.println("could not read config file: "+confName);
103     }
104     ostoreConf = conf;
105         }
106         public static ObjectStore getInstance() { return INSTANCE; }
107
108
109         /**
110          *  Method:       use
111          *  Description:  The ObjectStore tries to find the @see StoreIdentifier sid
112          *                and returns the stored Object.
113          *
114          *  @return       StorableObject is null when no StorableObject for the
115          *                StoreIdentifier sid is found.
116          */
117         public StorableObject use(StoreIdentifier sid) {
118     if (sid!=null ) {
119       StorableObject storeObject=null;
120       StoreContainer stoc = getStoreContainerForSid( sid );
121       if (stoc!=null) storeObject=stoc.use(sid);
122       else System.out.println("Warning: container not found for: " + sid.toString());
123       if (storeObject!=null) {
124         storeHit++;
125                     return storeObject;
126       }
127     }
128     storeMiss++; return null;
129
130         }
131
132         /**
133          *  Method:       add
134          *  Description:  A StoreIdentifier is added to the ObjectStore, if it
135          *                contains a reference to a @see StorableObject.
136          */
137         public void add(StoreIdentifier sid) {
138                 if ( sid!=null && sid.hasReference() ) {
139                         // find the right StoreContainer for sid
140                         StoreContainer stoc = getStoreContainerForSid(sid);
141                         if (stoc==null) {
142                                 // we have to make new StoreContainer
143                                 StoreContainerType stocType = sid.getStoreContainerType();
144                                 stoc = new StoreContainer(stocType);
145                                 containerMap.put(stocType, stoc);
146                         }
147                         stoc.add(sid);
148                 }
149         }
150
151         /**
152          *  Method:       invalidate(StorableObject sto)
153          *  Description:  ObjectStore is notified of change of a @see StorableObject
154          *                sto and invalidates all relevant cache entries.
155          */
156
157         public void invalidate(StoreIdentifier sid) {
158                 // propagate invalidation to StoreContainer
159                 if (sid!=null) {
160       StoreContainer stoc = getStoreContainerForSid(sid);
161       stoc.invalidate(sid);
162                 }
163         }
164
165   /**
166    *  Method:       invalidate(StoreContainerType)
167    *  Description:  serves to invalidate a whole StoreContainer
168    *
169    *  @return
170    */
171   public void invalidate(StoreContainerType stoc_type) {
172     if ( stoc_type != null ) {
173       /** @todo invalidates too much:
174        *  improvement: if instanceof StoreContainerEntity && EntityList
175        *  then invalidate only StoreIdentifier matching the right table
176        */
177       StoreContainer stoc = getStoreContainerForStocType(stoc_type);
178       if ( stoc!=null )
179         stoc.invalidate();
180     }
181
182   }
183
184         // internal methods for StoreContainer managment
185
186         /**
187          *  Method:       getStoreContainerForSid
188          *  Description:  private method to find the right @see StoreContainer for
189          *                the @see StoreIdentifier sid.
190          *
191          *  @return       StoreContainer is null when no Container is found.
192          */
193         private StoreContainer getStoreContainerForSid(StoreIdentifier sid){
194                 // find apropriate container for a specific sid
195                 if (sid!=null) {
196                         StoreContainerType stoc_type = sid.getStoreContainerType();
197                         return getStoreContainerForStocType(stoc_type);
198                 }
199                 return null;
200         }
201
202   private StoreContainer getStoreContainerForStocType(StoreContainerType stoc_type) {
203     if ( stoc_type!=null && containerMap.containsKey(stoc_type) )
204                                 return (StoreContainer)containerMap.get(stoc_type);
205     return null;
206   }
207
208         private boolean has(StoreIdentifier sid) {
209                 StoreContainer stoc = getStoreContainerForSid( sid );
210                 return ( stoc != null && stoc.has(sid) ) ? true:false;
211         }
212
213   public String getConfProperty(String name) {
214     if (name!=null ) {
215       String returnValue="";
216       try {
217         return ostoreConf.getProperty(name);
218       }
219       catch (MissingResourceException e) {
220         System.err.println("ObjectStore: " + e.toString());
221       }
222     }
223     return null;
224   }
225
226         /**
227          *  Method:       toString()
228          *  Description:  Displays statistical information about the ObjectStore.
229          *                Further information is gathered from all @see StoreContainer
230          *
231          *  @return       String
232          */
233         public String toString() {
234           return toHtml(null);
235   }
236
237   public String toHtml(HttpServletRequest req) {
238     float hitRatio=0;
239     long divisor=storeHit+storeMiss;
240     if (divisor>0) hitRatio=(float)storeHit/(float)divisor;
241     hitRatio*=100;
242
243     StringBuffer sb = new StringBuffer("Mir-ObjectStore ");
244                 sb.append( ((req!=null) ? html_version():version()) ).append("\n");
245                 sb.append("ObjectStore overall hits/misses/ratio: ").append(storeHit);
246                 sb.append("/").append(storeMiss).append("/").append(hitRatio);
247                 sb.append("%\nCurrently ").append(containerMap.size());
248                 sb.append(" StoreContainer in use - listing information:\n");
249
250                 // ask container for information
251                 StoreContainer currentStoc;
252                 for(Iterator it=containerMap.keySet().iterator();it.hasNext();) {
253                         currentStoc=(StoreContainer)containerMap.get(it.next());
254                         sb.append(currentStoc.toHtml(req));
255                 }
256
257                 return sb.toString();
258         }
259
260
261   /**
262          *  Method:       html_version()
263          *  Description:  returns ObjectStore version as String for HTML representation
264          *
265          *  @return       String
266          */
267   private String html_version() { return "<i>"+version()+"</i>"; }
268
269         /**
270          *  Method:       version()
271          *  Description:  returns ObjectStore version as String
272          *
273          *  @return       String
274          */
275         private String version() { return "v_sstart3__1.0"; }
276
277 }