001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.feature.visitor;
017:
018: import java.util.ArrayList;
019: import java.util.HashSet;
020: import java.util.ListIterator;
021: import java.util.Set;
022:
023: import org.geotools.factory.CommonFactoryFinder;
024: import org.geotools.feature.Feature;
025: import org.geotools.feature.FeatureType;
026: import org.geotools.filter.IllegalFilterException;
027: import org.opengis.filter.FilterFactory;
028: import org.opengis.filter.expression.Expression;
029:
030: /**
031: * Generates a list of unique values from a collection
032: *
033: * @author Cory Horner, Refractions
034: *
035: * @since 2.2.M2
036: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/feature/visitor/UniqueVisitor.java $
037: */
038: public class UniqueVisitor implements FeatureCalc {
039: private Expression expr;
040: Set set = new HashSet();
041:
042: public UniqueVisitor(String attributeTypeName) {
043: FilterFactory factory = CommonFactoryFinder
044: .getFilterFactory(null);
045: expr = factory.property(attributeTypeName);
046: }
047:
048: public UniqueVisitor(int attributeTypeIndex, FeatureType type)
049: throws IllegalFilterException {
050: FilterFactory factory = CommonFactoryFinder
051: .getFilterFactory(null);
052: expr = factory.property(type.getAttributeType(
053: attributeTypeIndex).getName());
054: }
055:
056: public UniqueVisitor(String attrName, FeatureType type)
057: throws IllegalFilterException {
058: FilterFactory factory = CommonFactoryFinder
059: .getFilterFactory(null);
060: expr = factory.property(type.getAttributeType(attrName)
061: .getName());
062: }
063:
064: public UniqueVisitor(Expression expr) {
065: this .expr = expr;
066: }
067:
068: public void visit(Feature feature) {
069: //we ignore null attributes
070: Object value = expr.evaluate(feature);
071: if (value != null) {
072: set.add(value);
073: }
074: }
075:
076: public Expression getExpression() {
077: return expr;
078: }
079:
080: public Set getUnique() {
081: /**
082: * Return a list of unique values from the collection
083: */
084: return set;
085: }
086:
087: public void setValue(Object newSet) {
088: if (newSet instanceof ArrayList) { //convert to set
089: ArrayList newList = (ArrayList) newSet;
090: Set anotherSet = new HashSet();
091: for (ListIterator i = newList.listIterator(); i.hasNext();) {
092: anotherSet.add(i.next());
093: }
094: this .set = anotherSet;
095: } else {
096: this .set = (Set) newSet;
097: }
098: }
099:
100: public void reset() {
101: /**
102: * Reset the unique and current minimum for the features in the
103: * collection
104: */
105: this .set = new HashSet();
106: }
107:
108: public CalcResult getResult() {
109: if (set.size() < 1) {
110: return null;
111: }
112: return new UniqueResult(set);
113: }
114:
115: public static class UniqueResult extends AbstractCalcResult {
116: private Set unique;
117:
118: public UniqueResult(Set newSet) {
119: unique = newSet;
120: }
121:
122: public Object getValue() {
123: return new HashSet(unique);
124: }
125:
126: public boolean isCompatible(CalcResult targetResults) {
127: //list each calculation result which can merge with this type of result
128: if (targetResults instanceof UniqueResult)
129: return true;
130: return false;
131: }
132:
133: public CalcResult merge(CalcResult resultsToAdd) {
134: if (!isCompatible(resultsToAdd)) {
135: throw new IllegalArgumentException(
136: "Parameter is not a compatible type");
137: }
138:
139: if (resultsToAdd instanceof UniqueResult) {
140: //add one set to the other (to create one big unique list)
141: Set newSet = new HashSet(unique);
142: newSet.addAll((Set) resultsToAdd.getValue());
143: return new UniqueResult(newSet);
144: } else {
145: throw new IllegalArgumentException(
146: "The CalcResults claim to be compatible, but the appropriate merge method has not been implemented.");
147: }
148: }
149: }
150: }
|