001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * If you wish your version of this file to be governed by only the CDDL
025: * or only the GPL Version 2, indicate your decision by adding
026: * "[Contributor] elects to include this software in this distribution
027: * under the [CDDL or GPL Version 2] license." If you do not indicate a
028: * single choice of license, a recipient has the option to distribute
029: * your version of this file under either the CDDL, the GPL Version 2 or
030: * to extend the choice of license to its licensees as provided above.
031: * However, if you add GPL Version 2 code and therefore, elected the GPL
032: * Version 2 license, then the option applies only if the new code is
033: * made subject to such option by the copyright holder.
034: *
035: * Contributor(s):
036: *
037: * Portions Copyrighted 2008 Sun Microsystems, Inc.
038: */
039:
040: package org.netbeans.modules.cnd.modelimpl.uid;
041:
042: import java.util.Collection;
043: import java.util.Iterator;
044: import org.netbeans.modules.cnd.api.model.CsmIdentifiable;
045: import org.netbeans.modules.cnd.api.model.CsmUID;
046:
047: /**
048: *
049: * @author Alexander Simon
050: */
051: public class LazyCsmCollection<T> implements Collection<T> {
052: private Collection<CsmUID<T>> uids;
053: boolean allowNullsAndSkip;
054:
055: public LazyCsmCollection(Collection<CsmUID<T>> uids,
056: boolean allowNullsAndSkip) {
057: this .uids = uids;
058: this .allowNullsAndSkip = allowNullsAndSkip;
059: }
060:
061: private T convertToObject(CsmUID uid) {
062: return (T) UIDCsmConverter.UIDtoCsmObject(uid);
063: }
064:
065: private CsmUID<T> convertToUID(T object) {
066: return ((CsmIdentifiable) object).getUID();
067: }
068:
069: public int size() {
070: return uids.size();
071: }
072:
073: public boolean isEmpty() {
074: return uids.isEmpty();
075: }
076:
077: public boolean contains(Object o) {
078: Iterator<T> it = iterator();
079: while (it.hasNext()) {
080: T object = it.next();
081: if (o == object || o != null && o.equals(object)) {
082: return true;
083: }
084: }
085: return false;
086: }
087:
088: public Iterator<T> iterator() {
089: return allowNullsAndSkip ? new MySafeIterator<T>()
090: : new MyIterator();
091: }
092:
093: public Object[] toArray() {
094: Object[] result = new Object[size()];
095: Iterator<T> e = iterator();
096: for (int i = 0; e.hasNext(); i++)
097: result[i] = e.next();
098: return result;
099: }
100:
101: public <T> T[] toArray(T[] a) {
102: int size = size();
103: if (a.length < size)
104: a = (T[]) java.lang.reflect.Array.newInstance(a.getClass()
105: .getComponentType(), size);
106:
107: Iterator<T> it = (Iterator<T>) iterator();
108: Object[] result = a;
109: for (int i = 0; i < size; i++)
110: result[i] = it.next();
111: if (a.length > size)
112: a[size] = null;
113: return a;
114: }
115:
116: public boolean add(T o) {
117: return uids.add(convertToUID(o));
118: }
119:
120: public boolean remove(Object o) {
121: return uids.remove(convertToUID((T) o));
122: }
123:
124: public boolean containsAll(Collection<?> c) {
125: Iterator<?> e = c.iterator();
126: while (e.hasNext())
127: if (!contains(e.next()))
128: return false;
129: return true;
130: }
131:
132: public boolean addAll(Collection<? extends T> c) {
133: boolean modified = false;
134: Iterator<? extends T> it = c.iterator();
135: while (it.hasNext()) {
136: if (add(it.next()))
137: modified = true;
138: }
139: return modified;
140: }
141:
142: public boolean removeAll(Collection<?> c) {
143: boolean modified = false;
144: Iterator<?> it = iterator();
145: while (it.hasNext()) {
146: if (c.contains(it.next())) {
147: it.remove();
148: modified = true;
149: }
150: }
151: return modified;
152: }
153:
154: public boolean retainAll(Collection<?> c) {
155: boolean modified = false;
156: Iterator<T> it = iterator();
157: while (it.hasNext()) {
158: if (!c.contains(it.next())) {
159: it.remove();
160: modified = true;
161: }
162: }
163: return modified;
164: }
165:
166: public void clear() {
167: uids.clear();
168: }
169:
170: @Override
171: public String toString() {
172: StringBuffer buf = new StringBuffer();
173: buf.append("["); // NOI18N
174:
175: Iterator<T> it = iterator();
176: boolean hasNext = it.hasNext();
177: while (hasNext) {
178: T o = it.next();
179: buf.append(o == this ? "(this Collection)" : String
180: .valueOf(o)); // NOI18N
181: hasNext = it.hasNext();
182: if (hasNext)
183: buf.append(", "); // NOI18N
184: }
185:
186: buf.append("]"); // NOI18N
187: return buf.toString();
188: }
189:
190: private class MyIterator<T> implements Iterator<T> {
191:
192: private Iterator it;
193:
194: private MyIterator() {
195: it = uids.iterator();
196: }
197:
198: public boolean hasNext() {
199: return it.hasNext();
200: }
201:
202: public T next() {
203: CsmUID uid = (CsmUID) it.next();
204: T decl = (T) convertToObject(uid);
205: assert decl != null : "no object for UID " + uid;
206: return decl;
207: }
208:
209: public void remove() {
210: it.remove();
211: }
212: }
213:
214: private class MySafeIterator<T> implements Iterator<T> {
215:
216: private Iterator it;
217: private T next;
218:
219: private MySafeIterator() {
220: it = uids.iterator();
221: next = getNextNonNull();
222: }
223:
224: public boolean hasNext() {
225: return next != null;
226: }
227:
228: private T getNextNonNull() {
229: T out = null;
230: while (out == null && it.hasNext()) {
231: CsmUID uid = (CsmUID) it.next();
232: out = (T) convertToObject(uid);
233: }
234: return out;
235: }
236:
237: public T next() {
238: T decl = next;
239: next = getNextNonNull();
240: return decl;
241: }
242:
243: public void remove() {
244: it.remove();
245: }
246: }
247: }
|