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    }