001: /*
002: $Header: /cvsroot/xorm/xorm/src/org/xorm/ListProxy.java,v 1.3 2003/06/27 20:06:07 dcheckoway Exp $
003:
004: This file is part of XORM.
005:
006: XORM is free software; you can redistribute it and/or modify
007: it under the terms of the GNU General Public License as published by
008: the Free Software Foundation; either version 2 of the License, or
009: (at your option) any later version.
010:
011: XORM is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: GNU General Public License for more details.
015:
016: You should have received a copy of the GNU General Public License
017: along with XORM; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: */
020: package org.xorm;
021:
022: import java.lang.reflect.Array;
023: import java.util.ArrayList;
024: import java.util.Collection;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.ListIterator;
028:
029: import org.xorm.datastore.Row;
030: import org.xorm.query.Selector;
031:
032: public class ListProxy extends RelationshipProxy implements List {
033: public ListProxy(InterfaceManager mgr, RelationshipMapping mapping,
034: InterfaceInvocationHandler owner,
035: ClassMapping classMapping, Object[] args) {
036: super (mgr, mapping, owner, classMapping, args);
037: }
038:
039: protected Selector getSelector() {
040: Selector selector = super .getSelector();
041: if (selector == null) {
042: return null;
043: }
044:
045: // Modify the basic selector by ordering by the index
046: Selector.Ordering[] ordering = new Selector.Ordering[1];
047: ordering[0] = new Selector.Ordering(mapping.getIndexColumn(),
048: Selector.Ordering.ASCENDING);
049: selector.setOrdering(ordering);
050:
051: // Ensure that the index column gets fetched
052: selector.getFetchColumns().add(mapping.getIndexColumn());
053: return selector;
054: }
055:
056: /**
057: * Lazy resolve on rows. Overrides the method in CollectionProxy
058: * to ensure that rows is always an instance of List. There
059: * is a slight performance impact to this if the datastore driver
060: * is not returning a List as the items must be copied.
061: */
062: public Collection getRows() {
063: if (rows == null) {
064: Collection c = super .getRows();
065: rows = (c instanceof List) ? c : new ArrayList(c);
066: }
067: return rows;
068: }
069:
070: // List operations
071: public boolean add(Object o) {
072: add(getRows().size(), o);
073: return true;
074: }
075:
076: public void add(int index, Object o) {
077: // Sanity checking
078: if (o == null)
079: throw new NullPointerException();
080: if (!getElementType().isInstance(o)) {
081: throw new IllegalArgumentException(
082: "Collection only accepts " + getElementType());
083: }
084:
085: if (!txnManaged) {
086: forceTransaction();
087: }
088:
089: InterfaceInvocationHandler handler = InterfaceInvocationHandler
090: .getHandler(o);
091: Row row;
092: if (mapping.isMToN()) {
093: row = new Row(mapping.getSource().getColumn().getTable());
094: row.setValue(mapping.getTarget().getColumn(), handler
095: .getObjectId());
096: markAsNew(row);
097: } else {
098: row = handler.getRow();
099: }
100: row.setValue(mapping.getSource().getColumn(), owner
101: .getObjectId());
102: row.setValue(mapping.getIndexColumn(), new Integer(index));
103:
104: ((List) getRows()).add(index, row);
105: rowToProxy.put(row, o);
106:
107: // TODO: alter indices of all elements > index
108:
109: reindex(index + 1, 1);
110: }
111:
112: protected void reindex(int start, int offset) {
113: ListIterator li = ((List) getRows()).listIterator(start);
114: while (li.hasNext()) {
115: Row row = (Row) li.next();
116: int oldIndex = ((Integer) row.getValue(mapping
117: .getIndexColumn())).intValue();
118: row.setValue(mapping.getIndexColumn(), new Integer(oldIndex
119: + offset));
120: // Mark the row for an update?
121: }
122: }
123:
124: public boolean addAll(int index, Collection c) {
125: // Sanity checking
126: if (c == null)
127: throw new NullPointerException();
128: if (c.isEmpty()) {
129: return false;
130: }
131:
132: if (!txnManaged) {
133: forceTransaction();
134: }
135:
136: int current = index;
137: ArrayList rows = new ArrayList();
138: Iterator i = c.iterator();
139: while (i.hasNext()) {
140: Object o = i.next();
141: if (!getElementType().isInstance(o)) {
142: throw new IllegalArgumentException(
143: "Collection only accepts " + getElementType());
144: }
145:
146: InterfaceInvocationHandler handler = InterfaceInvocationHandler
147: .getHandler(o);
148: Row row = new Row(mapping.getSource().getColumn()
149: .getTable());
150: row.setValue(mapping.getSource().getColumn(), owner
151: .getObjectId());
152: row.setValue(mapping.getTarget().getColumn(), handler
153: .getObjectId());
154: // TODO: set index value to current++
155:
156: rowToProxy.put(row, o);
157: if (mapping.isMToN()) {
158: markAsNew(row);
159: }
160: rows.add(row);
161: }
162: ((List) getRows()).addAll(index, rows);
163:
164: // TODO: Now update all indices of rows starting at current
165: return true;
166: }
167:
168: public Object get(int index) {
169: Row row = (Row) ((List) getRows()).get(index);
170: Object o = null;
171: if (rowToProxy.containsKey(row)) {
172: o = rowToProxy.get(row);
173: } else {
174: Object key = row.getValue(getKeyColumn());
175: o = mgr.lookup(getElementType(), key);
176: rowToProxy.put(row, o);
177: }
178: return o;
179: }
180:
181: public int indexOf(Object o) {
182: // It's possible that the Row backing o is the Row in the collection,
183: // but that's not true for many-to-many
184: // Tricky because we don't want Row.equals() to use the
185: // index column.
186: throw new UnsupportedOperationException();
187: }
188:
189: public int lastIndexOf(Object o) {
190: throw new UnsupportedOperationException();
191: }
192:
193: public ListIterator listIterator() {
194: throw new UnsupportedOperationException();
195: }
196:
197: public ListIterator listIterator(int index) {
198: throw new UnsupportedOperationException();
199: }
200:
201: public boolean remove(Object o) {
202: throw new UnsupportedOperationException();
203: }
204:
205: public Object remove(int index) {
206: throw new UnsupportedOperationException();
207: }
208:
209: public Object set(int index, Object o) {
210: throw new UnsupportedOperationException();
211: }
212:
213: public List subList(int fromIndex, int toIndex) {
214: throw new UnsupportedOperationException();
215: }
216:
217: public Object[] toArray() {
218: Object[] output = new Object[getRows().size()];
219:
220: Iterator it = iterator();
221: int i = 0;
222: while (it.hasNext()) {
223: output[i++] = it.next();
224: }
225: return output;
226: }
227:
228: public Object[] toArray(Object[] a) {
229: Object[] output = (Object[]) Array.newInstance(a.getClass()
230: .getComponentType(), getRows().size());
231: Iterator it = iterator();
232: int i = 0;
233: while (it.hasNext()) {
234: Array.set(output, i++, it.next());
235: }
236: return output;
237: }
238:
239: public boolean equals(Object o) {
240: // Check if all list elements are equal
241: throw new UnsupportedOperationException();
242: }
243: }
|