001 package org.apache.ojb.broker.cache;
002
003 /* Copyright 2003-2005 The Apache Software Foundation
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 import org.apache.ojb.broker.Identity;
019 import org.apache.ojb.broker.PBStateEvent;
020 import org.apache.ojb.broker.PBStateListener;
021 import org.apache.ojb.broker.PersistenceBroker;
022
023 import java.lang.ref.SoftReference;
024 import java.util.HashMap;
025 import java.util.Map;
026 import java.util.Properties;
027
028 /**
029 * This local {@link ObjectCache} implementation allows to have dedicated caches per broker.
030 * All calls are delegated to the cache associated with the currentBroker.
031 * When the broker was closed (returned to pool) the cache was cleared.
032 *
033 * <p>
034 * Implementation configuration properties:
035 * </p>
036 *
037 * <table cellspacing="2" cellpadding="2" border="3" frame="box">
038 * <tr>
039 * <td><strong>Property Key</strong></td>
040 * <td><strong>Property Values</strong></td>
041 * </tr>
042 * <tr>
043 * <td> - </td>
044 * <td>
045 * -
046 * </td>
047 * </tr>
048 * </table>
049 *
050 * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
051 * @version $Id: ObjectCachePerBrokerImpl.java,v 1.1 2007-08-24 22:17:29 ewestfal Exp $
052 */
053 public class ObjectCachePerBrokerImpl implements ObjectCache, PBStateListener
054 {
055 /**
056 * the hashtable holding all cached object
057 */
058 protected Map objectTable = null;
059
060 /**
061 * public Default Constructor
062 */
063 public ObjectCachePerBrokerImpl(PersistenceBroker broker, Properties prop)
064 {
065 objectTable = new HashMap();
066 // add this cache as permanent listener
067 broker.addListener(this, true);
068 }
069
070 /**
071 * Clear ObjectCache. I.e. remove all entries for classes and objects.
072 */
073 public void clear()
074 {
075 objectTable.clear();
076 }
077
078 /**
079 * Makes object persistent to the Objectcache.
080 * I'm using soft-references to allow gc reclaim unused objects
081 * even if they are still cached.
082 */
083 public void cache(Identity oid, Object obj)
084 {
085 if ((obj != null))
086 {
087 SoftReference ref = new SoftReference(obj);
088 objectTable.put(oid, ref);
089 }
090 }
091
092 public boolean cacheIfNew(Identity oid, Object obj)
093 {
094 if(objectTable.get(oid) == null)
095 {
096 objectTable.put(oid, obj);
097 return true;
098 }
099 return false;
100 }
101
102 /**
103 * Lookup object with Identity oid in objectTable.
104 * Returns null if no matching id is found
105 */
106 public Object lookup(Identity oid)
107 {
108 Object obj = null;
109 SoftReference ref = (SoftReference) objectTable.get(oid);
110 if (ref != null)
111 {
112 obj = ref.get();
113 if (obj == null)
114 {
115 objectTable.remove(oid); // Soft-referenced Object reclaimed by GC
116 }
117 }
118 return obj;
119 }
120
121 /**
122 * Removes an Object from the cache.
123 */
124 public void remove(Identity oid)
125 {
126 if (oid != null)
127 {
128 objectTable.remove(oid);
129 }
130 }
131
132 /**
133 * We clear the cache
134 */
135 public void beforeClose(PBStateEvent event)
136 {
137 clear();
138 }
139
140 public void afterOpen(PBStateEvent event)
141 {
142 //do nothing
143 }
144
145 public void beforeBegin(PBStateEvent event)
146 {
147 //do nothing
148 }
149
150 public void afterBegin(PBStateEvent event)
151 {
152 //do nothing
153 }
154
155 public void beforeCommit(PBStateEvent event)
156 {
157 //do nothing
158 }
159
160 public void afterCommit(PBStateEvent event)
161 {
162 //do nothing
163 }
164
165 public void beforeRollback(PBStateEvent event)
166 {
167 //do nothing
168 }
169
170 public void afterRollback(PBStateEvent event)
171 {
172 // clear to be in sync with DB
173 clear();
174 }
175 }