basic test run working, next step incorporating into db-layer
[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 final static ObjectStore    INSTANCE=new ObjectStore();
39         private final static HashMap        containerMap=new HashMap(); // StoreContainerType/StoreContainer
40         private final static Class          storableObjectInterface=StorableObject.class;
41         private static Logfile              storeLog;
42         private static long                 storeHit=0,storeMiss=0;
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     if (sid!=null ) {
59       StorableObject storeObject=null;
60       StoreContainer stoc = getStoreContainerForSid( sid );
61       if (stoc!=null) storeObject=stoc.use(sid);
62       else System.out.println("Warning: container not found for: " + sid.toString());
63       if (storeObject!=null) storeHit++;
64                   return storeObject;
65     }
66     storeMiss++; return null;
67
68         }
69
70         /**
71          *  Method:       add
72          *  Description:  A StoreIdentifier is added to the ObjectStore, if it
73          *                contains a reference to a @see StorableObject.
74          */
75         public void add(StoreIdentifier sid) {
76                 if ( sid!=null && sid.hasReference() ) {
77                         // find the right StoreContainer for sid
78                         StoreContainer stoc = getStoreContainerForSid(sid);
79                         if (stoc==null) {
80                                 // we have to make new StoreContainer
81                                 StoreContainerType stocType = sid.getStoreContainerType();
82                                 stoc = new StoreContainer(stocType);
83                                 containerMap.put(stocType, stoc);
84                         }
85                         stoc.add(sid);
86                 }
87         }
88
89         /**
90          *  Method:       toString()
91          *  Description:  Displays statistical information about the ObjectStore.
92          *                Further information is gathered from all @see StoreContainer
93          *
94          *  @return       String
95          */
96         public String toString() {
97
98     float hitRatio=0;
99     long divisor=storeHit+storeMiss;
100     if (divisor>0) hitRatio=(float)storeHit/(float)divisor;
101     hitRatio*=100;
102
103     StringBuffer sb = new StringBuffer("Mir-ObjectStore v_");
104                 sb.append(version()).append("\n");
105                 sb.append("ObjectStore overall hits/misses/ratio: ").append(storeHit);
106                 sb.append("/").append(storeMiss).append("/").append(hitRatio);
107                 sb.append("%\nCurrently ").append(containerMap.size());
108                 sb.append(" StoreContainer in use - listing information:\n");
109
110                 // ask container for information
111                 StoreContainer currentStoc;
112                 for(Iterator it=containerMap.keySet().iterator();it.hasNext();) {
113                         currentStoc=(StoreContainer)containerMap.get(it.next());
114                         sb.append(currentStoc.toString());
115                 }
116
117                 return sb.toString();
118         }
119
120         /**
121          *  Method:       invalidate(StorableObject sto)
122          *  Description:  ObjectStore is notified of change of a @see StorableObject
123          *                sto and invalidates all relevant cache entries.
124          */
125
126         public void invalidate(StoreIdentifier sid) {
127                 // propagate invalidation to StoreContainer
128                 if (sid!=null) {
129       StoreContainer stoc = getStoreContainerForSid(sid);
130       stoc.invalidate(sid);
131                 }
132         }
133
134   /**
135    *  Method:       invalidate(StoreContainerType)
136    *  Description:  serves to invalidate a whole StoreContainer
137    *
138    *  @return
139    */
140   public void invalidate(StoreContainerType stoc_type) {
141     if ( stoc_type != null ) {
142       StoreContainer stoc = getStoreContainerForStocType(stoc_type);
143       if ( stoc!=null )
144         stoc.invalidate();
145     }
146
147   }
148
149         // internal methods for StoreContainer managment
150
151         /**
152          *  Method:       getStoreContainerForSid
153          *  Description:  private method to find the right @see StoreContainer for
154          *                the @see StoreIdentifier sid.
155          *
156          *  @return       StoreContainer is null when no Container is found.
157          */
158         private StoreContainer getStoreContainerForSid(StoreIdentifier sid){
159                 // find apropriate container for a specific sid
160                 if (sid!=null) {
161                         StoreContainerType stoc_type = sid.getStoreContainerType();
162                         return getStoreContainerForStocType(stoc_type);
163                 }
164                 return null;
165         }
166
167   private StoreContainer getStoreContainerForStocType(StoreContainerType stoc_type) {
168     if ( stoc_type!=null && containerMap.containsKey(stoc_type) )
169                                 return (StoreContainer)containerMap.get(stoc_type);
170     return null;
171   }
172
173         /**
174          *  Method:       implementsStorableObject
175          *  Description:  internall helper method to find out if a class implements
176          *                interface StorableObject.
177          *
178          *  @return       true if yes, otherwise no.
179          */
180         private final static boolean implementsStorableObject(Class aClass) {
181                 if (aClass!=null) {
182                         Class[] interfaces = aClass.getInterfaces();
183                         if (interfaces.length>0) {
184                                 for (int i=0;i<interfaces.length;i++) {
185                                         if (interfaces[i]==storableObjectInterface) return true;
186                                 }
187                         }
188                 }
189                 return false;
190         }
191
192
193         private boolean has(StoreIdentifier sid) {
194                 StoreContainer stoc = getStoreContainerForSid( sid );
195                 return ( stoc != null && stoc.has(sid) ) ? true:false;
196         }
197
198
199         /**
200          *  Method:       version()
201          *  Description:  returns ObjectStore version as String
202          *
203          *  @return       String
204          */
205         private String version() { return "00.d5";}
206 }