    001    //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/ogcwebservices/wms/GetMapServiceInvokerForUL.java $
    002    /*----------------------------------------------------------------------------
    003     This file is part of deegree, http://deegree.org/
    004     Copyright (C) 2001-2009 by:
    005       Department of Geography, University of Bonn
    006     and
    007       lat/lon GmbH
    008
    009     This library is free software; you can redistribute it and/or modify it under
    010     the terms of the GNU Lesser General Public License as published by the Free
    011     Software Foundation; either version 2.1 of the License, or (at your option)
    012     any later version.
    013     This library is distributed in the hope that it will be useful, but WITHOUT
    014     ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    015     FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
    016     details.
    017     You should have received a copy of the GNU Lesser General Public License
    018     along with this library; if not, write to the Free Software Foundation, Inc.,
    019     59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    020
    021     Contact information:
    022
    023     lat/lon GmbH
    024     Aennchenstr. 19, 53177 Bonn
    025     Germany
    026     http://lat-lon.de/
    027
    028     Department of Geography, University of Bonn
    029     Prof. Dr. Klaus Greve
    030     Postfach 1147, 53001 Bonn
    031     Germany
    032     http://www.geographie.uni-bonn.de/deegree/
    033
    034     e-mail: info@deegree.org
    035    ----------------------------------------------------------------------------*/
    036    package org.deegree.ogcwebservices.wms;
    037
    038    import static java.lang.Boolean.FALSE;
    039
    040    import java.io.ByteArrayOutputStream;
    041    import java.io.InputStreamReader;
    042    import java.io.StringReader;
    043    import java.net.URI;
    044    import java.net.URL;
    045    import java.util.Arrays;
    046    import java.util.Iterator;
    047    import java.util.List;
    048    import java.util.Map;
    049    import java.util.concurrent.Callable;
    050
    051    import org.deegree.datatypes.QualifiedName;
    052    import org.deegree.framework.log.ILogger;
    053    import org.deegree.framework.log.LoggerFactory;
    054    import org.deegree.framework.util.CharsetUtils;
    055    import org.deegree.framework.util.IDGenerator;
    056    import org.deegree.framework.util.NetWorker;
    057    import org.deegree.framework.xml.XMLFragment;
    058    import org.deegree.graphics.MapFactory;
    059    import org.deegree.graphics.sld.AbstractStyle;
    060    import org.deegree.graphics.sld.FeatureTypeConstraint;
    061    import org.deegree.graphics.sld.LayerFeatureConstraints;
    062    import org.deegree.graphics.sld.RemoteOWS;
    063    import org.deegree.graphics.sld.StyleUtils;
    064    import org.deegree.graphics.sld.UserLayer;
    065    import org.deegree.graphics.sld.UserStyle;
    066    import org.deegree.model.feature.FeatureCollection;
    067    import org.deegree.model.feature.GMLFeatureCollectionDocument;
    068    import org.deegree.model.filterencoding.Filter;
    069    import org.deegree.ogcbase.PropertyPath;
    070    import org.deegree.ogcwebservices.OGCWebService;
    071    import org.deegree.ogcwebservices.OGCWebServiceException;
    072    import org.deegree.ogcwebservices.wfs.operation.FeatureResult;
    073    import org.deegree.ogcwebservices.wfs.operation.GetFeature;
    074    import org.w3c.dom.Element;
    075
    076    /**
    077     * class for accessing the data of one user layer and creating <tt>DisplayElement</tt>s and a <tt>Thrme</tt> from it.
    078     * The class extends <tt>Thread</tt> and implements the run method, so that a parallel data accessing from several
    079     * layers is possible.
    080     *
    081     * @version $Revision: 18195 $
    082     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
    083     * @author last edited by: $Author: mschneider $
    084     *
    085     * @version 1.0. $Revision: 18195 $, $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
    086     *
    087     * @since 2.0
    088     */
    089    class GetMapServiceInvokerForUL extends GetMapServiceInvoker implements Callable<Object> {
    090
    091        private static final ILogger LOG = LoggerFactory.getLogger( GetMapServiceInvokerForUL.class );
    092
    093        private UserLayer layer = null;
    094
    095        private UserStyle[] styles = null;
    096
    097        /**
    098         *
    099         * @param handler
    100         * @param layer
    101         * @param scale
    102         *            current mapscale denominator
    103         */
    104        GetMapServiceInvokerForUL( DefaultGetMapHandler handler, UserLayer layer, double scale ) {
    105            super( handler, scale );
    106
    107            this.layer = layer;
    108            AbstractStyle[] tmp = layer.getStyles();
    109            styles = new UserStyle[tmp.length];
    110            for ( int i = 0; i < tmp.length; i++ ) {
    111                styles[i] = (UserStyle) tmp[i];
    112            }
    113
    114        }
    115
    116        public Object call() {
    117
    118            try {
    119                if ( layer.getRemoteOWS() == null || layer.getRemoteOWS().getService().equals( RemoteOWS.WFS ) ) {
    120                    return handleWFS();
    121                } else if ( layer.getRemoteOWS().getService().equals( RemoteOWS.WCS ) ) {
    122                    return handleWCS();
    123                }
    124
    125            } catch ( OGCWebServiceException e ) {
    126                return e;
    127            } catch ( Exception e ) {
    128                LOG.logError( e.getMessage(), e );
    129                OGCWebServiceException exce = new OGCWebServiceException( "ServiceInvokerForUL: " + layer.getName(),
    130                                                                          "Couldn't perform query!" );
    131                return exce;
    132            }
    133
    134            return null;
    135        }
    136
    137        /**
    138         * handles requests against a WFS
    139         */
    140        private Object handleWFS()
    141                                throws Exception {
    142
    143            FeatureCollection fc = null;
    144            String request = createGetFeatureRequest();
    145            LOG.logDebug( request );
    146            if ( layer.getRemoteOWS() != null ) {
    147                // handle request against a remote WFS
    148                RemoteOWS remoteOWS = layer.getRemoteOWS();
    149                URL url = remoteOWS.getOnlineResource();
    150
    151                NetWorker nw = new NetWorker( CharsetUtils.getSystemCharset(), url, request );
    152                InputStreamReader isr = new InputStreamReader( nw.getInputStream(), CharsetUtils.getSystemCharset() );
    153                GMLFeatureCollectionDocument doc = new GMLFeatureCollectionDocument();
    154                doc.load( isr, url.toString() );
    155                Element root = doc.getRootElement();
    156
    157                if ( root.getNodeName().indexOf( "Exception" ) > -1 ) {
    158                    ByteArrayOutputStream bos = new ByteArrayOutputStream( 1000 );
    159                    doc.write( bos );
    160                    throw new Exception( new String( bos.toByteArray() ) );
    161                }
    162                fc = doc.parse();
    163            } else {
    164                // handle request agaist a local WFS; this is bit problematic
    165                // because deegree WMS is able to handle more than one
    166                // local WFS. At the moment the WFS will be used that will
    167                // returned by the WFServiceFactory as default
    168                XMLFragment xml = new XMLFragment( new StringReader( request ), XMLFragment.DEFAULT_URL );
    169                Element root = xml.getRootElement();
    170                // create OGCWebServiceEvent object
    171                IDGenerator idg = IDGenerator.getInstance();
    172                GetFeature gfr = GetFeature.create( "" + idg.generateUniqueID(), root );
    173
    174                // returns the WFS responsible for handling current feature type
    175                OGCWebService wfs = getResponsibleService( layer );
    176                FeatureResult fr = (FeatureResult) wfs.doService( gfr );
    177                fc = (FeatureCollection) fr.getResponse();
    178            }
    179            org.deegree.graphics.Layer fl = MapFactory.createFeatureLayer( layer.getName(), this.handler.getRequestCRS(),
    180                                                                           fc );
    181            return MapFactory.createTheme( layer.getName(), fl, styles );
    182        }
    183
    184        /**
    185         * creates a GetFeature request related to the UserLayer encapsulated in this object
    186         */
    187        private String createGetFeatureRequest()
    188                                throws Exception {
    189
    190            LayerFeatureConstraints lfc = layer.getLayerFeatureConstraints();
    191            FeatureTypeConstraint[] ftc = lfc.getFeatureTypeConstraint();
    192
    193            List<UserStyle> styleList = Arrays.asList( styles );
    194            List<PropertyPath> pp = StyleUtils.extractRequiredProperties( styleList, scaleDen );
    195            LOG.logDebug( "required properties: ", pp );
    196            pp = findGeoProperties( layer, ftc, pp );
    197            Map<String, URI> namesp = extractNameSpaceDef( pp );
    198            for ( int i = 0; i < ftc.length; i++ ) {
    199                QualifiedName qn = ftc[i].getFeatureTypeName();
    200                namesp.put( qn.getPrefix(), qn.getNamespace() );
    201            }
    202
    203            StringBuffer sb = new StringBuffer( 5000 );
    204            sb.append( "<?xml version='1.0' encoding='" + CharsetUtils.getSystemCharset() + "'?>" );
    205            sb.append( "<GetFeature xmlns='http://www.opengis.net/wfs' " );
    206            sb.append( "xmlns:ogc='http://www.opengis.net/ogc' " );
    207            sb.append( "xmlns:gml='http://www.opengis.net/gml' " );
    208
    209            Iterator<String> iter = namesp.keySet().iterator();
    210            while ( iter.hasNext() ) {
    211                String pre = iter.next();
    212                URI nsp = namesp.get( pre );
    213                if ( !pre.equals( "xmlns" ) ) {
    214                    sb.append( "xmlns:" ).append( pre ).append( "='" );
    215                    sb.append( nsp.toASCIIString() ).append( "' " );
    216                }
    217            }
    218
    219            sb.append( "service='WFS' version='1.1.0' " );
    220            sb.append( "outputFormat='text/xml; subtype=gml/3.1.1'>" );
    221            for ( int i = 0; i < ftc.length; i++ ) {
    222                QualifiedName qn = ftc[i].getFeatureTypeName();
    223                sb.append( "<Query typeName='" ).append( qn.getPrefixedName() ).append( "'>" );
    224
    225                for ( int j = 0; j < pp.size(); j++ ) {
    226                    if ( !pp.get( j ).getAsString().endsWith( "$SCALE" ) ) {
    227                        // $SCALE is a dynamicly created property of each feature
    228                        // and can not be requested
    229                        sb.append( "<PropertyName>" ).append( pp.get( j ).getAsString() );
    230                        sb.append( "</PropertyName>" );
    231                    }
    232                }
    233
    234                Filter filter = ftc[i].getFilter();
    235                if ( filter != null ) {
    236                    sb.append( filter.to110XML() );
    237                }
    238                sb.append( "</Query>" );
    239            }
    240            sb.append( "</GetFeature>" );
    241
    242            LOG.logDebug( sb.toString() );
    243
    244            return sb.toString();
    245        }
    246
    247        /**
    248         * handles requests against a WCS
    249         */
    250        private Object handleWCS()
    251                                throws Exception {
    252            return FALSE;
    253            /*
    254             * TODO RemoteOWS remoteOWS = layer.getRemoteOWS(); URL url = remoteOWS.getOnlineResource();
    255             *
    256             * NetWorker nw = new NetWorker( url ); MemoryCacheSeekableStream mcss = new MemoryCacheSeekableStream(
    257             * nw.getInputStream() );
    258             *
    259             * RenderedOp rop = JAI.create("stream", mcss);
    260             *
    261             * GC_GridCoverage gc = new ImageGridCoverage(rop.getAsBufferedImage(), request.getBoundingBox(), reqCRS,
    262             * false); mcss.close();
    263             *
    264             * org.deegree.graphics.Layer rl = MapFactory.createRasterLayer(layer.getName(), gc);
    265             *
    266             * putTheme(index, MapFactory.createTheme(layer.getName(), rl)); mcss.close(); increaseCounter();
    267             */
    268
    269        }
    270
    271    }