001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-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; either
009: * version 2.1 of the License, or (at your option) any later version.
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.wfs;
017:
018: import java.io.IOException;
019: import java.io.InputStream;
020: import java.net.HttpURLConnection;
021: import java.net.MalformedURLException;
022: import java.net.URI;
023: import java.util.ArrayList;
024: import java.util.HashMap;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.NoSuchElementException;
029:
030: import org.geotools.data.FeatureReader;
031: import org.geotools.data.wfs.Action.InsertAction;
032: import org.geotools.data.wfs.Action.UpdateAction;
033: import org.geotools.feature.Feature;
034: import org.geotools.feature.FeatureType;
035: import org.geotools.feature.IllegalAttributeException;
036: import org.geotools.xml.DocumentFactory;
037: import org.geotools.xml.XMLHandlerHints;
038: import org.geotools.xml.gml.FCBuffer;
039: import org.xml.sax.SAXException;
040:
041: /**
042: * <p>
043: * DOCUMENT ME!
044: * </p>
045: *
046: * @author dzwiers
047: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/plugin/wfs/src/main/java/org/geotools/data/wfs/WFSFeatureReader.java $
048: */
049: public class WFSFeatureReader extends FCBuffer {
050: private InputStream is = null;
051: private WFSTransactionState ts = null;
052: private Feature next = null;
053: private int insertSearchIndex = -1;
054:
055: private WFSFeatureReader(InputStream is, int capacity, int timeout,
056: WFSTransactionState trans, WFSFeatureType ft) {
057: //document may be null
058: super (null, capacity, timeout, ft);
059: this .is = is;
060: ts = trans;
061: }
062:
063: /**
064: *
065: * @param document
066: * @param capacity
067: * @param timeout
068: * @param transaction
069: * @param ft
070: * @return WFSFeatureReader
071: * @throws SAXException
072: */
073: public static FeatureReader getFeatureReader(URI document,
074: int capacity, int timeout, WFSTransactionState transaction,
075: WFSFeatureType ft) throws SAXException {
076: HttpURLConnection hc;
077:
078: try {
079: hc = (HttpURLConnection) document.toURL().openConnection();
080:
081: return getFeatureReader(hc.getInputStream(), capacity,
082: timeout, transaction, ft);
083: } catch (MalformedURLException e) {
084: logger.warning(e.toString());
085: throw new SAXException(e);
086: } catch (IOException e) {
087: logger.warning(e.toString());
088: throw new SAXException(e);
089: }
090: }
091:
092: /**
093: *
094: * @param is
095: * @param capacity
096: * @param timeout
097: * @param transaction
098: * @param ft
099: * @return WFSFeatureReader
100: * @throws SAXException
101: */
102: public static WFSFeatureReader getFeatureReader(InputStream is,
103: int capacity, int timeout, WFSTransactionState transaction,
104: WFSFeatureType ft) throws SAXException {
105: WFSFeatureReader fc = new WFSFeatureReader(is, capacity,
106: timeout, transaction, ft);
107: fc.start(); // calls run
108:
109: if (fc.exception != null) {
110: throw fc.exception;
111: }
112:
113: return fc;
114: }
115:
116: /**
117: * @see java.lang.Runnable#run()
118: */
119: public void run() {
120: XMLHandlerHints hints = new XMLHandlerHints();
121: initHints(hints);
122:
123: try {
124: try {
125: DocumentFactory.getInstance(is, hints, logger
126: .getLevel());
127: is.close();
128:
129: // start parsing until buffer part full, then yield();
130: } catch (StopException e) {
131: exception = e;
132: state = STOP;
133: is.close();
134: yield();
135: } catch (SAXException e) {
136: exception = e;
137: state = STOP;
138: is.close();
139: yield();
140: } catch (RuntimeException e) {
141: exception = new SAXException(e.getMessage());
142: exception.initCause(e);
143: state = STOP;
144: is.close();
145: yield();
146: }
147: } catch (IOException e) {
148: logger.warning(e.toString());
149: }
150: }
151:
152: protected void initHints(XMLHandlerHints hints) {
153: super .initHints(hints);
154:
155: if (ft instanceof WFSFeatureType) {
156: Map schemas = new HashMap(1);
157: WFSFeatureType wfsFT = (WFSFeatureType) ft;
158: schemas.put(wfsFT.getNamespace().toString(), wfsFT
159: .getSchemaURI());
160: hints.put(XMLHandlerHints.NAMESPACE_MAPPING, schemas);
161: }
162: }
163:
164: /**
165: *
166: * @see org.geotools.data.FeatureReader#hasNext()
167: */
168: public boolean hasNext() throws IOException {
169: if (next != null) {
170: return true;
171: }
172:
173: try {
174: loadElement();
175: } catch (NoSuchElementException e) {
176: return false;
177: }
178:
179: return next != null;
180: }
181:
182: private boolean loadElement() throws NoSuchElementException,
183: IOException {
184: if (ts == null) {
185: while ((next == null) && super .hasNext())
186: next = super .next();
187: } else {
188: List l = ts.getActions(ft.getTypeName());
189:
190: if ((insertSearchIndex < l.size()) && (next == null)) {
191: // look for an insert then
192: // advance one spot
193:
194: while ((insertSearchIndex + 1 < l.size())
195: && (next == null)) {
196: insertSearchIndex++;
197: Action a = (Action) l.get(insertSearchIndex);
198: if (a.getType() == Action.INSERT) {
199: InsertAction ia = (InsertAction) a;
200: next = ia.getFeature();
201:
202: //run thorough the rest to look for deletes / mods
203: int i = insertSearchIndex + 1;
204:
205: while ((i < l.size()) && (next != null)) {
206: a = (Action) l.get(i);
207: next = updateFeature(a, next);
208: i++;
209: }
210: }
211: }
212: }
213:
214: while ((next == null) && super .hasNext()) {
215: next = super .next();
216:
217: if ((ts != null) && (next != null)) {
218: // check to make sure it wasn't deleted
219: // check for updates
220: Iterator i = l.iterator();
221:
222: while (i.hasNext() && (next != null)) {
223: Action a = (Action) i.next();
224:
225: next = updateFeature(a, next);
226: }
227: }
228: }
229:
230: }
231:
232: return next != null;
233: }
234:
235: private Feature updateFeature(Action a, Feature feature) {
236: if ((a.getType() == Action.DELETE)
237: && a.getFilter().evaluate(feature)) {
238: return null;
239: } else {
240: if ((a.getType() == Action.UPDATE)
241: && a.getFilter().evaluate(feature)) {
242: // update the feature
243: UpdateAction ua = (UpdateAction) a;
244: ua.update(feature);
245: }
246: }
247: return feature;
248: }
249:
250: /**
251: * @see org.geotools.data.FeatureReader#next()
252: */
253: public Feature next() throws IOException, NoSuchElementException {
254: if (next == null) {
255: loadElement(); // load it
256:
257: if (next == null) {
258: throw new NoSuchElementException();
259: }
260: }
261:
262: Feature r = next;
263: next = null;
264:
265: return r;
266: }
267:
268: }
|