001    package org.apache.ojb.broker.util.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 org.apache.ojb.broker.PersistenceBroker;
019    import org.apache.ojb.broker.PersistenceBrokerException;
020    import org.apache.ojb.broker.metadata.ClassDescriptor;
021    
022    import java.util.Iterator;
023    import java.util.Vector;
024    
025    /**
026     * This is a collection that tracks removal and addition of elements.
027     * This tracking allow the PersistenceBroker to delete elements from
028     * the database that have been removed from the collection before a
029     * PB.store() orperation occurs.
030     * This will allow to use the PB api in way pretty close to ODMG persistent
031     * collections!
032     * @author Thomas Mahler
033     * @version $Id: RemovalAwareCollection.java,v 1.1 2007-08-24 22:17:39 ewestfal Exp $
034     */
035    public class RemovalAwareCollection extends ManageableVector implements IRemovalAwareCollection
036    {
037        private Vector allObjectsToBeRemoved = new Vector();
038    
039        /**
040         * @see org.apache.ojb.broker.ManageableCollection#afterStore(PersistenceBroker broker)
041         */
042        public void afterStore(PersistenceBroker broker) throws PersistenceBrokerException
043        {
044            // make sure allObjectsToBeRemoved does not contain
045            // any instances that got re-added to the list
046            allObjectsToBeRemoved.removeAll(this);
047    
048            Iterator iter = allObjectsToBeRemoved.iterator();
049            while (iter.hasNext())
050            {
051                Object obj = iter.next();
052                ClassDescriptor cld = broker.getClassDescriptor(obj.getClass());
053                if (broker.serviceBrokerHelper().assertValidPkForDelete(cld, obj))
054                {    
055                    broker.delete(obj);
056                }    
057            }
058            allObjectsToBeRemoved.clear();
059        }
060    
061        /**
062         * @see java.util.List#remove(int)
063         */
064        public Object remove(int index)
065        {
066            Object toBeRemoved = super.remove(index);
067            registerForDeletion(toBeRemoved);
068            return toBeRemoved;
069        }
070    
071        protected void registerForDeletion(Object toBeRemoved)
072        {
073            //only add objects once to avoid double deletions
074            if (!allObjectsToBeRemoved.contains(toBeRemoved))
075            {
076                this.allObjectsToBeRemoved.add(toBeRemoved);
077            }
078        }
079    
080        /**
081         * @see java.util.Collection#remove(Object)
082         */
083        public boolean remove(Object o)
084        {
085            boolean result = super.remove(o);
086            registerForDeletion(o);
087            return result;
088        }
089    
090        /**
091         * @see java.util.Vector#clear()
092         */
093        public synchronized void clear()
094        {
095            removeAllElements();
096        }
097    
098        /**
099         * @see java.util.Vector#removeAllElements()
100         */
101        public synchronized void removeAllElements()
102        {
103            for (int i = 0; i < this.size(); i++)
104            {
105                registerForDeletion(this.get(i));
106            }
107            super.removeAllElements();
108        }
109    
110    
111        /**
112         * @see java.util.Vector#removeElementAt(int)
113         */
114        public synchronized void removeElementAt(int index)
115        {
116            Object toBeDeleted = this.get(index);
117            registerForDeletion(toBeDeleted);
118            super.removeElementAt(index);
119        }
120    
121        /**
122         * @see java.util.AbstractList#removeRange(int, int)
123         */
124        protected void removeRange(int fromIndex, int toIndex)
125        {
126            for (int i = fromIndex; i < toIndex; i++)
127            {
128                registerForDeletion(this.get(i));
129            }
130            super.removeRange(fromIndex, toIndex);
131        }
132    
133    }