org.deegree.igeo.dataadapter.wfs.WFS110DataLoader.java Source code

Java tutorial

Introduction

Here is the source code for org.deegree.igeo.dataadapter.wfs.WFS110DataLoader.java

Source

//$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;
    }

}