KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > broker > cache > MaterializationCache


1 package org.apache.ojb.broker.cache;
2
3 /* Copyright 2004-2005 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 import java.util.HashMap JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.Map JavaDoc;
21
22 import org.apache.ojb.broker.Identity;
23 import org.apache.ojb.broker.util.logging.Logger;
24 import org.apache.ojb.broker.util.logging.LoggerFactory;
25
26 /**
27  * A wrapper class for {@link ObjectCache} implementations used to materialize object graphs and
28  * push the fully materialized object to the real object cache.
29  * To avoid passing of partial materialized objects to cache this class act as a temporary storage
30  * for unmaterialized (new read or refreshed) objects.
31  *
32  * @author <a HREF="mailto:arminw@apache.org">Armin Waibel</a>
33  * @version $Id: MaterializationCache.java,v 1.1.2.6 2005/12/21 22:24:15 tomdz Exp $
34  */

35 public class MaterializationCache implements ObjectCacheInternal
36 {
37     private static Logger log = LoggerFactory.getLogger(MaterializationCache.class);
38
39     private CacheDistributor cacheDistributor;
40     private HashMap JavaDoc objectBuffer;
41     private boolean enabledReadCache;
42     private int invokeCounter;
43
44     MaterializationCache(CacheDistributor cache)
45     {
46         this.cacheDistributor = cache;
47         this.objectBuffer = new HashMap JavaDoc();
48         enabledReadCache = false;
49     }
50
51     /**
52      * Returns <em>true</em> if the materialisation cache is enabled, otherwise <em>false</em>.
53      */

54     public boolean isEnabledMaterialisationCache()
55     {
56         return enabledReadCache;
57     }
58
59     /**
60      * For internal use only! Helper method to guarantee that only full materialized objects
61      * will be pushed to the application cache regardless if an local PB transaction
62      * is running or not. When a complex object is materialized there will be
63      * nested calls to the same PB instance methods, e.g. materialization of a referenced
64      * object which itself have several references, ...
65      * <br/>
66      * This method and {@link #disableMaterializationCache()} are used to delimit nested calls
67      * and to detect the end of an object materialization and avoid endless loops on circular
68      * references.
69      * <br/>
70      * If an code block with 'enabledMaterializationCache' throws an exception, in catch-block
71      * method {@link #doLocalClear()} have to be called.
72      */

73     public void enableMaterializationCache()
74     {
75         ++invokeCounter;
76         enabledReadCache = true;
77     }
78
79     /**
80      * @see #enableMaterializationCache()
81      */

82     public void disableMaterializationCache()
83     {
84         if(!enabledReadCache) return;
85
86         --invokeCounter;
87         /*
88         if materialization of the requested object was completed, the
89         counter represents '0' and we push the object
90         to the application cache
91         */

92         if(invokeCounter == 0)
93         {
94             try
95             {
96                 if(log.isDebugEnabled())
97                 {
98                     log.debug("Materialisation of object is finished, push "
99                             + objectBuffer.size() + "objects to cache");
100                 }
101                 pushObjects();
102             }
103             finally
104             {
105                 doLocalClear();
106             }
107         }
108     }
109
110     public void doInternalCache(Identity oid, Object JavaDoc obj, int type)
111     {
112         // if OJB try to build an object graph put objects in local cache
113
// else use the application cache
114
if(enabledReadCache)
115         {
116             doLocalCache(oid, obj, type);
117         }
118         else
119         {
120             cacheDistributor.doInternalCache(oid, obj, type);
121         }
122     }
123
124     public void cache(Identity oid, Object JavaDoc obj)
125     {
126         doInternalCache(oid, obj, TYPE_UNKNOWN);
127     }
128
129     /**
130      * @see ObjectCacheInternal#cacheIfNew(org.apache.ojb.broker.Identity, Object)
131      */

132     public boolean cacheIfNew(Identity oid, Object JavaDoc obj)
133     {
134         boolean result = cacheDistributor.cacheIfNew(oid, obj);
135         if(enabledReadCache)
136         {
137             doLocalCache(oid, obj, TYPE_CACHED_READ);
138         }
139         return result;
140     }
141
142     public Object JavaDoc lookup(Identity oid)
143     {
144         Object JavaDoc result = null;
145         if(enabledReadCache)
146         {
147             result = doLocalLookup(oid);
148         }
149         if(result == null)
150         {
151             result = cacheDistributor.lookup(oid);
152         }
153         return result;
154     }
155
156     public Object JavaDoc doLocalLookup(Identity oid)
157     {
158         ObjectEntry entry = (ObjectEntry) objectBuffer.get(oid);
159         return entry != null ? entry.obj : null;
160     }
161
162     public void remove(Identity oid)
163     {
164         doLocalRemove(oid);
165         cacheDistributor.remove(oid);
166     }
167
168     public void doLocalRemove(Identity oid)
169     {
170         objectBuffer.remove(oid);
171     }
172
173     /**
174      * Clears the internal used cache for object materialization.
175      */

176     public void doLocalClear()
177     {
178         if(log.isDebugEnabled()) log.debug("Clear materialization cache");
179         invokeCounter = 0;
180         enabledReadCache = false;
181         objectBuffer.clear();
182     }
183
184     public void clear()
185     {
186         if(log.isDebugEnabled()) log.debug("Clear used caches");
187         doLocalClear();
188         cacheDistributor.clear();
189     }
190
191     private void doLocalCache(Identity oid, Object JavaDoc obj, int type)
192     {
193         objectBuffer.put(oid, new ObjectEntry(obj, type));
194     }
195
196     private void pushObjects()
197     {
198         Iterator JavaDoc it = objectBuffer.entrySet().iterator();
199         Map.Entry JavaDoc entry;
200         ObjectEntry oe;
201         while(it.hasNext())
202         {
203             entry = (Map.Entry JavaDoc) it.next();
204             oe = (ObjectEntry) entry.getValue();
205             /*
206             never push temporary object to a higher level cache
207             */

208             if(oe.type != TYPE_TEMP)
209             {
210                 if(log.isDebugEnabled()) log.debug("Push to cache: " + entry.getKey());
211                 cacheDistributor.doInternalCache((Identity) entry.getKey(), oe.obj, oe.type);
212             }
213         }
214     }
215
216     //===========================================================
217
// inner class
218
//===========================================================
219

220     static final class ObjectEntry
221     {
222         Object JavaDoc obj;
223         int type;
224
225         public ObjectEntry(Object JavaDoc obj, int type)
226         {
227             this.obj = obj;
228             this.type = type;
229         }
230     }
231 }
232
Popular Tags