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