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.AbstractMap;
020 import java.util.Iterator;
021 import java.util.Set;
022 import java.util.List;
023
024 import org.apache.ojb.broker.PBKey;
025 import org.apache.ojb.broker.PersistenceBroker;
026 import org.apache.ojb.broker.PersistenceBrokerAware;
027 import org.apache.ojb.broker.PersistenceBrokerException;
028 import org.apache.ojb.broker.util.collections.ManageableHashSet;
029 import org.apache.ojb.broker.util.logging.Logger;
030 import org.apache.ojb.broker.util.logging.LoggerFactory;
031 import org.apache.ojb.odmg.TransactionExt;
032 import org.apache.ojb.odmg.TransactionImpl;
033 import org.apache.ojb.odmg.TxManagerFactory;
034 import org.apache.ojb.odmg.RuntimeObject;
035 import org.odmg.DMap;
036 import org.odmg.Transaction;
037
038 /**
039 * @author <a href="mailto:thma@apache.org">Thomas Mahler<a>
040 * @version $Id: DMapImpl.java,v 1.1 2007-08-24 22:17:37 ewestfal Exp $
041 */
042
043 public class DMapImpl extends AbstractMap implements DMap, Serializable, PersistenceBrokerAware
044 {
045 private static final long serialVersionUID = 7048246616243056480L;
046 private transient Logger log;
047
048 private Integer id;
049 private Set entries;
050 private PBKey pbKey;
051
052 /**
053 * DMapImpl constructor comment.
054 */
055 public DMapImpl()
056 {
057 this.entries = new ManageableHashSet();
058 // if(getTransaction() == null)
059 // {
060 // throw new TransactionNotInProgressException("Materialization of DCollection instances must be done" +
061 // " within a odmg-tx");
062 // }
063 getPBKey();
064 }
065
066 /**
067 * DListImpl constructor comment.
068 */
069 public DMapImpl(PBKey key)
070 {
071 this.entries = new ManageableHashSet();
072 this.pbKey = key;
073 }
074
075 protected Logger getLog()
076 {
077 if (log == null)
078 {
079 log = LoggerFactory.getLogger(DMapImpl.class);
080 }
081 return log;
082 }
083
084 protected TransactionImpl getTransaction()
085 {
086 return TxManagerFactory.instance().getTransaction();
087 }
088
089 public PBKey getPBKey()
090 {
091 if(pbKey == null)
092 {
093 TransactionExt tx = getTransaction();
094 if(tx != null && tx.isOpen())
095 {
096 pbKey = tx.getBroker().getPBKey();
097 }
098 }
099 return pbKey;
100 }
101
102 public void setPBKey(PBKey pbKey)
103 {
104 this.pbKey = pbKey;
105 }
106
107 protected DMapEntry prepareEntry(Object key, Object value)
108 {
109 return new DMapEntry(this, key, value);
110 }
111
112 /**
113 * Returns a set view of the mappings contained in this map. Each element
114 * in the returned set is a <tt>Map.Entry</tt>. The set is backed by the
115 * map, so changes to the map are reflected in the set, and vice-versa.
116 * If the map is modified while an iteration over the set is in progress,
117 * the results of the iteration are undefined. The set supports element
118 * removal, which removes the corresponding mapping from the map, via the
119 * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, <tt>removeAll</tt>,
120 * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not support
121 * the <tt>add</tt> or <tt>addAll</tt> operations.
122 *
123 * @return a set view of the mappings contained in this map.
124 */
125 public Set entrySet()
126 {
127 return entries;
128 }
129
130 /**
131 * lazily retrieve the ID of the set, no need to precompute it.
132 */
133 public Integer getId()
134 {
135 return id;
136 }
137
138 /**
139 *
140 */
141 public Object put(Object key, Object value)
142 {
143
144 DMapEntry entry = prepareEntry(key, value);
145 boolean ok = entries.add(entry);
146 if (ok)
147 {
148 TransactionImpl tx = getTransaction();
149 if ((tx != null) && (tx.isOpen()))
150 {
151 List regList = tx.getRegistrationList();
152 RuntimeObject rt = new RuntimeObject(this, tx);
153 tx.lockAndRegister(rt, Transaction.WRITE, false, regList);
154
155 rt = new RuntimeObject(key, tx);
156 tx.lockAndRegister(rt, Transaction.READ, regList);
157
158 rt = new RuntimeObject(value, tx);
159 tx.lockAndRegister(rt, Transaction.READ, regList);
160
161 rt = new RuntimeObject(entry, tx, true);
162 tx.lockAndRegister(rt, Transaction.WRITE, false, regList);
163 }
164 return null;
165 }
166 else
167 {
168 return this.get(key);
169 }
170 }
171
172
173 public Object remove(Object key)
174 {
175 Iterator i = entrySet().iterator();
176 DMapEntry correctEntry = null;
177 if (key == null)
178 {
179 while (correctEntry == null && i.hasNext())
180 {
181 DMapEntry e = (DMapEntry) i.next();
182 if (e.getKey() == null)
183 correctEntry = e;
184 }
185 }
186 else
187 {
188 while (correctEntry == null && i.hasNext())
189 {
190 DMapEntry e = (DMapEntry) i.next();
191 if (key.equals(e.getKey()))
192 correctEntry = e;
193 }
194 }
195
196 Object oldValue = null;
197 if (correctEntry != null)
198 {
199 oldValue = correctEntry.getValue();
200 i.remove();
201 TransactionImpl tx = getTransaction();
202 if ((tx != null) && (tx.isOpen()))
203 {
204 tx.deletePersistent(new RuntimeObject(correctEntry, tx));
205 }
206 }
207 return oldValue;
208 }
209
210
211 /**
212 * Gets the entries.
213 * @return Returns a Set
214 */
215 public Set getEntries()
216 {
217 return entries;
218 }
219
220 /**
221 * Sets the entries.
222 * @param entries The entries to set
223 */
224 public void setEntries(ManageableHashSet entries)
225 {
226 this.entries = entries;
227 }
228
229 /**
230 * Sets the id.
231 * @param id The id to set
232 */
233 public void setId(Integer id)
234 {
235 this.id = id;
236 }
237
238 //***************************************************************
239 // PersistenceBrokerAware interface
240 //***************************************************************
241
242 /**
243 * prepare itself for persistence. Each DList entry generates an
244 * {@link org.apache.ojb.broker.Identity} for the wrapped persistent
245 * object.
246 */
247 public void beforeInsert(PersistenceBroker broker) throws PersistenceBrokerException
248 {
249 // for (Iterator it = entries.iterator(); it.hasNext();)
250 // {
251 // ((DMapEntry)it.next()).prepareForPersistency(broker);
252 // }
253 }
254
255 /**
256 * noop
257 */
258 public void beforeUpdate(PersistenceBroker broker) throws PersistenceBrokerException
259 {
260 }
261
262 /**
263 * noop
264 */
265 public void beforeDelete(PersistenceBroker broker) throws PersistenceBrokerException
266 {
267 }
268
269 /**
270 * noop
271 */
272 public void afterUpdate(PersistenceBroker broker) throws PersistenceBrokerException
273 {
274 }
275
276 /**
277 * noop
278 */
279 public void afterInsert(PersistenceBroker broker) throws PersistenceBrokerException
280 {
281 }
282
283 /**
284 * noop
285 */
286 public void afterDelete(PersistenceBroker broker) throws PersistenceBrokerException
287 {
288 }
289
290 /**
291 * noop
292 */
293 public void afterLookup(PersistenceBroker broker) throws PersistenceBrokerException
294 {
295 }
296
297 }