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: import com.versant.core.jdo.sco.SCOListIterator;
018: import com.versant.core.jdo.VersantStateManager;
019:
020: import javax.jdo.spi.PersistenceCapable;
021: import java.io.Serializable;
022: import java.util.Collection;
023: import java.util.Iterator;
024: import java.util.ListIterator;
025: import java.util.Vector;
026:
027: import com.versant.core.common.BindingSupportImpl;
028:
029: /**
030: * A Detached SCO implementation of a Vector.
031: */
032: public final class DetachSCOVector extends Vector implements
033: Serializable, VersantSimpleSCO {
034:
035: private PersistenceCapable owner;
036: private int fierldNo;
037: private VersantStateManager stateManager;
038:
039: public DetachSCOVector(PersistenceCapable owner,
040: VersantStateManager stateManager, VersantFieldMetaData fmd,
041: Object[] originalData) {
042: this .owner = owner;
043: this .fierldNo = fmd.getManagedFieldNo();
044: this .stateManager = stateManager;
045: int n = originalData == null ? 0 : originalData.length;
046: if (n > 0)
047: ensureCapacity(n);
048: if (!owner.jdoIsNew()) {
049: for (int i = 0; i < n; i++) {
050: Object o = originalData[i];
051: if (o == null)
052: break;
053: super .add(o);
054: }
055: } else {
056: for (int i = 0; i < n; i++) {
057: Object o = originalData[i];
058: if (o == null)
059: throw createNPE();
060: super .add(o);
061: }
062: }
063: }
064:
065: private RuntimeException createNPE() {
066: return BindingSupportImpl.getInstance().nullElement(
067: "Null element not allowed.");
068: }
069:
070: public synchronized void setSize(int newSize) {
071: if (newSize > elementCount) {
072: throw BindingSupportImpl.getInstance().nullElement(
073: "setSize called with " + newSize + " > "
074: + elementCount + " and "
075: + "null elements are not allowed.");
076: }
077: super .setSize(newSize);
078: makeDirty();
079: }
080:
081: public synchronized void setElementAt(Object obj, int index) {
082: if (obj == null)
083: throw createNPE();
084: super .setElementAt(obj, index);
085: makeDirty();
086: }
087:
088: public synchronized void removeElementAt(int index) {
089: super .removeElementAt(index);
090: makeDirty();
091: }
092:
093: public synchronized void insertElementAt(Object obj, int index) {
094: if (obj == null)
095: throw createNPE();
096: makeDirty();
097: super .insertElementAt(obj, index);
098: }
099:
100: public synchronized void addElement(Object obj) {
101: if (obj == null)
102: throw createNPE();
103: super .addElement(obj);
104: makeDirty();
105: }
106:
107: public synchronized void removeAllElements() {
108: modCount++;
109: // Let gc do its work
110: for (int i = 0; i < elementCount; i++) {
111: elementData[i] = null;
112: }
113: elementCount = 0;
114: makeDirty();
115: }
116:
117: public synchronized Object set(int index, Object element) {
118: if (element == null)
119: throw createNPE();
120: Object obj = super .set(index, element);
121: makeDirty();
122: return obj;
123: }
124:
125: public synchronized boolean add(Object o) {
126: if (o == null)
127: throw createNPE();
128: super .add(o);
129: makeDirty();
130: return true;
131: }
132:
133: public synchronized Object remove(int index) {
134: Object obj = super .remove(index);
135: makeDirty();
136: return obj;
137: }
138:
139: public synchronized boolean addAll(Collection c) {
140: if (super .addAll(c)) {
141: makeDirty();
142: return true;
143: }
144: return false;
145: }
146:
147: public synchronized boolean removeAll(Collection c) {
148: boolean modified = false;
149: Iterator e = super .iterator();
150: Object o = null;
151: while (e.hasNext()) {
152: o = e.next();
153: if (c.contains(o)) {
154: e.remove();
155: modified = true;
156: }
157: }
158: if (modified)
159: makeDirty();
160: return modified;
161: }
162:
163: public synchronized boolean retainAll(Collection c) {
164: boolean modified = false;
165: Iterator e = super .iterator();
166: Object o = null;
167: while (e.hasNext()) {
168: o = e.next();
169: if (!c.contains(o)) {
170: e.remove();
171: modified = true;
172: }
173: }
174: if (modified) {
175: makeDirty();
176: }
177: return modified;
178: }
179:
180: public synchronized boolean addAll(int index, Collection c) {
181: if (super .addAll(index, c)) {
182: makeDirty();
183: return true;
184: }
185: return false;
186: }
187:
188: protected void removeRange(int fromIndex, int toIndex) {
189: super .removeRange(fromIndex, toIndex);
190: makeDirty();
191: }
192:
193: public ListIterator listIterator() {
194: return new SCOListIterator(super .listIterator(), stateManager,
195: owner, fierldNo);
196: }
197:
198: public ListIterator listIterator(int index) {
199: return new SCOListIterator(super .listIterator(index),
200: stateManager, owner, fierldNo);
201: }
202:
203: public Iterator iterator() {
204: return new SCOIterator(super .iterator(), stateManager, owner,
205: fierldNo);
206: }
207:
208: private void makeDirty() {
209: if (stateManager != null && owner != null) {
210: stateManager.makeDirty(owner, fierldNo);
211: }
212: }
213:
214: public void makeTransient() {
215: owner = null;
216: stateManager = null;
217: }
218: }
|