86f2c4a73219cfd93278f6812773880b5764e8ef
[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  : ").append(storeHit);
96     sb.append("\nObjectStore misses: ").append(storeMiss);
97     sb.append("\nCurrently ").append(containerMap.size());
98     sb.append("\nStoreContainer 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)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 "prototype_daytwo";}
179 }