starting to test object store
[mir.git] / source / mir / storage / store / ObjectStore.java
1 package mir.storage.store;
2
3 /**
4  * Title:         ObjectStore for StorableObjects
5  * Description:   ObjectStore holds a Map of @see StoreContainer for all possible
6  *                @see StoreIdentifier.
7  *
8  *                @see StorageIdentifier - identitfies one object in the ObjectStore
9  *                      i.e. in its apropriate bucket. It holds a unique identifier
10  *                      of a StorableObject and a reference on the StorableObject.
11  *
12  *                @see StoreContainer - "Buckets" to store different types of Objects
13  *                      in one Container. These buckets are cofigurable via
14  *                      config.properties.
15  *
16  *                @see StoreContainerType - is a signature for all StoreContainer
17  *                      and StoreIdentifier.
18  *
19  *                @see StorableObjects - Interface Object have to implement to
20  *                      be handled by the ObjectStore
21  *
22  *                @see ServletStoreInfo - Maintenance Servlet for ObjectStore.
23  *                      Displays information about current content of the
24  *                      ObjectStore.
25  *
26  *
27  * Copyright:     Copyright (c) 2002
28  * Company:       indy
29  * @author        rk
30  * @version 1.0
31  */
32
33 import java.util.*;
34 import mir.misc.Logfile;
35
36 public class ObjectStore {
37
38         private static ObjectStore    INSTANCE=new ObjectStore();
39         private static HashMap        containerMap=new HashMap(); // StoreContainerType/StoreContainer
40         private static Logfile        storeLog;
41         private static long           storeHit=0,storeMiss=0;
42         private static Class          storableObjectInterface=StorableObject.class;
43
44         private ObjectStore() {
45         }
46         public static ObjectStore getInstance() { return INSTANCE; }
47
48
49         /**
50          *  Method:       use
51          *  Description:  The ObjectStore tries to find the @see StoreIdentifier sid
52          *                and returns the stored Object.
53          *
54          *  @return       StorableObject is null when no StorableObject for the
55          *                StoreIdentifier sid is found.
56          */
57         public StorableObject use(StoreIdentifier sid) {
58                 StorableObject storeObject=null;
59                 StoreContainer stoc = getStoreContainerForSid( sid );
60                 if (stoc!=null) storeObject=stoc.use(sid);
61                 if (storeObject==null) storeMiss++; else storeHit++;
62                 return storeObject;
63         }
64
65         /**
66          *  Method:       add
67          *  Description:  A StoreIdentifier is added to the ObjectStore, if it
68          *                contains a reference to a @see StorableObject.
69          */
70         public void add(StoreIdentifier sid) {
71                 if ( sid!=null && sid.hasReference() ) {
72                         // find the right StoreContainer for sid
73                         StoreContainer stoc = getStoreContainerForSid(sid);
74                         if (stoc==null) {
75                                 // we have to make new StoreContainer
76                                 StoreContainerType stocType = sid.getStoreContainerType();
77                                 stoc = new StoreContainer(stocType);
78                                 containerMap.put(stocType, stoc);
79                         }
80                         stoc.add(sid);
81                 }
82         }
83
84         /**
85          *  Method:       toString()
86          *  Description:  Displays statistical information about the ObjectStore.
87          *                Further information is gathered from all @see StoreContainer
88          *
89          *  @return       String
90          */
91         public String toString() {
92
93                 StringBuffer sb = new StringBuffer("Mir-ObjectStore v_");
94                 sb.append(version()).append("\n");
95                 sb.append("\nObjectStore hits/misses: ").append(storeHit);
96                 sb.append("/").append(storeMiss);
97                 sb.append("\nCurrently ").append(containerMap.size());
98                 sb.append(" StoreContainer in use - listing information:\n");
99
100                 // ask container for information
101                 StoreContainer currentStoc;
102                 for(Iterator it=containerMap.keySet().iterator();it.hasNext();) {
103                         currentStoc=(StoreContainer)containerMap.get(it.next());
104                         sb.append(currentStoc.toString());
105                 }
106
107                 return sb.toString();
108         }
109
110         /**
111          *  Method:       invalidate(StorableObject sto)
112          *  Description:  ObjectStore is notified of change of a @see StorableObject
113          *                sto and invalidates all relevant cache entries.
114          */
115
116         public void invalidate(StorableObject sto) {
117                 // propagate invalidation to StoreContainer
118                 if (sto!=null) {
119                         StoreIdentifier sid = sto.getStoreIdentifier();
120                         if (sto!=null) {
121                                 StoreContainer stoc = getStoreContainerForSid(sid);
122                                 stoc.invalidate(sto);
123                         }
124                 }
125         }
126
127         // internal methods for StoreContainer managment
128
129         /**
130          *  Method:       getStoreContainerForSid
131          *  Description:  private method to find the right @see StoreContainer for
132          *                the @see StoreIdentifier sid.
133          *
134          *  @return       StoreContainer is null when no Container is found.
135          */
136         private StoreContainer getStoreContainerForSid(StoreIdentifier sid){
137                 // find apropriate container for a specific sid
138                 if (sid!=null) {
139                         StoreContainerType stoc_type = sid.getStoreContainerType();
140                         if ( containerMap.containsKey(stoc_type) )
141                                 return (StoreContainer)containerMap.get(stoc_type);
142                 }
143                 return null;
144         }
145
146         /**
147          *  Method:       implementsStorableObject
148          *  Description:  internall helper method to find out if a class implements
149          *                interface StorableObject.
150          *
151          *  @return       true if yes, otherwise no.
152          */
153         private final static boolean implementsStorableObject(Class aClass) {
154                 if (aClass!=null) {
155                         Class[] interfaces = aClass.getInterfaces();
156                         if (interfaces.length>0) {
157                                 for (int i=0;i<interfaces.length;i++) {
158                                         if (interfaces[i]==storableObjectInterface) return true;
159                                 }
160                         }
161                 }
162                 return false;
163         }
164
165
166         private boolean has(StoreIdentifier sid) {
167                 StoreContainer stoc = getStoreContainerForSid( sid );
168                 return ( stoc != null && stoc.has(sid) ) ? true:false;
169         }
170
171
172         /**
173          *  Method:       version()
174          *  Description:  returns ObjectStore version as String
175          *
176          *  @return       String
177          */
178         private String version() { return "00_daythree";}
179 }