View Javadoc

1   /*
2   * E-nspire Gemini.
3   * A Java and AspectJ based framework that enables transparent 
4   * bidirectional relationships between Plain Old Java Objects.
5   * 
6   * Copyright (C) 2005 Dragan Djuric
7   * 
8   * This program is free software; you can redistribute it and/or
9   * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  * 
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  * 
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21  * 
22  * Contact the author at dragand@dev.java.net
23  */
24  package com.enspire.gemini.bidirectional;
25  
26  import java.util.ListIterator;
27  import org.apache.commons.collections.iterators.AbstractListIteratorDecorator;
28  import com.enspire.gemini.BidirectionalProperty;
29  
30  /***
31   * <p><a href="http://www.e-nspire.com">e-nspire site</a></p>
32   * Decorator around another <code>BidirectionlListIterator</code>. 
33   * Ensures bidirectional behaviour over iterated elements.
34   * 
35   * @author Dragan Djuric <dragand@dev.java.net>
36   * @since 1.0
37   */
38  public class BidirectionalListIterator extends AbstractListIteratorDecorator {
39  
40      private BidirectionalProperty bidirectionalProperty;
41      private Object current;
42      
43      /***
44       * Creates the bidirectional list iterator.
45       * @param listIterator an iterator that will be decorated
46       * @param bidirectionalProperty the source of the decorated iterator
47       */
48      public BidirectionalListIterator(ListIterator listIterator, 
49              BidirectionalProperty bidirectionalProperty) {
50          super(listIterator);
51          this.bidirectionalProperty = bidirectionalProperty;
52      }
53      
54      /***
55       * @return Returns the bidirectionalProperty.
56       */
57      public BidirectionalProperty getBidirectionalProperty() {
58          return this.bidirectionalProperty;
59      }
60      
61      /***
62       * @return Returns the last.
63       */
64      public Object getCurrent() {
65          return this.current;
66      }
67      
68      /***
69       * @see java.util.Iterator#next()
70       */
71      public Object next() {
72          current = super.next();
73          return current;
74      }
75      
76      /***
77       * @see java.util.ListIterator#previous()
78       */
79      public Object previous() {
80          current = super.previous();
81          return current;
82      }
83  
84      /***
85       * @see java.util.Iterator#remove()
86       */
87      public void remove() {
88          super.remove();
89          try {
90              getBidirectionalProperty().getRelationshipUpdater().unset(
91                      getCurrent(), getBidirectionalProperty().getOppositeName(), 
92                      getBidirectionalProperty().getOwner());
93          }catch(RuntimeException e) {
94              super.add(current);
95          }
96      }
97      
98      /***
99       * @see org.apache.commons.collections.iterators.AbstractListIteratorDecorator#set(java.lang.Object)
100      */
101     public void set(Object obj) {
102         Object oldValue = this.getCurrent();
103         super.set(obj);
104         try {
105             getBidirectionalProperty().getRelationshipUpdater().unset(
106                     oldValue, getBidirectionalProperty().getOppositeName(), 
107                     getBidirectionalProperty().getOwner());
108             getBidirectionalProperty().getRelationshipUpdater().set(
109                     obj, getBidirectionalProperty().getOppositeName(),
110                     getBidirectionalProperty().getOwner());
111         }catch(RuntimeException e) {
112             if (oldValue != null) {
113                 super.set(oldValue);
114                 getBidirectionalProperty().getRelationshipUpdater().set(
115                         oldValue, getBidirectionalProperty().getOppositeName(),
116                         getBidirectionalProperty().getOwner());
117             }
118             throw e;
119         }
120     }
121 
122     /***
123      * @see org.apache.commons.collections.iterators.AbstractListIteratorDecorator#add(java.lang.Object)
124      */
125     public void add(Object obj) {
126         super.add(obj);
127         try {
128             getBidirectionalProperty().getRelationshipUpdater().set(
129                     obj, getBidirectionalProperty().getOppositeName(),
130                     getBidirectionalProperty().getOwner());
131         }catch(RuntimeException e) {
132             super.remove();
133         }
134     }
135     
136     
137 }