KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ojb > odmg > NamedRootsMap


1 package org.apache.ojb.odmg;
2
3 /* Copyright 2002-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.io.Serializable JavaDoc;
19 import java.util.HashMap JavaDoc;
20 import java.util.Iterator JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import org.apache.commons.lang.SerializationUtils;
24 import org.apache.ojb.broker.Identity;
25 import org.apache.ojb.broker.PersistenceBroker;
26 import org.apache.ojb.broker.PersistenceBrokerException;
27 import org.apache.ojb.broker.core.proxy.ProxyHelper;
28 import org.apache.ojb.broker.metadata.ClassDescriptor;
29 import org.apache.ojb.broker.util.ObjectModification;
30 import org.apache.ojb.broker.util.logging.Logger;
31 import org.apache.ojb.broker.util.logging.LoggerFactory;
32 import org.odmg.ClassNotPersistenceCapableException;
33 import org.odmg.ObjectNameNotFoundException;
34 import org.odmg.ObjectNameNotUniqueException;
35 import org.odmg.Transaction;
36
37 /**
38  * ODMG NamedRoots implementation.
39  * this implementation stores the (name, Identity) pairs in
40  * a database table.
41  * therefore the NamedRootsMap underlies the same transaction management
42  * as all other persistent objects
43  *
44  * @author Thomas Mahler
45  * @version $Id: NamedRootsMap.java,v 1.12.2.5 2005/12/21 22:29:21 tomdz Exp $
46  */

