001 package org.apache.ojb.odmg.collections;
002
003 /* Copyright 2002-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 java.io.Serializable;
019 import java.util.Map.Entry;
020
021 import org.apache.ojb.broker.Identity;
022 import org.apache.ojb.broker.OJBRuntimeException;
023 import org.apache.ojb.broker.PBKey;
024 import org.apache.ojb.broker.PersistenceBroker;
025 import org.apache.ojb.broker.PersistenceBrokerAware;
026 import org.apache.ojb.broker.PersistenceBrokerException;
027 import org.apache.ojb.broker.util.logging.Logger;
028 import org.apache.ojb.broker.util.logging.LoggerFactory;
029 import org.apache.ojb.odmg.PBCapsule;
030 import org.apache.ojb.odmg.TransactionExt;
031 import org.apache.ojb.odmg.TransactionImpl;
032 import org.apache.ojb.odmg.TxManagerFactory;
033
034 /**
035 * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
036 * @version $Id: DMapEntry.java,v 1.1 2007-08-24 22:17:37 ewestfal Exp $
037 */
038
039 public class DMapEntry implements Entry, Serializable, PersistenceBrokerAware
040 {
041 private static final long serialVersionUID = 4382757889982004339L;
042 private transient Logger log = LoggerFactory.getLogger(DMapEntry.class);
043
044 private PBKey pbKey;
045
046 private Integer id;
047 private Integer dmapId;
048 private Identity keyOid;
049 private Identity valueOid;
050
051 /* declare transient because the object is not required to be serializable and we can reload it via the oid */
052 private transient Object keyRealSubject;
053 /* declare transient because the object is not required to be serializable and we can reload it via the oid */
054 private transient Object valueRealSubject;
055
056 /**
057 * Used to materialize DMaps from the database.
058 */
059 public DMapEntry()
060 {
061 // if(getTransaction() == null)
062 // {
063 // throw new TransactionNotInProgressException("Materialization of DCollection instances must be done with a tx");
064 // }
065 this.pbKey = getPBKey();
066 }
067
068 /**
069 * DMapEntry constructor comment.
070 */
071 public DMapEntry(DMapImpl map, Object key, Object value)
072 {
073 if(map != null)
074 {
075 dmapId = map.getId();
076 }
077 keyRealSubject = key;
078 valueRealSubject = value;
079 getPBKey();
080 }
081
082 protected Logger getLog()
083 {
084 if(log == null)
085 {
086 log = LoggerFactory.getLogger(DMapEntry.class);
087 }
088 return log;
089 }
090
091 protected TransactionImpl getTransaction()
092 {
093 return TxManagerFactory.instance().getTransaction();
094 }
095
096 public PBKey getPBKey()
097 {
098 if(pbKey == null)
099 {
100 TransactionImpl tx = getTransaction();
101 if(tx != null && tx.isOpen())
102 {
103 pbKey = tx.getBroker().getPBKey();
104 }
105 }
106 return pbKey;
107 }
108
109 protected void prepareForPersistency(PersistenceBroker broker)
110 {
111 if(keyOid == null)
112 {
113 if(keyRealSubject == null)
114 {
115 throw new OJBRuntimeException("Key identity and real key object are 'null' - Can not persist empty entry");
116 }
117 else
118 {
119 keyOid = broker.serviceIdentity().buildIdentity(keyRealSubject);
120 }
121 }
122 if(valueOid == null)
123 {
124 if(valueRealSubject == null)
125 {
126 throw new OJBRuntimeException("Key identity and real key object are 'null' - Can not persist empty entry");
127 }
128 else
129 {
130 valueOid = broker.serviceIdentity().buildIdentity(valueRealSubject);
131 }
132 }
133 }
134
135 protected void prepareKeyRealSubject(PersistenceBroker broker)
136 {
137 if(keyOid == null)
138 {
139 getLog().info("Cannot retrieve real key object because its id is not known");
140 }
141 else
142 {
143 keyRealSubject = broker.getObjectByIdentity(keyOid);
144 }
145 }
146
147 protected void prepareValueRealSubject(PersistenceBroker broker)
148 {
149 if(valueOid == null)
150 {
151 getLog().info("Cannot retrieve real key object because its id is not known");
152 }
153 else
154 {
155 valueRealSubject = broker.getObjectByIdentity(valueOid);
156 }
157 }
158
159 /**
160 * Returns the real key object.
161 */
162 public Object getRealKey()
163 {
164 if(keyRealSubject != null)
165 {
166 return keyRealSubject;
167 }
168 else
169 {
170 TransactionExt tx = getTransaction();
171
172 if((tx != null) && tx.isOpen())
173 {
174 prepareKeyRealSubject(tx.getBroker());
175 }
176 else
177 {
178 if(getPBKey() != null)
179 {
180 PBCapsule capsule = new PBCapsule(getPBKey(), null);
181
182 try
183 {
184 prepareKeyRealSubject(capsule.getBroker());
185 }
186 finally
187 {
188 capsule.destroy();
189 }
190 }
191 else
192 {
193 getLog().warn("No tx, no PBKey - can't materialise key with Identity " + getKeyOid());
194 }
195 }
196 }
197 return keyRealSubject;
198 }
199
200 /* (non-Javadoc)
201 * @see java.util.Map.Entry#getKey()
202 */
203 public Object getKey()
204 {
205 // we don't save the key object itself but only its identiy
206 // so we now might have to load the object from the db
207 if((keyRealSubject == null))
208 {
209 return getRealKey();
210 }
211 else
212 {
213 return keyRealSubject;
214 }
215 }
216
217 /**
218 * Returns the real value object.
219 */
220 public Object getRealValue()
221 {
222 if(valueRealSubject != null)
223 {
224 return valueRealSubject;
225 }
226 else
227 {
228 TransactionExt tx = getTransaction();
229
230 if((tx != null) && tx.isOpen())
231 {
232 prepareValueRealSubject(tx.getBroker());
233 }
234 else
235 {
236 if(getPBKey() != null)
237 {
238 PBCapsule capsule = new PBCapsule(getPBKey(), null);
239
240 try
241 {
242 prepareValueRealSubject(capsule.getBroker());
243 }
244 finally
245 {
246 capsule.destroy();
247 }
248 }
249 else
250 {
251 getLog().warn("No tx, no PBKey - can't materialise value with Identity " + getKeyOid());
252 }
253 }
254 }
255 return valueRealSubject;
256 }
257
258 /* (non-Javadoc)
259 * @see java.util.Map.Entry#getValue()
260 */
261 public Object getValue()
262 {
263 // we don't save the value object itself but only its identiy
264 // so we now might have to load the object from the db
265 if((valueRealSubject == null))
266 {
267 return getRealValue();
268 }
269 else
270 {
271 return valueRealSubject;
272 }
273 }
274
275 /*
276 * (non-Javadoc)
277 * @see java.util.Map.Entry#setValue(java.lang.Object)
278 */
279 public Object setValue(Object obj)
280 {
281 Object old = valueRealSubject;
282
283 valueRealSubject = obj;
284 return old;
285 }
286
287 /**
288 * Gets the dmapId.
289 *
290 * @return Returns a int
291 */
292 public Integer getDmapId()
293 {
294 return dmapId;
295 }
296
297 /**
298 * Sets the dmapId.
299 *
300 * @param dmapId The dmapId to set
301 */
302 public void setDmapId(Integer dmapId)
303 {
304 this.dmapId = dmapId;
305 }
306
307 /**
308 * Gets the id.
309 *
310 * @return Returns a int
311 */
312 public Integer getId()
313 {
314 return id;
315 }
316
317 /**
318 * Sets the id.
319 *
320 * @param id The id to set
321 */
322 public void setId(Integer id)
323 {
324 this.id = id;
325 }
326
327 public Identity getKeyOid()
328 {
329 return keyOid;
330 }
331
332 public void setKeyOid(Identity keyOid)
333 {
334 this.keyOid = keyOid;
335 }
336
337 public Identity getValueOid()
338 {
339 return valueOid;
340 }
341
342 public void setValueOid(Identity valueOid)
343 {
344 this.valueOid = valueOid;
345 }
346
347 //===================================================
348 // PersistenceBrokerAware interface methods
349 //===================================================
350 public void beforeInsert(PersistenceBroker broker) throws PersistenceBrokerException
351 {
352 // before insert we have to build the Identity objects of the persistent objects
353 // we can't do this ealier, because we can now expect that the persistent object
354 // was written to DB (we make sure in code that the persistent object was locked before
355 // this entry) and the generated Identity is valid
356 prepareForPersistency(broker);
357 }
358
359 public void beforeUpdate(PersistenceBroker broker) throws PersistenceBrokerException{}
360 public void beforeDelete(PersistenceBroker broker) throws PersistenceBrokerException{}
361 public void afterLookup(PersistenceBroker broker) throws PersistenceBrokerException{}
362 public void afterDelete(PersistenceBroker broker) throws PersistenceBrokerException{}
363 public void afterInsert(PersistenceBroker broker) throws PersistenceBrokerException{}
364 public void afterUpdate(PersistenceBroker broker) throws PersistenceBrokerException{}
365 }