001: /**
002: * Copyright (C) 2001-2004 France Telecom R&D
003: *
004: * This library is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This library is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: */package org.objectweb.speedo.genclass.collection;
018:
019: import org.objectweb.jorm.api.PException;
020: import org.objectweb.jorm.api.PExceptionIO;
021: import org.objectweb.jorm.api.PIndexedElem;
022: import org.objectweb.speedo.api.Debug;
023: import org.objectweb.speedo.genclass.AbstractGenClassHome;
024: import org.objectweb.speedo.genclass.GenClassAccessor;
025: import org.objectweb.speedo.genclass.GenClassElement;
026: import org.objectweb.speedo.genclass.api.SpeedoGenClassPO;
027: import org.objectweb.speedo.mim.api.PersistentObjectItf;
028: import org.objectweb.speedo.mim.api.StateItf;
029: import org.objectweb.speedo.pm.api.POManagerItf;
030: import org.objectweb.util.monolog.api.BasicLevel;
031:
032: import java.util.Collection;
033: import java.util.Iterator;
034: import java.util.List;
035: import java.util.ListIterator;
036: import java.util.Map;
037:
038: /**
039: *
040: * @author S.Chassande-Barrioz
041: */
042: public class ListAccessor extends CollectionAccessor implements List {
043: /**
044: * Indicates the number of elements existing on the data support. All
045: * element added after this index must be marked as CREATED.
046: */
047: protected int loadedSize = -1;
048:
049: public ListAccessor(SpeedoGenClassPO thepo) {
050: super (thepo);
051: }
052:
053: public void workingSetClosed() {
054: super .workingSetClosed();
055: //Update the loaded size after the data support flushing
056: loadedSize = elements.size();
057: }
058:
059: public String toString() {
060: return "ListAccessor: id=" + gcpo.speedoGetGenClassId();
061: }
062:
063: public PIndexedElem createPIndexedElem(GenClassAccessor gca) {
064: return new ListElem(gca);
065: }
066:
067: public void paSetNbElem(int nbelem) {
068: super .paSetNbElem(nbelem);
069: loadedSize = 0;
070: }
071:
072: public void paAdd(PIndexedElem elem, Object conn)
073: throws PExceptionIO {
074: super .paAdd(elem, conn);
075: loadedSize++;
076: //order the elements list
077: try {
078: //get the real index of the last element added
079: int index = elem
080: .pieGetIntIndexField(CollectionElem.INDEX_FIELD_NAME);
081: boolean sorted = false;
082: //bubble sort
083: for (int i = elements.size() - 1; i > 0 && !sorted; i--) {
084: int currentIndex = ((PIndexedElem) elements.get(i - 1))
085: .pieGetIntIndexField(CollectionElem.INDEX_FIELD_NAME);
086: if (index < currentIndex) {
087: //swap between i and i-1
088: elements.set(i, elements
089: .set(i - 1, elements.get(i)));
090: } else {
091: sorted = true;
092: }
093: }
094: } catch (PException e) {
095: throw new PExceptionIO(e,
096: "Unable to get the index of PIndexedElem at the ListAccessor level.");
097: }
098: }
099:
100: public boolean add(Object o) {
101: if (super .add(o)) {
102: int idx = elements.size() - 1;
103: ListElem le = (ListElem) elements.get(idx);
104: le.setIndex(new Integer(idx));
105: return true;
106: } else {
107: return false;
108: }
109: }
110:
111: public boolean addAll(int i, Collection c) {
112: if (c == null) {
113: return false;
114: }
115: int size = elements.size();
116: if (size > i) {
117: Iterator it = c.iterator();
118: int j = i;
119: while (it.hasNext()) {
120: add(j, it.next());
121: j++;
122: }
123: return true;
124: } else {
125: throw new IndexOutOfBoundsException(
126: "Try to insert at the position " + i
127: + " whereas there is only " + size
128: + " elements.");
129: }
130: }
131:
132: public Object get(int i) {
133: ListElem le = (ListElem) elements.get(i);
134: if (le.getElemStatus() == PIndexedElem.ELEM_DELETED) {
135: throw new java.lang.ArrayIndexOutOfBoundsException(i);
136: }
137: return le.getElement();
138: }
139:
140: public Object set(int i, Object o) {
141: ListElem le = (ListElem) elements.get(i);
142: if (le.getElemStatus() == PIndexedElem.ELEM_DELETED) {
143: throw new java.lang.ArrayIndexOutOfBoundsException(i);
144: }
145: Object res = le.getElement();
146: le.setStatus(PIndexedElem.ELEM_MODIFIED);
147: le.setElement(o);
148: return res;
149: }
150:
151: public void add(int i, Object o) {
152: int size = elements.size();
153: if (size > i) {
154: Object toAdd = o;
155: Object tmp = o;
156: int j = i;
157: ListElem le;
158: //insert the new and shift others
159: while (j < size) {
160: le = (ListElem) elements.get(j);
161: tmp = le.element;
162: le.element = toAdd;
163: le
164: .setStatus((j < loadedSize ? PIndexedElem.ELEM_MODIFIED
165: : PIndexedElem.ELEM_CREATED));
166: toAdd = tmp;
167: j++;
168: }
169: //create a new entry for the shifted element (or the added if i = size)
170: le = (ListElem) createPIndexedElem();
171: le.setStatus((j < loadedSize ? PIndexedElem.ELEM_MODIFIED
172: : PIndexedElem.ELEM_CREATED));
173: le.setIndex(new Integer(size));
174: elements.add(le);
175: } else {
176: throw new IndexOutOfBoundsException(
177: "Try to insert at the position " + i
178: + " whereas there is only " + size
179: + " elements.");
180: }
181: }
182:
183: public Object remove(int i) {
184: return null;
185: }
186:
187: public int indexOf(Object o) {
188: return 0;
189: }
190:
191: public int lastIndexOf(Object o) {
192: return 0;
193: }
194:
195: public ListIterator listIterator() {
196: return null;
197: }
198:
199: public ListIterator listIterator(int i) {
200: return null;
201: }
202:
203: public List subList(int i, int i1) {
204: return null;
205: }
206:
207: public void attachCopy(POManagerItf pm, Map map,
208: StateItf fieldsClone) {
209: CollectionAccessor ca = (CollectionAccessor) fieldsClone;
210: //get an iterator on the PIndexed elements of the collection
211: Iterator it = ca.collection.iterator();
212: int index = 0;
213: while (it.hasNext()) {
214: Object elem = it.next();
215: //if it is a persistent object
216: if (elem instanceof PersistentObjectItf) {
217: //get the detached speedo po
218: PersistentObjectItf spDetached = (PersistentObjectItf) elem;
219: PersistentObjectItf sp = (PersistentObjectItf) map
220: .get(spDetached);
221: if (sp == null) {
222: map.put(spDetached, sp);
223: sp = (PersistentObjectItf) pm.speedoAttachCopy(
224: spDetached, map);
225: }
226: //put the element of the collection attribute in the elements attribute (the opposite of the jdoDetachCopy method)
227: speedoAddOnAttach(sp, index++);
228: } else {
229: //just add the java object in the collection
230: speedoAddOnAttach(elem, index++);
231: }
232: }
233: }
234:
235: protected GenClassElement speedoAddOnAttach(Object o, int index) {
236: if (o instanceof PersistentObjectItf
237: && !((PersistentObjectItf) o).speedoIsActive()) {
238: ((AbstractGenClassHome) getSpeedoPO().speedoGetHome())
239: .makePersistent(null, (PersistentObjectItf) o,
240: (SpeedoGenClassPO) getSpeedoPO(), null);
241: }
242: synchronized (this ) {
243: if (contains(o, index)) {
244: return null;
245: }
246: // Put it in the "elements" list
247: GenClassElement element = (GenClassElement) createPIndexedElem();
248: element.setElement(o);
249: return (elements.add(element) ? element : null);
250: }
251: }
252:
253: public boolean contains(Object o, int index) {
254: tmpelem.setElement(o);
255: tmpelem.setIndex(new Integer(index));
256: Iterator it = elements.iterator();
257: while (it.hasNext()) {
258: PIndexedElem e = (PIndexedElem) it.next();
259: if (e.equals(tmpelem)
260: && e.getElemStatus() != PIndexedElem.ELEM_DELETED) {
261: if (Debug.ON && getLogger() != null) {
262: logger.log(BasicLevel.DEBUG, "contains(): yes");
263: }
264: return true;
265: }
266: }
267: if (Debug.ON && getLogger() != null) {
268: logger.log(BasicLevel.DEBUG, "contains(): no");
269: }
270: return false;
271: }
272:
273: }
|