001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdo.sco.detached;
012:
013: import com.versant.core.jdo.VersantStateManager;
014: import com.versant.core.common.VersantFieldMetaData;
015: import com.versant.core.jdo.sco.VersantSimpleSCO;
016: import com.versant.core.jdo.sco.SCOIterator;
017:
018: import javax.jdo.spi.PersistenceCapable;
019: import java.io.Serializable;
020: import java.util.ArrayList;
021: import java.util.Collection;
022: import java.util.Iterator;
023:
024: import com.versant.core.common.BindingSupportImpl;
025:
026: /**
027: * Detached SCO for ArrayList.
028: */
029: public final class DetachSCOArrayList extends ArrayList implements
030: Serializable, VersantSimpleSCO {
031:
032: private int fieldNo;
033: private VersantStateManager stateManager;
034: private PersistenceCapable owner;
035:
036: public DetachSCOArrayList(PersistenceCapable owner,
037: VersantStateManager stateManager, VersantFieldMetaData fmd,
038: Object[] originalData) {
039: this .fieldNo = fmd.getManagedFieldNo();
040: this .stateManager = stateManager;
041: this .owner = owner;
042: int n = originalData == null ? 0 : originalData.length;
043: if (n > 0)
044: ensureCapacity(n);
045: for (int i = 0; i < n; i++) {
046: Object o = originalData[i];
047: if (o == null)
048: throw createNPE();
049: super .add(o);
050: }
051: }
052:
053: private RuntimeException createNPE() {
054: return BindingSupportImpl.getInstance().nullElement(
055: "Null element not allowed.");
056: }
057:
058: public Object set(int index, Object element) {
059: if (element == null)
060: throw createNPE();
061: Object result = super .set(index, element);
062: makeDirty();
063: return result;
064: }
065:
066: public boolean add(Object o) {
067: if (o == null)
068: throw createNPE();
069: super .add(o);
070: makeDirty();
071: return true;
072: }
073:
074: public void add(int index, Object element) {
075: if (element == null)
076: throw createNPE();
077: super .add(index, element);
078: makeDirty();
079: }
080:
081: public Object remove(int index) {
082: Object result = super .remove(index);
083: if (result == null)
084: return null; // ok as we do not allow nulls in list
085: makeDirty();
086: return result;
087: }
088:
089: public boolean remove(Object o) {
090: // Finding the index and removing it is faster as ArrayList leaves this
091: // to AbstractCollection which creates an Iterator to search for the
092: // element and calls Iterator.remove when it is found. This in turn
093: // calls remove(index) on us. Braindead but true!
094: int i = indexOf(o);
095: if (i < 0)
096: return false;
097: remove(i);
098: return true;
099: }
100:
101: public boolean addAll(Collection c) {
102: if (super .addAll(c)) {
103: makeDirty();
104: return true;
105: }
106: return false;
107: }
108:
109: public void clear() {
110: super .clear();
111: makeDirty();
112: }
113:
114: public boolean addAll(int index, Collection c) {
115: boolean result;
116: result = super .addAll(index, c);
117: if (result)
118: makeDirty();
119: return result;
120: }
121:
122: protected void removeRange(int fromIndex, int toIndex) {
123: super .removeRange(fromIndex, toIndex);
124: makeDirty();
125: }
126:
127: public boolean removeAll(Collection c) {
128: if (super .removeAll(c)) {
129: makeDirty();
130: return true;
131: }
132: return false;
133: }
134:
135: public boolean retainAll(Collection c) {
136: boolean modified = false;
137: Iterator e = super .iterator();
138: while (e.hasNext()) {
139: Object o = e.next();
140: if (!c.contains(o)) {
141: e.remove();
142: modified = true;
143: }
144: }
145: if (modified)
146: makeDirty();
147: return modified;
148: }
149:
150: public void makeDirty() {
151: if (stateManager != null && owner != null) {
152: stateManager.makeDirty(owner, fieldNo);
153: }
154: }
155:
156: public Iterator iterator() {
157: return new SCOIterator(super .iterator(), stateManager, owner,
158: fieldNo);
159: }
160:
161: public void makeTransient() {
162: owner = null;
163: stateManager = null;
164: }
165: }
|