Java tutorial
//$HeadURL$ /*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2012 by: Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de 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; either version 2.1 of the License, or (at your option) any later version. 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. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: info@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.igeo.dataadapter.wfs; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.apache.commons.httpclient.HttpMethod; import org.apache.sanselan.util.IOUtils; import org.deegree.datatypes.QualifiedName; import org.deegree.framework.log.ILogger; import org.deegree.framework.log.LoggerFactory; import org.deegree.framework.util.GeometryUtils; import org.deegree.framework.util.HttpUtils; import org.deegree.framework.xml.XMLFragment; import org.deegree.igeo.ApplicationContainer; import org.deegree.igeo.dataadapter.DataAccessException; import org.deegree.igeo.i18n.Messages; import org.deegree.igeo.mapmodel.Layer; import org.deegree.model.feature.Feature; import org.deegree.model.feature.FeatureCollection; import org.deegree.model.feature.FeatureProperty; import org.deegree.model.feature.GMLFeatureCollectionDocument; import org.deegree.model.feature.schema.GMLSchema; import org.deegree.model.feature.schema.GMLSchemaDocument; import org.deegree.model.filterencoding.ComplexFilter; import org.deegree.model.filterencoding.Filter; import org.deegree.model.filterencoding.LogicalOperation; import org.deegree.model.filterencoding.Operation; import org.deegree.model.filterencoding.OperationDefines; import org.deegree.model.filterencoding.PropertyName; import org.deegree.model.filterencoding.SpatialOperation; import org.deegree.model.spatialschema.Envelope; import org.deegree.model.spatialschema.Geometry; import org.deegree.model.spatialschema.GeometryException; import org.deegree.model.spatialschema.GeometryFactory; import org.deegree.model.spatialschema.MultiSurface; import org.deegree.model.spatialschema.Surface; import org.deegree.ogcwebservices.wfs.XMLFactory; import org.deegree.ogcwebservices.wfs.operation.GetFeature; import org.deegree.ogcwebservices.wfs.operation.GetFeature.RESULT_TYPE; import org.deegree.ogcwebservices.wfs.operation.Query; /** * Implementation of {@link WFSDataLoader} for WFS 1.1.0 * * @author <a href="mailto:wanhoff@lat-lon.de">Jeronimo Wanhoff</a> * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> * @author last edited by: $Author$ * * @version. $Revision$, $Date$ */ public class WFS110DataLoader implements WFSDataLoader { private static final ILogger LOG = LoggerFactory.getLogger(WFS110DataLoader.class); private int timeout = 20000; private int maxFeatures = 5000; /** * package protected to avoid uncontrolled access */ WFS110DataLoader() { } /* * (non-Javadoc) * * @see org.deegree.igeo.dataadapter.WFSDataLoader#setTimeout(int) */ public void setTimeout(int timeout) { this.timeout = timeout; } /* * (non-Javadoc) * * @see org.deegree.igeo.dataadapter.WFSDataLoader#setMaxFeatures(int) */ public void setMaxFeatures(int maxFeatures) { this.maxFeatures = maxFeatures; } /** * reads data from a WFS and returns the result as feature collection. returned data may be limited by a restricting * bounding box and/or a filter expression * * @param wfs * @param property * @param bbox * @param query, must not be <code>null</code> * @param layer * @return feature collection */ public FeatureCollection readFeatureCollection(URL wfs, QualifiedName property, Envelope bbox, Query query, Layer layer) { Filter filter = query.getFilter(); // if all features shall be loaded wether a filter nor a bbox will be set. On the other // a user may has defined a general filter but no spatial restrictions should be used // loading data (e.g. a WFSDataSource is not LazyLoading). Operation op = null; if (bbox != null) { PropertyName pn = new PropertyName(property); try { op = new SpatialOperation(OperationDefines.BBOX, pn, GeometryFactory.createSurface(bbox, bbox.getCoordinateSystem())); } catch (GeometryException e) { LOG.logError(e.getMessage(), e); throw new DataAccessException(Messages.getMessage(Locale.getDefault(), "$DG10020")); } } if (op != null && filter != null) { List<Operation> list = new ArrayList<Operation>(); list.add(op); list.add(((ComplexFilter) filter).getOperation()); op = new LogicalOperation(OperationDefines.AND, list); filter = new ComplexFilter(op); } else if (op != null && filter == null) { filter = new ComplexFilter(op); } query = Query.create(query.getPropertyNames(), query.getFunctions(), query.getSortProperties(), query.getHandle(), query.getFeatureVersion(), query.getTypeNames(), query.getAliases(), query.getSrsName(), filter, query.getMaxFeatures(), query.getStartPosition(), query.getResultType()); query.setSrsName(layer.getOwner().getCoordinateSystem().getPrefixedName()); GetFeature getFeature = GetFeature.create("1.1.0", "99", RESULT_TYPE.RESULTS, GetFeature.FORMAT_GML3, null, maxFeatures, 0, -1, -1, new Query[] { query }); ApplicationContainer<?> appCont = layer.getOwner().getApplicationContainer(); XMLFragment xml = null; try { xml = XMLFactory.export(getFeature); xml = HttpUtils.addAuthenticationForXML(xml, appCont.getUser(), appCont.getPassword(), appCont.getCertificate(wfs.toURI().toASCIIString())); if (LOG.getLevel() == ILogger.LOG_DEBUG) { LOG.logDebug("GetFeature request: ", xml.getAsString()); } } catch (Exception e) { LOG.logError(e.getMessage(), e); throw new DataAccessException(Messages.getMessage(Locale.getDefault(), "$DG10021")); } InputStream is = null; try { HttpMethod m = HttpUtils.performHttpPost(wfs.toURI().toASCIIString(), xml, timeout, appCont.getUser(), appCont.getPassword(), null); is = m.getResponseBodyAsStream(); if (LOG.getLevel() == ILogger.LOG_DEBUG) { byte[] bs = IOUtils.getInputStreamBytes(is); String s = new String(bs, "UTF-8"); LOG.logDebug("GetFeature Response", s); is = new ByteArrayInputStream(s.getBytes("UTF-8")); } } catch (Exception e) { LOG.logError(e.getMessage(), e); throw new DataAccessException( Messages.getMessage(Locale.getDefault(), "$DG10022", wfs, xml.getAsString())); } GMLFeatureCollectionDocument gml = new GMLFeatureCollectionDocument(); FeatureCollection fc = null; try { gml.load(is, wfs.toExternalForm()); fc = gml.parse(); } catch (Exception e) { LOG.logError(e.getMessage(), e); throw new DataAccessException( Messages.getMessage(Locale.getDefault(), "$DG10023", wfs, xml.getAsString())); } fc = ensureClockwiseSurfaceOrientation(fc); return fc; } /** * @param fc * @return */ private FeatureCollection ensureClockwiseSurfaceOrientation(FeatureCollection fc) { int c = fc.size(); for (int i = 0; i < c; i++) { Feature feature = fc.getFeature(i); FeatureProperty[] fp = feature.getProperties(); for (int j = 0; j < fp.length; j++) { Object value = fp[j].getValue(); if (value != null && (value instanceof Surface || value instanceof MultiSurface)) { try { fp[j].setValue(GeometryUtils.ensureClockwise((Geometry) fp[j].getValue())); } catch (GeometryException e) { e.printStackTrace(); } } } } return fc; } /* * (non-Javadoc) * * @see * org.deegree.client.presenter.connector.WFSDataLoader#readGMLApplicationSchema(org.deegree.datatypes.QualifiedName * ) */ public GMLSchema readGMLApplicationSchema(URL wfs, Layer layer, QualifiedName[] featureTypes) { StringBuffer sb = new StringBuffer(1000); sb.append("request=DescribeFeatureType&version=1.1.0&service=WFS&TYPENAME="); for (int i = 0; i < featureTypes.length; i++) { sb.append(featureTypes[i].getPrefix()).append(':'); sb.append(featureTypes[i].getLocalName()); if (i < featureTypes.length - 1) { sb.append(','); } } sb.append("&NAMESPACE=xmlns("); for (int i = 0; i < featureTypes.length; i++) { sb.append(featureTypes[i].getPrefix()).append('='); sb.append(featureTypes[i].getNamespace().toASCIIString()); if (i < featureTypes.length - 1) { sb.append(','); } } sb.append(')'); InputStream is; try { ApplicationContainer<?> appCont = layer.getOwner().getApplicationContainer(); String tmp = HttpUtils.normalizeURL(wfs); String request = HttpUtils.addAuthenticationForKVP(sb.toString(), appCont.getUser(), appCont.getPassword(), appCont.getCertificate(tmp)); is = HttpUtils.performHttpGet(wfs.toURI().toASCIIString(), request, timeout, appCont.getUser(), appCont.getPassword(), null).getResponseBodyAsStream(); } catch (Exception e) { LOG.logError(e.getMessage(), e); throw new DataAccessException(Messages.getMessage(Locale.getDefault(), "$DG10024", wfs, sb.toString())); } GMLSchemaDocument xsd = new GMLSchemaDocument(); GMLSchema schema = null; try { xsd.load(is, wfs.toURI().toASCIIString()); schema = xsd.parseGMLSchema(); } catch (Exception e) { LOG.logError(e.getMessage(), e); throw new DataAccessException(Messages.getMessage(Locale.getDefault(), "$DG10025", wfs, sb.toString())); } return schema; } }