/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2004-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.data.wfs.v1_0_0; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; import org.geotools.data.FeatureReader; import org.geotools.data.wfs.v1_0_0.Action.InsertAction; import org.geotools.data.wfs.v1_0_0.Action.UpdateAction; import org.geotools.xml.DocumentFactory; import org.geotools.xml.XMLHandlerHints; import org.geotools.xml.gml.FCBuffer; import org.opengis.feature.simple.SimpleFeature; import org.opengis.feature.simple.SimpleFeatureType; import org.xml.sax.SAXException; /** * <p> * DOCUMENT ME! * </p> * * @author dzwiers * * * @source $URL$ */ public class WFSFeatureReader extends FCBuffer { private InputStream is = null; private WFSTransactionState ts = null; private SimpleFeature next = null; private int insertSearchIndex = -1; private WFSFeatureReader(InputStream is, int capacity, int timeout, WFSTransactionState trans, SimpleFeatureType ft) { //document may be null super(null, capacity, timeout,ft); this.is = is; ts = trans; } /** * * @param document * @param capacity * @param timeout * @param transaction * @param ft * @return WFSFeatureReader * @throws SAXException */ public static FeatureReader<SimpleFeatureType, SimpleFeature> getFeatureReader(URI document, int capacity, int timeout, WFSTransactionState transaction, SimpleFeatureType ft) throws SAXException { HttpURLConnection hc; try { hc = (HttpURLConnection) document.toURL().openConnection(); return getFeatureReader(hc.getInputStream(), capacity, timeout, transaction, ft); } catch (MalformedURLException e) { logger.warning(e.toString()); throw new SAXException(e); } catch (IOException e) { logger.warning(e.toString()); throw new SAXException(e); } } /** * * @param is * @param capacity * @param timeout * @param transaction * @param ft * @return WFSFeatureReader * @throws SAXException */ public static WFSFeatureReader getFeatureReader(InputStream is, int capacity, int timeout, WFSTransactionState transaction, SimpleFeatureType ft) throws SAXException { WFSFeatureReader fc = new WFSFeatureReader(is, capacity, timeout, transaction, ft); fc.start(); // calls run if (fc.exception != null) { throw fc.exception; } return fc; } /** * @see java.lang.Runnable#run() */ public void run() { XMLHandlerHints hints = new XMLHandlerHints(); initHints(hints); try { try { DocumentFactory.getInstance(is, hints, logger.getLevel()); is.close(); // start parsing until buffer part full, then yield(); } catch (StopException e) { exception = e; state = STOP; is.close(); yield(); } catch (SAXException e) { exception = e; state = STOP; is.close(); yield(); } catch (RuntimeException e) { exception = new SAXException(e.getMessage()); exception.initCause(e); state = STOP; is.close(); yield(); } } catch (IOException e) { logger.warning(e.toString()); } } protected void initHints( XMLHandlerHints hints ) { super.initHints(hints); // Map<String,URI> schemas=new HashMap<String,URI>(1); // SimpleFeatureType wfsFT= ft; // // String namespace = ft.getName().getNamespaceURI(); // URI uri; // try { // uri = new URI( namespace ); // schemas.put(namespace,uri); // hints.put(XMLHandlerHints.NAMESPACE_MAPPING, schemas); // // } catch (URISyntaxException e) { // } } /** * * @see org.geotools.data.FeatureReader#hasNext() */ public boolean hasNext() throws IOException { if (next != null) { return true; } try { loadElement(); } catch (NoSuchElementException e) { return false; } return next != null; } private boolean loadElement() throws NoSuchElementException, IOException { if (ts == null) { while ((next == null) && super.hasNext()){ next = super.next(); } } else { List<Action> l = ts.getActions(ft.getTypeName()); if ((insertSearchIndex < l.size()) && (next == null) ) { // look for an insert then // advance one spot while ((insertSearchIndex+1 < l.size()) && (next == null)) { insertSearchIndex++; Action a = (Action) l.get(insertSearchIndex); if (a.getType() == Action.INSERT) { InsertAction ia = (InsertAction) a; next = ia.getFeature(); //run thorough the rest to look for deletes / mods int i = insertSearchIndex + 1; while ((i < l.size()) && (next != null)) { a = (Action) l.get(i); next=updateFeature(a, next); i++; } } } } while ((next == null) && super.hasNext()) { next = super.next(); if ((ts != null) && (next != null)) { // check to make sure it wasn't deleted // check for updates Iterator<Action> i = l.iterator(); while (i.hasNext() && (next != null)) { Action a = (Action) i.next(); next=updateFeature(a, next); } } } } return next != null; } private SimpleFeature updateFeature( Action a, SimpleFeature feature ) { if ((a.getType() == Action.DELETE) && a.getFilter().evaluate(feature)) { return null; } else { if ((a.getType() == Action.UPDATE) && a.getFilter().evaluate(feature)) { // update the feature UpdateAction ua = (UpdateAction) a; ua.update(feature); } } return feature; } /** * @see org.geotools.data.FeatureReader#next() */ public SimpleFeature next() throws IOException, NoSuchElementException { if (next == null) { loadElement(); // load it if (next == null) { throw new NoSuchElementException(); } } SimpleFeature r = next; next = null; return r; } }