47 public class NamedRootsMap
48 {
49     private Logger log = LoggerFactory.getLogger(NamedRootsMap.class);
50     private TransactionImpl tx;
51     private HashMap JavaDoc tempBindings;
52     private Map JavaDoc deletionMap;
53     private Map JavaDoc insertMap;
54
55     NamedRootsMap(TransactionImpl tx)
56     {
57         this.tx = tx;
58         this.tempBindings = new HashMap JavaDoc();
59     }
60
61     private void addForDeletion(NamedEntry entry)
62     {
63         if(deletionMap == null)
64         {
65             deletionMap = new HashMap JavaDoc();
66         }
67         deletionMap.put(entry.getName(), entry);
68     }
69
70     private void addForInsert(NamedEntry entry)
71     {
72         if(insertMap == null)
73         {
74             insertMap = new HashMap JavaDoc();
75         }
76         insertMap.put(entry.getName(), entry);
77         if(deletionMap != null) deletionMap.remove(entry.getName());
78     }
79
80     /**
81      * Have to be performed after the "normal" objects be written
82      * to DB and before method {@link #performInsert()}.
83      */

84     public void performDeletion()
85     {
86         if(deletionMap == null)
87             return;
88         else
89         {
90             PersistenceBroker broker = tx.getBroker();
91             Iterator JavaDoc it = deletionMap.values().iterator();
92             while(it.hasNext())
93             {
94                 NamedEntry namedEntry = (NamedEntry) it.next();
95                 broker.delete(namedEntry);
96             }
97         }
98     }
99
100     /**
101      * Have to be performed after the "normal" objects be written
102      * to DB and after method {@link #performDeletion()}.
103      */

104     public void performInsert()
105     {
106         if(insertMap == null)
107             return;
108         else
109         {
110             PersistenceBroker broker = tx.getBroker();
111             Iterator JavaDoc it = insertMap.values().iterator();
112             while(it.hasNext())
113             {
114                 NamedEntry namedEntry = (NamedEntry) it.next();
115                 namedEntry.prepareForStore(broker);
116                 broker.store(namedEntry, ObjectModification.INSERT);
117             }
118         }
119     }
120
121     public void afterWriteCleanup()
122     {
123         if(deletionMap != null) deletionMap.clear();
124         if(insertMap != null) insertMap.clear();
125     }
126
127     private void localBind(String JavaDoc key, NamedEntry entry) throws ObjectNameNotUniqueException
128     {
129         if(tempBindings.containsKey(key))
130         {
131             throw new ObjectNameNotUniqueException("Object key already in use, the key '"
132                     + key + "' is not unique");
133         }
134         else
135         {
136             tempBindings.put(key, entry);
137         }
138     }
139
140     private void localUnbind(String JavaDoc key)
141     {
142         tempBindings.remove(key);
143     }
144
145     private NamedEntry localLookup(String JavaDoc key)
146     {
147         return (NamedEntry) tempBindings.get(key);
148     }
149
150     /**
151      * Return a named object associated with the specified key.
152      */

153     Object JavaDoc lookup(String JavaDoc key) throws ObjectNameNotFoundException
154     {
155         Object JavaDoc result = null;
156         NamedEntry entry = localLookup(key);
157         // can't find local bound object
158
if(entry == null)
159         {
160             try
161             {
162                 PersistenceBroker broker = tx.getBroker();
163                 // build Identity to lookup entry
164
Identity oid = broker.serviceIdentity().buildIdentity(NamedEntry.class, key);
165                 entry = (NamedEntry) broker.getObjectByIdentity(oid);
166             }
167             catch(Exception JavaDoc e)
168             {
169                 log.error("Can't materialize bound object for key '" + key + "'", e);
170             }
171         }
172         if(entry == null)
173         {
174             log.info("No object found for key '" + key + "'");
175         }
176         else
177         {
178             Object JavaDoc obj = entry.getObject();
179             // found a persistent capable object associated with that key
180
if(obj instanceof Identity)
181             {
182                 Identity objectIdentity = (Identity) obj;
183                 result = tx.getBroker().getObjectByIdentity(objectIdentity);
184                 // lock the persistance capable object
185
RuntimeObject rt = new RuntimeObject(result, objectIdentity, tx, false);
186                 tx.lockAndRegister(rt, Transaction.READ, tx.getRegistrationList());
187             }
188             else
189             {
190                 // nothing else to do
191
result = obj;
192             }
193         }
194         if(result == null) throw new ObjectNameNotFoundException("Can't find named object for name '" + key + "'");
195         return result;
196     }
197
198     /**
199      * Remove a named object
200      */

201     void unbind(String JavaDoc key)
202     {
203         NamedEntry entry = new NamedEntry(key, null, false);
204         localUnbind(key);
205         addForDeletion(entry);
206     }
207
208     public void bind(Object JavaDoc object, String JavaDoc name) throws ObjectNameNotUniqueException
209     {
210         boolean useIdentity = true;
211         PersistenceBroker broker = tx.getBroker();
212         ClassDescriptor cld = null;
213         try
214         {
215             cld = broker.getClassDescriptor(ProxyHelper.getRealClass(object));
216         }
217         catch(PersistenceBrokerException e)
218         {
219         }
220
221         // if null a non-persistent capable object was specified
222
if(cld == null)
223         {
224             useIdentity = false;
225             if(!(object instanceof Serializable JavaDoc))
226             {
227                 throw new ClassNotPersistenceCapableException(
228                         "Can't bind named object, because it's not Serializable. Name=" + name + ", object=" + object);
229             }
230         }
231         else
232         {
233             RuntimeObject rt = new RuntimeObject(object, tx);
234             // if the object is already persistet, check for read
235
// lock to make sure
236
// that the used object is a valid version
237
// else persist the specified named object
238
if(!rt.isNew())
239             {
240                 tx.lockAndRegister(rt, Transaction.READ, tx.getRegistrationList());
241             }
242             else
243             {
244                 tx.makePersistent(rt);
245             }
246         }
247         NamedEntry oldEntry = localLookup(name);
248         if(oldEntry == null)
249         {
250             Identity oid = broker.serviceIdentity().buildIdentity(NamedEntry.class, name);
251             oldEntry = (NamedEntry) broker.getObjectByIdentity(oid);
252         }
253         if(oldEntry != null)
254         {
255             throw new ObjectNameNotUniqueException("The name of the specified named object already exist, name=" + name);
256         }
257
258         NamedEntry entry = new NamedEntry(name, object, useIdentity);
259         addForInsert(entry);
260         localBind(name, entry);
261     }
262
263
264
265     //==============================================
266
// inner class
267
//==============================================
268
/**
269      * represents an entry to the named roots table.
270      * maps names (Strings) to OJB Identities
271      */

272     public static final class NamedEntry implements Serializable JavaDoc
273     {
274         static final long serialVersionUID = 6179717896336300342L;
275         /**
276          * the name under which an object is registered in the NamedRoots Map
277          */

278         private String JavaDoc name;
279         /**
280          * the serialized Identity representing the named Object
281          */

282         private byte[] oid;
283
284         private transient Object JavaDoc object;
285         private transient boolean useIdentity;
286
287         public NamedEntry()
288         {
289         }
290
291         NamedEntry(final String JavaDoc aName, final Object JavaDoc object, final boolean useIdentity)
292         {
293             this.name = aName;
294             this.object = object;
295             this.useIdentity = useIdentity;
296         }
297
298         /**
299          * This has to be called before this object will be persistet.
300          */

301         public void prepareForStore(PersistenceBroker broker)
302         {
303             if(object != null)
304             {
305                 if(useIdentity)
306                 {
307                     Identity oid = broker.serviceIdentity().buildIdentity(object);
308                     this.oid = SerializationUtils.serialize(oid);
309                 }
310                 else
311                 {
312                     this.oid = SerializationUtils.serialize((Serializable JavaDoc) object);
313                 }
314             }
315         }
316
317         public String JavaDoc getName()
318         {
319             return name;
320         }
321
322         public void setName(String JavaDoc name)
323         {
324             this.name = name;
325         }
326
327         public byte[] getOid()
328         {
329             return oid;
330         }
331
332         public void setOid(byte[] oid)
333         {
334             this.oid = oid;
335         }
336
337         Object JavaDoc getObject()
338         {
339             if(object != null)
340             {
341                 return object;
342             }
343             else
344             {
345                 return oid != null ? SerializationUtils.deserialize(oid) : null;
346             }
347         }
348     }
349 }
350
Popular Tags