001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-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.data.postgis;
017:
018: import java.io.IOException;
019: import java.util.Iterator;
020: import java.util.Set;
021: import java.util.logging.Level;
022: import java.util.logging.Logger;
023:
024: import org.geotools.data.postgis.fidmapper.VersionedFIDMapper;
025: import org.geotools.feature.FeatureType;
026: import org.geotools.filter.CompareFilter;
027: import org.geotools.filter.FidFilter;
028: import org.geotools.filter.Filter;
029: import org.geotools.filter.FilterFactory;
030: import org.geotools.filter.visitor.DuplicatorFilterVisitor;
031:
032: /**
033: * Takes a filter that eventually contains a fid filter and builds a new filter that does not have
034: * it, and relies on attributes instead. This assumes pk attributes are part of the feature type.
035: * <br>
036: * This cloning is necessary because public FID do not contain the revision attribute, that will be
037: * handled by including new filters.
038: *
039: * @author aaime
040: * @since 2.4
041: *
042: */
043: class FidTransformeVisitor extends DuplicatorFilterVisitor {
044: /** The logger for the postgis module. */
045: protected static final Logger LOGGER = org.geotools.util.logging.Logging
046: .getLogger("org.geotools.data.postgis");
047:
048: private VersionedFIDMapper mapper;
049:
050: private Object featureType;
051:
052: public FidTransformeVisitor(FilterFactory factory,
053: FeatureType featureType, VersionedFIDMapper mapper) {
054: super (factory);
055: this .mapper = mapper;
056: this .featureType = featureType;
057: }
058:
059: public void visit(FidFilter filter) {
060: Set ids = filter.getIDs();
061: if (ids.isEmpty()) {
062: throw new IllegalArgumentException(
063: "Invalid fid filter provides, has no fids inside");
064: }
065: Filter external = null;
066: for (Iterator it = ids.iterator(); it.hasNext();) {
067: String id = (String) it.next();
068: Object[] attributes;
069: try {
070: attributes = mapper.getUnversionedPKAttributes(id);
071: } catch (IOException e) {
072: // assume the fid provided is not in the format the mapper can handle, so
073: // it's not really a real datastore fid but has been provided by the user.
074: // No harm dome, we just need to skip it
075: if (LOGGER.isLoggable(Level.FINE))
076: LOGGER.fine("Skipping fid " + id
077: + " since it's not in the "
078: + "proper format for this datastore"
079: + e.getMessage());
080: continue;
081: }
082: Filter idf = null;
083: for (int i = 0, j = 0; i < attributes.length; j++) {
084: String colName = mapper.getColumnName(j);
085: if ("revision".equals(colName))
086: continue;
087: CompareFilter equal = ff
088: .createCompareFilter(Filter.COMPARE_EQUALS);
089: equal.addLeftValue(ff
090: .createAttributeExpression(colName));
091: equal.addRightValue(ff
092: .createLiteralExpression(attributes[i]));
093: if (idf == null)
094: idf = equal;
095: else
096: idf = idf.and(equal);
097: i++;
098: }
099: if (external == null)
100: external = idf;
101: else
102: external = external.or(idf);
103: }
104: // if all the fids are in an improper format, the fid filter is equivalent to
105: // a Filter that excludes everything... Since I cannot use Filter.EXCLUDE (it breaks
106: // the filter splitter with a class cast exception) I'm falling back on the old
107: // "1 = 0" filter (ugly, but works...)
108: if (external == null) {
109: CompareFilter equal = ff
110: .createCompareFilter(Filter.COMPARE_EQUALS);
111: equal.addLeftValue(ff.createLiteralExpression(0));
112: equal.addRightValue(ff.createLiteralExpression(1));
113: pages.push(equal);
114: } else
115: pages.push(external);
116: }
117:
118: }
|