001 package org.apache.ojb.odmg.collections;
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 java.io.Serializable;
019
020 import org.apache.commons.lang.builder.ToStringBuilder;
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.RuntimeObject;
031 import org.apache.ojb.odmg.TransactionImpl;
032 import org.apache.ojb.odmg.TxManagerFactory;
033 import org.odmg.Transaction;
034
035 /**
036 * Encapsulates an DList entry object.
037 *
038 * @version $Id: DListEntry.java,v 1.1 2007-08-24 22:17:37 ewestfal Exp $
039 */
040 public class DListEntry implements Serializable, PersistenceBrokerAware
041 {
042 private static final long serialVersionUID = 5251476492626009907L;
043 /*
044 * declare transient, because ManageableCollection entries need to be {@link java.io.Serializable}.
045 */
046 private transient Logger log;
047 protected transient Object realSubject;
048 protected PBKey pbKey;
049
050 protected Integer id;
051 protected Integer dlistId;
052 protected Identity oid;
053 protected int position;
054
055 /**
056 * Used to instantiate persistent DLists from DB by the kernel
057 * FOR INTERNAL USE ONLY
058 */
059 public DListEntry()
060 {
061 /*
062 arminw:
063 When PB kernel fill DList with DListEntry, the DListEntry needs to know the current
064 used PBKey, because we need to lookup the real objects when user iterates the list,
065 thus we need the associated PBKey to find right PB/DB connection.
066 TODO: Find a better solution
067 */
068 // if(getTransaction() == null)
069 // {
070 // throw new TransactionNotInProgressException("Materialization of DCollection instances must be done with a tx");
071 // }
072 getPBKey();
073 }
074
075 /**
076 * Standard way to instantiate new entries
077 */
078 public DListEntry(DListImpl theDList, Object theObject)
079 {
080 this.dlistId = theDList.getId();
081 this.position = theDList.size();
082 this.realSubject = theObject;
083 this.pbKey = getPBKey();
084 }
085
086 protected Logger getLog()
087 {
088 if(log == null)
089 {
090 log = LoggerFactory.getLogger(DListEntry.class);
091 }
092 return log;
093 }
094
095 protected TransactionImpl getTransaction()
096 {
097 return TxManagerFactory.instance().getTransaction();
098 }
099
100 public PBKey getPBKey()
101 {
102 if(pbKey == null)
103 {
104 TransactionImpl tx = getTransaction();
105 if(tx != null && tx.isOpen())
106 {
107 pbKey = tx.getBroker().getPBKey();
108 }
109 }
110 return pbKey;
111 }
112
113 protected void prepareForPersistency(PersistenceBroker broker)
114 {
115 if(oid == null)
116 {
117 if(realSubject == null)
118 {
119 throw new OJBRuntimeException("Identity and real object are 'null' - Can not persist empty entry");
120 }
121 else
122 {
123 oid = broker.serviceIdentity().buildIdentity(realSubject);
124 }
125 }
126 }
127
128 protected void prepareRealSubject(PersistenceBroker broker)
129 {
130 if(oid == null)
131 {
132 throw new OJBRuntimeException("can not return real object, real object and Identity is null");
133 }
134 realSubject = broker.getObjectByIdentity(oid);
135 }
136
137 public Object getRealSubject()
138 {
139 if(realSubject != null)
140 {
141 return realSubject;
142 }
143 else
144 {
145 TransactionImpl tx = getTransaction();
146 if(tx != null && tx.isOpen())
147 {
148 prepareRealSubject(tx.getBroker());
149 if(realSubject != null)
150 {
151 RuntimeObject rt = new RuntimeObject(realSubject, tx, false);
152 tx.lockAndRegister(rt, Transaction.READ, tx.getRegistrationList());
153 }
154 }
155 else
156 {
157 PBKey aPbKey = getPBKey();
158 if(aPbKey != null)
159 {
160 PBCapsule capsule = new PBCapsule(aPbKey, null);
161 try
162 {
163 prepareRealSubject(capsule.getBroker());
164 }
165 finally
166 {
167 capsule.destroy();
168 }
169 }
170 else
171 {
172 getLog().warn("No tx, no PBKey - can't materialise object with Identity " + getOid());
173 }
174 }
175 }
176 return realSubject;
177 }
178
179 public void setRealSubject(Object realSubject)
180 {
181 this.realSubject = realSubject;
182 }
183
184 public int getPosition()
185 {
186 return position;
187 }
188
189 public void setPosition(int newPosition)
190 {
191 position = newPosition;
192 }
193
194 /**
195 * Gets the dlistId.
196 *
197 * @return Returns a int
198 */
199 public Integer getDlistId()
200 {
201 return dlistId;
202 }
203
204 /**
205 * Sets the dlistId.
206 *
207 * @param dlistId The dlistId to set
208 */
209 public void setDlistId(Integer dlistId)
210 {
211 this.dlistId = dlistId;
212 }
213
214 /**
215 * Gets the id.
216 *
217 * @return Returns a int
218 */
219 public Integer getId()
220 {
221 return id;
222 }
223
224 /**
225 * Sets the id.
226 *
227 * @param id The id to set
228 */
229 public void setId(Integer id)
230 {
231 this.id = id;
232 }
233
234 public Identity getOid()
235 {
236 return oid;
237 }
238
239 public void setOid(Identity oid)
240 {
241 this.oid = oid;
242 }
243
244 /**
245 * return String representation.
246 */
247 public String toString()
248 {
249 ToStringBuilder buf = new ToStringBuilder(this);
250 buf.append("id", id);
251 buf.append("dListId", dlistId);
252 buf.append("position", position);
253 buf.append("identity", oid);
254 buf.append("realSubject", realSubject);
255 return buf.toString();
256 }
257
258
259 //===================================================
260 // PersistenceBrokerAware interface methods
261 //===================================================
262 public void beforeInsert(PersistenceBroker broker) throws PersistenceBrokerException
263 {
264 // before insert we have to build the Identity objects of the persistent objects
265 // we can't do this ealier, because we can now expect that the persistent object
266 // was written to DB (we make sure in code that the persistent object was locked before
267 // this entry) and the generated Identity is valid
268 prepareForPersistency(broker);
269 }
270
271 public void beforeUpdate(PersistenceBroker broker) throws PersistenceBrokerException{}
272 public void beforeDelete(PersistenceBroker broker) throws PersistenceBrokerException{}
273 public void afterLookup(PersistenceBroker broker) throws PersistenceBrokerException{}
274 public void afterDelete(PersistenceBroker broker) throws PersistenceBrokerException{}
275 public void afterInsert(PersistenceBroker broker) throws PersistenceBrokerException{}
276 public void afterUpdate(PersistenceBroker broker) throws PersistenceBrokerException{}
277 }