001    // $HeadURL: /cvsroot/deegree/src/org/deegree/ogcwebservices/wms/WMService.java,v
002    // 1.3 2004/07/12 06:12:11 ap Exp $
003    /*----------------    FILE HEADER  ------------------------------------------
004    
005     This file is part of deegree.
006     Copyright (C) 2001-2008 by:
007     EXSE, Department of Geography, University of Bonn
008     http://www.giub.uni-bonn.de/deegree/
009     lat/lon GmbH
010     http://www.lat-lon.de
011    
012     This library is free software; you can redistribute it and/or
013     modify it under the terms of the GNU Lesser General Public
014     License as published by the Free Software Foundation; either
015     version 2.1 of the License, or (at your option) any later version.
016    
017     This library is distributed in the hope that it will be useful,
018     but WITHOUT ANY WARRANTY; without even the implied warranty of
019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
020     Lesser General Public License for more details.
021    
022     You should have received a copy of the GNU Lesser General Public
023     License along with this library; if not, write to the Free Software
024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
025    
026     Contact:
027    
028     Andreas Poth
029     lat/lon GmbH
030     Aennchenstr. 19
031     53115 Bonn
032     Germany
033     E-Mail: poth@lat-lon.de
034    
035     Prof. Dr. Klaus Greve
036     Department of Geography
037     University of Bonn
038     Meckenheimer Allee 166
039     53115 Bonn
040     Germany
041     E-Mail: greve@giub.uni-bonn.de
042    
043     
044     ---------------------------------------------------------------------------*/
045    package org.deegree.ogcwebservices.wms;
046    
047    import java.lang.reflect.Constructor;
048    import java.lang.reflect.InvocationTargetException;
049    
050    import org.deegree.enterprise.Proxy;
051    import org.deegree.framework.log.ILogger;
052    import org.deegree.framework.log.LoggerFactory;
053    import org.deegree.framework.trigger.TriggerProvider;
054    import org.deegree.ogcwebservices.CurrentUpdateSequenceException;
055    import org.deegree.ogcwebservices.InvalidUpdateSequenceException;
056    import org.deegree.ogcwebservices.OGCWebService;
057    import org.deegree.ogcwebservices.OGCWebServiceException;
058    import org.deegree.ogcwebservices.OGCWebServiceRequest;
059    import org.deegree.ogcwebservices.OGCWebServiceResponse;
060    import org.deegree.ogcwebservices.getcapabilities.OGCCapabilities;
061    import org.deegree.ogcwebservices.wms.configuration.WMSConfigurationType;
062    import org.deegree.ogcwebservices.wms.operation.DescribeLayer;
063    import org.deegree.ogcwebservices.wms.operation.GetFeatureInfo;
064    import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
065    import org.deegree.ogcwebservices.wms.operation.GetLegendGraphicResult;
066    import org.deegree.ogcwebservices.wms.operation.GetMap;
067    import org.deegree.ogcwebservices.wms.operation.GetStyles;
068    import org.deegree.ogcwebservices.wms.operation.GetStylesResult;
069    import org.deegree.ogcwebservices.wms.operation.PutStyles;
070    import org.deegree.ogcwebservices.wms.operation.WMSGetCapabilities;
071    import org.deegree.ogcwebservices.wms.operation.WMSGetCapabilitiesResult;
072    import org.deegree.ogcwebservices.wms.operation.WMSProtocolFactory;
073    
074    /**
075     * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
076     * @author last edited by: $Author: aschmitz $
077     * 
078     * @version 1.0. $Revision: 10167 $, $Date: 2008-02-19 16:59:48 +0100 (Di, 19 Feb 2008) $
079     * 
080     * @since 1.1
081     * 
082     */
083    
084    public class WMService implements OGCWebService {
085    
086        private static final ILogger LOG = LoggerFactory.getLogger( WMService.class );
087    
088        private static final TriggerProvider TP = TriggerProvider.create( WMService.class );
089    
090        private WMSConfigurationType configuration = null;
091    
092        /**
093         * Creates a new WMService object.
094         * 
095         * @param configuration
096         */
097        public WMService( WMSConfigurationType configuration ) {
098            this.configuration = configuration;
099            Proxy proxy = configuration.getDeegreeParams().getProxy();
100            if ( proxy != null ) {
101                proxy.setProxy( true );
102            }
103        }
104    
105        /**
106         * 
107         */
108        public OGCCapabilities getCapabilities() {
109            // should a class implement the WMSConfigurationType and not be an instance
110            // of OGCCapabilities, here's where it'll fail ;-)
111            return (OGCCapabilities) configuration;
112        }
113    
114        /**
115         * the method performs the handling of the passed OGCWebServiceEvent directly and returns the
116         * result to the calling class/method
117         * 
118         * @param request
119         *            request to perform
120         * 
121         * @throws OGCWebServiceException
122         */
123        public Object doService( OGCWebServiceRequest request )
124                                throws OGCWebServiceException {
125    
126            request = (OGCWebServiceRequest) TP.doPreTrigger( this, request )[0];
127    
128            LOG.logDebug( "Handling WMS request with ID ", request.getId() );
129    
130            Object result = null;
131            if ( request instanceof GetMap ) {
132                GetMapHandler gmh = (GetMapHandler) createHandler( request, GetMap.class,
133                                                                   HandlerMapping.getString( "WMService.GETMAP" ) );
134                result = gmh.performGetMap();
135            } else if ( request instanceof GetFeatureInfo ) {
136                GetFeatureInfoHandler gmh = (GetFeatureInfoHandler) createHandler(
137                                                                                   request,
138                                                                                   GetFeatureInfo.class,
139                                                                                   HandlerMapping.getString( "WMService.GETFEATUREINFO" ) );
140                result = gmh.performGetFeatureInfo();
141            } else if ( request instanceof WMSGetCapabilities ) {
142                result = handleGetCapabilities( (WMSGetCapabilities) request );
143            } else if ( request instanceof GetStyles ) {
144                handleGetStyles( (GetStyles) request );
145            } else if ( request instanceof PutStyles ) {
146                handlePutStyles( (PutStyles) request );
147            } else if ( request instanceof DescribeLayer ) {
148                result = new DescribeLayerHandler().perform( (DescribeLayer) request, configuration );
149            } else if ( request instanceof GetLegendGraphic ) {
150                result = handleGetLegendGraphic( (GetLegendGraphic) request );
151            }
152    
153            LOG.logDebug( "Handled WMS request with ID ", request.getId() );
154    
155            return TP.doPostTrigger( this, result )[0];
156        }
157    
158        /**
159         * creates a handler class for performing the incomming request. The instance that will be
160         * created depends on the responsible class the for the submitted request in the WMS
161         * capabilities/configuration.
162         * 
163         * @param request
164         *            request to be performed
165         * @param requestClass
166         *            of the request (GetStyles, WMSFeatureInfoRequest etc.)
167         * @param operationType
168         *            type of the operation to perform by the handler
169         */
170        private Object createHandler( OGCWebServiceRequest request, Class<?> requestClass, String className )
171                                throws OGCWebServiceException {
172            // describes the signature of the required constructor
173            Class[] cl = new Class[2];
174            cl[0] = WMSConfigurationType.class;
175            cl[1] = requestClass;
176    
177            // set parameter to submitt to the constructor
178            Object[] o = new Object[2];
179            o[0] = configuration;
180            o[1] = request;
181    
182            Object handler = null;
183    
184            try {
185                // get constructor
186                Class<?> creator = Class.forName( className );
187                Constructor<?> con = creator.getConstructor( cl );
188    
189                // call constructor and instantiate a new DataStore
190                handler = con.newInstance( o );
191            } catch ( ClassNotFoundException cce ) {
192                throw new OGCWebServiceException( "Couldn't instantiate " + className + "! \n" + cce.toString() );
193            } catch ( NoSuchMethodException nsme ) {
194                throw new OGCWebServiceException( "Couldn't instantiate " + className + "! \n" + nsme.toString() );
195            } catch ( InstantiationException ie ) {
196                throw new OGCWebServiceException( "Couldn't instantiate " + className + "! \n" + ie.toString() );
197            } catch ( IllegalAccessException iae ) {
198                throw new OGCWebServiceException( "Couldn't instantiate " + className + "! \n" + iae.toString() );
199            } catch ( InvocationTargetException ite ) {
200                // causes need not be OGCWebService exceptions
201                Throwable cause = ite.getCause();
202                if ( cause instanceof OGCWebServiceException ) {
203                    throw (OGCWebServiceException) cause;
204                }
205                LOG.logError( "Unknown error", cause );
206                throw new OGCWebServiceException( getClass().getName(), cause.getMessage() );
207            } catch ( Exception e ) {
208                throw new OGCWebServiceException( "Couldn't instantiate " + className + "! \n" + e.toString() );
209            }
210    
211            return handler;
212        }
213    
214        /**
215         * reads/creates the capabilities of the WMS.
216         * 
217         * @param request
218         *            capabilities request
219         */
220        private WMSGetCapabilitiesResult handleGetCapabilities( WMSGetCapabilities request )
221                                throws OGCWebServiceException {
222    
223            String rUp = request.getUpdateSequence();
224            String cUp = configuration.getUpdateSequence();
225    
226            if ( ( rUp != null ) && ( cUp != null ) && ( rUp.compareTo( cUp ) == 0 ) ) {
227                throw new CurrentUpdateSequenceException( "request update sequence (" + rUp + ") is equal to capabilities"
228                                                          + " update sequence " + cUp );
229            }
230    
231            if ( ( rUp != null ) && ( cUp != null ) && ( rUp.compareTo( cUp ) > 0 ) ) {
232                throw new InvalidUpdateSequenceException( "request update sequence: " + rUp + " is higher than the "
233                                                          + "capabilities update sequence " + cUp );
234            }
235    
236            WMSGetCapabilitiesResult res = null;
237            res = WMSProtocolFactory.createGetCapabilitiesResponse( request, null, configuration );
238    
239            return res;
240        }
241    
242        /**
243         * @param request
244         *            get styles request (WMS 1.1.1 - SLD)
245         */
246        private GetStylesResult handleGetStyles( GetStyles request ) {
247            throw new UnsupportedOperationException( "handleGetStyles(" + request.getClass().getSimpleName()
248                                                     + ") not implemented" );
249        }
250    
251        /**
252         * @param request
253         *            put styles request (WMS 1.1.1 - SLD)
254         */
255        private void handlePutStyles( PutStyles request ) {
256            throw new UnsupportedOperationException( "handlePutStyles(" + request.getClass().getSimpleName()
257                                                     + ") not implemented" );
258        }
259    
260        /**
261         * @param request
262         * 
263         * @return the response
264         * @throws WebServiceException
265         */
266        private OGCWebServiceResponse handleGetLegendGraphic( GetLegendGraphic request )
267                                throws OGCWebServiceException {
268            OGCWebServiceResponse result;
269    
270            Object o = createHandler( request, GetLegendGraphic.class,
271                                      HandlerMapping.getString( "WMService.GETLEGENDGRAPHIC" ) );
272            GetLegendGraphicHandler glgh = (GetLegendGraphicHandler) o;
273            result = glgh.performGetLegendGraphic();
274            if ( ( (GetLegendGraphicResult) result ).getLegendGraphic() != null ) {
275                // cache.push(request, ((GetLegendGraphicResult) result).getLegendGraphic());
276            }
277    
278            return result;
279        }
280    
281    }