001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005: package org.geoserver.wfsv;
006:
007: import net.opengis.wfsv.DifferenceQueryType;
008: import net.opengis.wfsv.GetDiffType;
009: import org.geoserver.wfs.WFS;
010: import org.geoserver.wfs.WFSException;
011: import org.geotools.data.FeatureSource;
012: import org.geotools.data.VersioningFeatureSource;
013: import org.geotools.data.postgis.FeatureDiffReader;
014: import org.geotools.feature.FeatureType;
015: import org.geotools.filter.expression.AbstractExpressionVisitor;
016: import org.geotools.filter.visitor.AbstractFilterVisitor;
017: import org.geotools.xml.EMFUtils;
018: import org.opengis.filter.Filter;
019: import org.opengis.filter.FilterFactory;
020: import org.opengis.filter.expression.ExpressionVisitor;
021: import org.opengis.filter.expression.PropertyName;
022: import org.vfny.geoserver.global.Data;
023: import org.vfny.geoserver.global.FeatureTypeInfo;
024: import java.io.IOException;
025: import java.util.ArrayList;
026: import java.util.List;
027: import java.util.logging.Logger;
028: import javax.xml.namespace.QName;
029:
030: /**
031: * Versioning Web Feature Service GetDiff operation
032: *
033: * @author Andrea Aime, TOPP
034: *
035: */
036: public class GetDiff {
037: /**
038: * logger
039: */
040: static Logger LOGGER = org.geotools.util.logging.Logging
041: .getLogger("org.geoserver.wfsv");
042:
043: /**
044: * WFS configuration
045: */
046: WFS wfs;
047:
048: /**
049: * The catalog
050: */
051: Data catalog;
052:
053: /**
054: * Filter factory
055: */
056: FilterFactory filterFactory;
057:
058: /**
059: * Creates the GetLog operation
060: *
061: * @param wfs
062: * @param catalog
063: */
064: public GetDiff(WFS wfs, Data catalog) {
065: this .wfs = wfs;
066: this .catalog = catalog;
067: }
068:
069: /**
070: * @return The reference to the GeoServer catalog.
071: */
072: public Data getCatalog() {
073: return catalog;
074: }
075:
076: /**
077: * @return The reference to the WFS configuration.
078: */
079: public WFS getWFS() {
080: return wfs;
081: }
082:
083: /**
084: * Sets the filter factory to use to create filters.
085: *
086: * @param filterFactory
087: */
088: public void setFilterFactory(FilterFactory filterFactory) {
089: this .filterFactory = filterFactory;
090: }
091:
092: public FeatureDiffReader[] run(GetDiffType request) {
093: List queries = request.getDifferenceQuery();
094:
095: // basic checks
096: if (queries.isEmpty()) {
097: throw new WFSException("No difference query specified");
098: }
099:
100: if (EMFUtils.isUnset(queries, "typeName")) {
101: String msg = "No feature types specified";
102: throw new WFSException(msg);
103: }
104:
105: // for each difference query check the feature type is versioned, and
106: // gather bounds
107: List result = new ArrayList(queries.size());
108:
109: try {
110: for (int i = 0; (i < queries.size()); i++) {
111: DifferenceQueryType query = (DifferenceQueryType) queries
112: .get(i);
113: FeatureTypeInfo meta = featureTypeInfo((QName) query
114: .getTypeName());
115: FeatureSource source = meta.getFeatureSource();
116:
117: if (!(source instanceof VersioningFeatureSource)) {
118: throw new WFSException("Feature type"
119: + query.getTypeName() + " is not versioned");
120: }
121:
122: Filter filter = (Filter) query.getFilter();
123:
124: // make sure filters are sane
125: if (filter != null) {
126: final FeatureType featureType = source.getSchema();
127: ExpressionVisitor visitor = new AbstractExpressionVisitor() {
128: public Object visit(PropertyName name,
129: Object data) {
130: // case of multiple geometries being returned
131: if (name.evaluate(featureType) == null) {
132: // we want to throw wfs exception, but cant
133: throw new WFSException(
134: "Illegal property name: "
135: + name
136: .getPropertyName(),
137: "InvalidParameterValue");
138: }
139:
140: return name;
141: };
142: };
143:
144: filter.accept(new AbstractFilterVisitor(visitor),
145: null);
146: }
147:
148: // extract collection
149: VersioningFeatureSource store = (VersioningFeatureSource) source;
150: FeatureDiffReader differences = store.getDifferences(
151: query.getFromFeatureVersion(), query
152: .getToFeatureVersion(), filter, null);
153:
154: // TODO: handle logs reprojection in another CRS
155: result.add(differences);
156: }
157: } catch (IOException e) {
158: throw new WFSException("Error occurred getting features",
159: e, request.getHandle());
160: }
161:
162: return (FeatureDiffReader[]) result
163: .toArray(new FeatureDiffReader[result.size()]);
164: }
165:
166: FeatureTypeInfo featureTypeInfo(QName name) throws WFSException,
167: IOException {
168: FeatureTypeInfo meta = catalog.getFeatureTypeInfo(name
169: .getLocalPart(), name.getNamespaceURI());
170:
171: if (meta == null) {
172: String msg = "Could not locate " + name + " in catalog.";
173: throw new WFSException(msg);
174: }
175:
176: return meta;
177: }
178: }
|