001: /* uDig - User Friendly Desktop Internet GIS client
002: * http://udig.refractions.net
003: * (C) 2004, Refractions Research Inc.
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation;
008: * version 2.1 of the License.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: */
015: package net.refractions.udig.ui;
016:
017: import java.util.Collection;
018: import java.util.HashSet;
019: import java.util.Iterator;
020: import java.util.LinkedList;
021: import java.util.List;
022: import java.util.NoSuchElementException;
023: import java.util.Set;
024:
025: import net.refractions.udig.core.IProvider;
026:
027: import org.eclipse.jface.viewers.IStructuredSelection;
028: import org.geotools.feature.Feature;
029:
030: /**
031: * A selection that uses a set of fids to indicate the selection in the collection of features. The actual selection
032: * is the features indicated by the fids.
033: * @author Jesse
034: * @since 1.1.0
035: */
036: public class FidSelection implements IStructuredSelection {
037:
038: private final Set<String> fids;
039: private final IProvider<Collection<Feature>> provider;
040: private volatile Feature firstElement;
041: private volatile LinkedList<Feature> list;
042: private volatile Object[] array;
043:
044: /**
045: * New Instance.
046: * @param fids
047: * @param provider
048: */
049: public FidSelection(Set<String> fids,
050: IProvider<Collection<Feature>> provider) {
051: this .fids = new HashSet<String>(fids);
052: this .provider = provider;
053: }
054:
055: public Object getFirstElement() {
056: if (isEmpty())
057: throw new NoSuchElementException("Selection is empty."); //$NON-NLS-1$
058:
059: return doFirstElement();
060: }
061:
062: private Object doFirstElement() {
063: if (firstElement == null) {
064: synchronized (this ) {
065: if (firstElement == null) {
066: for (Feature feature : provider.get()) {
067: if (fids.contains(feature.getID())) {
068: firstElement = feature;
069: break;
070: }
071: }
072: }
073:
074: }
075: }
076: return firstElement;
077: }
078:
079: public Iterator iterator() {
080: final HashSet<String> fids = new HashSet<String>(this .fids);
081: final Iterator<Feature> featureIter = this .provider.get()
082: .iterator();
083:
084: return new Iterator() {
085: private Feature next;
086: private Feature live;
087:
088: public boolean hasNext() {
089: if (next != null)
090: return true;
091:
092: while (featureIter.hasNext() && !fids.isEmpty()
093: && next == null) {
094: Feature current = featureIter.next();
095: if (fids.remove(current.getID())) {
096: next = current;
097: }
098: }
099:
100: return next != null;
101: }
102:
103: public Object next() {
104: if (!hasNext()) {
105: throw new NoSuchElementException(
106: "No more elements in iterator"); //$NON-NLS-1$
107: }
108: live = next;
109: next = null;
110: return live;
111: }
112:
113: public void remove() {
114: FidSelection.this .fids.remove(live.getID());
115: }
116:
117: };
118: }
119:
120: public int size() {
121: return toList().size();
122: }
123:
124: public Object[] toArray() {
125: if (array == null) {
126: synchronized (this ) {
127: if (array == null) {
128: array = toList().toArray();
129: }
130: }
131: }
132: return array;
133: }
134:
135: public List toList() {
136: if (list == null) {
137: synchronized (this ) {
138: if (list == null) {
139: list = new LinkedList<Feature>();
140: Iterator iter = iterator();
141: while (iter.hasNext()) {
142: list.add((Feature) iter.next());
143: }
144: }
145: }
146: }
147:
148: return list;
149: }
150:
151: public boolean isEmpty() {
152: return doFirstElement() == null;
153: }
154:
155: }
|