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    }