001: /*
002:
003: This software is OSI Certified Open Source Software.
004: OSI Certified is a certification mark of the Open Source Initiative.
005:
006: The license (Mozilla version 1.0) can be read at the MMBase site.
007: See http://www.MMBase.org/license
008:
009: */
010:
011: package org.mmbase.bridge.implementation;
012:
013: import org.mmbase.bridge.*;
014: import java.util.*;
015: import org.mmbase.util.logging.*;
016:
017: /**
018: * A list of objects.
019: * This is the base class for all basic implementations of the bridge lists.
020: *
021: * @author Pierre van Rooden
022: * @version $Id: BasicList.java,v 1.31 2008/02/27 11:47:26 michiel Exp $
023: */
024: public class BasicList<E extends Comparable<? super E>> extends
025: ArrayList<E> implements BridgeList<E> {
026:
027: private static final Logger log = Logging
028: .getLoggerInstance(BasicList.class);
029:
030: private Map<Object, Object> properties = new HashMap<Object, Object>();
031:
032: // during inititializion of the list, you sometimes want to switch off
033: // also when everything is certainly converted
034: boolean autoConvert = true;
035:
036: BasicList() {
037: super ();
038: }
039:
040: protected BasicList(Collection c) {
041: super (c);
042: }
043:
044: public Object getProperty(Object key) {
045: return properties.get(key);
046: }
047:
048: public void setProperty(Object key, Object value) {
049: properties.put(key, value);
050: }
051:
052: /**
053: * converts the object in the list to the excpected format
054: */
055: @SuppressWarnings("unchecked")
056: protected E convert(Object o) {
057: return (E) o;
058: }
059:
060: protected final E convert(Object o, int index) {
061: E newO;
062: try {
063: newO = convert(o);
064: if (log.isDebugEnabled()) {
065: log.debug("Converted " + o.getClass() + " to "
066: + newO.getClass() + " in " + getClass());
067: }
068: } catch (Throwable t) {
069: log.warn(t);
070: newO = null;
071: }
072: if (newO != o) {
073: set(index, newO);
074: }
075: return newO;
076: }
077:
078: @Override
079: public boolean contains(Object o) {
080: // make sure every element is of the right type, ArrayList implementation does _not_ call get.
081: convertAll();
082: return super .contains(o);
083: }
084:
085: @Override
086: public boolean remove(Object o) {
087: // make sure every element is of the right type, otherwise 'equals' is very odd..
088: convertAll();
089: return super .remove(o);
090: }
091:
092: @Override
093: public boolean removeAll(Collection<?> c) {
094: // make sure every element is of the right type, otherwise 'equals' is very odd..
095: convertAll();
096: return super .removeAll(c);
097: }
098:
099: @Override
100: public E get(int index) {
101: if (autoConvert) {
102: return convert(super .get(index), index);
103: } else {
104: return super .get(index);
105: }
106: }
107:
108: public void sort() {
109: Collections.sort(this );
110: }
111:
112: public void sort(Comparator<? super E> comparator) {
113: Collections.sort(this , comparator);
114: }
115:
116: @Override
117: public void add(int index, E o) {
118: autoConvert = true;
119: super .add(index, o);
120: }
121:
122: @Override
123: public boolean add(E o) {
124: autoConvert = true;
125: return super .add(o);
126: }
127:
128: /**
129: * @since MMBase-1.6.2
130: */
131: protected void convertAll() {
132: log.debug("convert all");
133: for (int i = 0; i < size(); i++) {
134: convert(super .get(i), i);
135: }
136: autoConvert = false;
137: }
138:
139: @Override
140: public Object[] toArray() { // needed when you e.g. want to sort the list.
141: // make sure every element is of the right type, otherwise sorting can happen on the wrong type.
142: if (autoConvert)
143: convertAll();
144: return super .toArray();
145: }
146:
147: public BridgeList<E> subList(int fromIndex, int toIndex) {
148: return new BasicList<E>(super .subList(fromIndex, toIndex));
149: }
150:
151: protected class BasicIterator implements ListIterator<E> {
152: protected ListIterator<E> iterator;
153:
154: protected BasicIterator() {
155: this .iterator = BasicList.this .listIterator();
156: }
157:
158: public boolean hasNext() {
159: return iterator.hasNext();
160: }
161:
162: public boolean hasPrevious() {
163: return iterator.hasPrevious();
164: }
165:
166: public int nextIndex() {
167: return iterator.nextIndex();
168: }
169:
170: public int previousIndex() {
171: return iterator.previousIndex();
172: }
173:
174: public void remove() {
175: iterator.remove();
176: }
177:
178: // These have to be implemented with a check if o is of the right type.
179: public void set(E o) {
180: iterator.set(o);
181: }
182:
183: public void add(E o) {
184: BasicList.this .autoConvert = true;
185: iterator.add(o);
186: }
187:
188: public E next() {
189: E next = iterator.next();
190: int i = nextIndex();
191: return BasicList.this .convert(next, i);
192: }
193:
194: public E previous() {
195: E previous = iterator.previous();
196: int i = previousIndex();
197: return BasicList.this.convert(previous, i);
198: }
199:
200: }
201:
202: }
|