001    //$Header: /raid/cvs-repos/cvsroot/lgv_3g/src/de/latlon/lgv3d/WPVSClientConfig.java,v 1.1 2007/03/09 10:40:46 ap Exp $
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    
037    package org.deegree.portal.common;
038    
039    import java.io.IOException;
040    import java.io.InputStream;
041    import java.net.MalformedURLException;
042    import java.net.URL;
043    import java.util.ArrayList;
044    import java.util.List;
045    import java.util.Properties;
046    
047    import org.deegree.framework.log.ILogger;
048    import org.deegree.framework.log.LoggerFactory;
049    import org.deegree.model.crs.CoordinateSystem;
050    import org.deegree.ogcwebservices.OWSUtils;
051    import org.deegree.ogcwebservices.getcapabilities.InvalidCapabilitiesException;
052    import org.deegree.ogcwebservices.wpvs.capabilities.Dataset;
053    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSCapabilities;
054    import org.deegree.ogcwebservices.wpvs.capabilities.WPVSCapabilitiesDocument;
055    import org.xml.sax.SAXException;
056    
057    /**
058     * TODO add documentation here
059     *
060     * @author <a href="mailto:taddei@lat-lon.de">Ugo Taddei</a>
061     * @author last edited by: $Author: ap $
062     *
063     * @version $Revision: 1.1 $, $Date: 2007/03/09 10:40:46 $
064     */
065    public class WPVSClientConfig {
066    
067        private final String[] initialBBox;
068    
069        private final String initialBBoxString;
070    
071        private final String wpvsBaseURL;
072    
073        private final int viewHeight;
074    
075        private final int viewWidth;
076    
077        private final int overViewHeight;
078    
079        private final int overViewWidth;
080    
081        private final String[] availableDatasets;
082    
083        private final WPVSCapabilities WPVS_Capabilities;
084    
085        private final String WMS_GetMap_Fragment;
086    
087        private static WPVSClientConfig clientConfig;
088    
089        private final Properties clientOptions;
090    
091        private final String defaultCRS;
092    
093        private final String propertieFile = "wpvsclient.properties";
094    
095        private final String elevationModel;
096    
097        private final String serviceIdentification;
098    
099        private final int distanceAboveSeaLevel;
100    
101        private final int initialPitch;
102    
103        private final int initialRoll;
104    
105        private final int initialYaw;
106    
107        private final int initialHeight;
108    
109        private final int initialDistance;
110    
111        private final double poi_x;
112    
113        private final double poi_y;
114    
115        private static ILogger LOG = LoggerFactory.getLogger( WPVSClientConfig.class );
116    
117        private WPVSClientConfig() throws SAXException, InvalidCapabilitiesException, IOException {
118            // Singleton pattern
119            clientOptions = new Properties();
120            try {
121                InputStream clientProps = WPVSClientConfig.class.getResourceAsStream( "/" + propertieFile );
122                if ( clientProps == null ) {
123                    clientProps = WPVSClientConfig.class.getResourceAsStream( propertieFile );
124                }
125                clientOptions.load( clientProps );
126            } catch ( IOException e ) {
127                LOG.logError( e.getMessage(), e );
128            }
129    
130            String value = clientOptions.getProperty( "initialBBox" );
131            if ( value == null || "".equals( value.trim() ) ) {
132                LOG.logError( "The property 'initialBBox' can not be found or has no value. Please insert it into the wpvsclient.properties." );
133                throw new IllegalArgumentException(
134                                                    "The property 'initialBBox' can not be found or has no value. Please insert it into the wpvsclient.properties." );
135            }
136    
137            initialBBox = value.split( "," );
138            if ( initialBBox.length != 4 ) {
139                LOG.logError( "The property 'initialBBox' must have exactly 4 values seperated by commata (',')." );
140                throw new IllegalArgumentException(
141                                                    "The property 'initialBBox' must have exactly 4 values seperated by commata (',')." );
142    
143            }
144            initialBBoxString = value;
145    
146            String wpvsAddress = clientOptions.getProperty( "wpvsService" );
147            if ( wpvsAddress == null ) {
148                LOG.logError( "The property 'wpvsService' can not be found or has no value. Please insert it into the wpvsclient.properties." );
149                throw new IllegalArgumentException(
150                                                    "The property 'wpvsService' can not be found or has no value. Please insert it into the wpvsclient.properties." );
151            }
152    
153            wpvsBaseURL = OWSUtils.validateHTTPGetBaseURL( wpvsAddress );
154    
155            URL wpvsAddressURL = null;
156            try {
157                wpvsAddressURL = new URL( wpvsAddress + "request=GetCapabilities&service=WPVS" );
158            } catch ( MalformedURLException e ) {
159                throw new IllegalArgumentException( "The value (" + wpvsAddress
160                                                    + ") of property 'WPVS_Capabilities' is not a valid URL because: "
161                                                    + e.getMessage() );
162            }
163            WPVSCapabilitiesDocument capsDoc = new WPVSCapabilitiesDocument();
164            try {
165                capsDoc.load( wpvsAddressURL );
166            } catch ( IOException e ) {
167                LOG.logError( "Error while contacting the wpvs at location: '" + wpvsAddress
168                              + "' please make sure, the server is a valid wpvs." );
169                throw e;
170            }
171            WPVS_Capabilities = (WPVSCapabilities) capsDoc.parseCapabilities();
172    
173            String serviceID = WPVS_Capabilities.getServiceIdentification().getName();
174            if ( serviceID == null ) {
175                serviceIdentification = "Unknown WPVS service";
176            } else {
177                serviceIdentification = serviceID;
178            }
179    
180            // find the datasets and a default crs.
181            Dataset ds = WPVS_Capabilities.getDataset();
182            if ( ds == null ) {
183                throw new IllegalArgumentException(
184                                                    "Found no rootdataset in the capabilitiesdocument, this may not be, please make sure, the server at location: "
185                                                                            + wpvsBaseURL + " is a valid wpvs." );
186            }
187            List<Dataset> foundSets = new ArrayList<Dataset>();
188            //foundSets.add( ds );
189            findDataSets( ds, foundSets );
190            availableDatasets = new String[foundSets.size()];
191            String elevationModeltmp = null;
192            for ( int i = 0; i < foundSets.size(); ++i ) {
193                availableDatasets[i] = foundSets.get( i ).getName();
194                if ( elevationModeltmp == null && foundSets.get( i ).getElevationModel() != null ) {
195                    LOG.logInfo( "Using elevationModel of dataset: " + availableDatasets[i] );
196                    elevationModeltmp = foundSets.get( i ).getElevationModel().getName();
197                }
198    
199            }
200    
201            if ( elevationModeltmp == null ) {
202                LOG.logInfo( "Found no elevationModel in the capabilitiesdocument, though correct it is a little awkward, please make sure, the server at location: "
203                             + wpvsBaseURL + " is configured correctly." );
204            }
205    
206            elevationModel = elevationModeltmp;
207    
208            value = clientOptions.getProperty( "defaultCRS" );
209            if ( value == null || "".equals( value.trim() ) ) {
210                LOG.logInfo( "The property 'defaultCRS' can not be found or has no value. Trying to find in datasets." );
211                CoordinateSystem[] crs = ds.getCrs();
212                if ( crs == null || crs.length == 0 ) {
213                    LOG.logInfo( "No crs's found in datasets, setting defaultCRS to EPSG:4326." );
214                    defaultCRS = "EPGS:4326";
215                } else {
216                    defaultCRS = crs[0].getFormattedString();
217                }
218            } else {
219                defaultCRS = value.trim();
220            }
221    
222            value = clientOptions.getProperty( "WMS_GetMap_Fragment" );
223            if ( value == null ) {
224                value = clientOptions.getProperty( "wmsDefaultLayer" );
225                if ( value == null ) {
226                    String message = "No WMS_GetMap_Fragment was defined, and no wms default Layer was defined, please specify either one (WMS_GetMap_Fragment or wmsDefaultLayer) in wpvsclient.properties no Overview image will be available";
227                    LOG.logInfo( message );
228                    WMS_GetMap_Fragment = null;
229                } else {
230                    String layer = value;
231                    value = clientOptions.getProperty( "wmsVersion" );
232                    if ( value == null ) {
233                        LOG.logInfo( "No WMS_GetMap_Fragment was defined, and no wms version was found defined,thus assuming version 1.3.0" );
234                        value = "1.3.0";
235                    }
236                    WMS_GetMap_Fragment = wpvsAddress
237                                          + "SERVICE=WMS&VERSION="
238                                          + value
239                                          + "&REQUEST=GetMap&FORMAT=image/png&TRANSPARENT=true&BGCOLOR=0xFFFFFF&EXCEPTIONS=application/vnd.ogc.se_inimage&STYLES=&LAYERS="
240                                          + layer + "&CRS=" + defaultCRS;
241    
242                    LOG.logInfo( "The property WMS_GetMap_Fragment could not be found or has no value. Using the default wpvs server adress as the base wms overview server. Request will be:\n"
243                                 + WMS_GetMap_Fragment );
244                }
245            } else {
246                WMS_GetMap_Fragment = value;
247            }
248    
249            value = clientOptions.getProperty( "viewHeight" );
250            if ( value == null ) {
251                LOG.logInfo( "The property 'viewHeight' can not be found or has no value. Setting viewHeight to a value of 600." );
252                viewHeight = 600;
253            } else {
254                viewHeight = Integer.parseInt( value );
255            }
256    
257            value = clientOptions.getProperty( "viewWidth" );
258            if ( value == null ) {
259                LOG.logInfo( "The property 'viewWidth' can not be found or has no value. Setting viewWidth to a value of 800." );
260                viewWidth = 800;
261            } else {
262                viewWidth = Integer.parseInt( value );
263            }
264    
265            value = clientOptions.getProperty( "overViewHeight" );
266            if ( value == null ) {
267                LOG.logInfo( "The property 'overViewHeight' can not be found or has no value. Setting overViewHeight to a value of 150." );
268                overViewHeight = 150;
269            } else {
270                overViewHeight = Integer.parseInt( value );
271            }
272    
273            value = clientOptions.getProperty( "overViewWidth" );
274            if ( value == null ) {
275                LOG.logInfo( "The property 'overViewWidth' can not be found or has no value. Setting overViewWidth to a value of 150." );
276                overViewWidth = 150;
277            } else {
278                overViewWidth = Integer.parseInt( value );
279            }
280    
281            value = clientOptions.getProperty( "distanceAboveSeaLevel" );
282            if ( value == null ) {
283                LOG.logInfo( "The property 'distanceAboveSeaLevel' can not be found or has no value. Setting initialElevation to a value of 150." );
284                distanceAboveSeaLevel = 0;
285            } else {
286                distanceAboveSeaLevel = Integer.parseInt( value );
287            }
288            value = clientOptions.getProperty( "initialHeight" );
289            if ( value == null ) {
290                LOG.logInfo( "The property 'initialHeight' can not be found or has no value. Setting initialElevation to a value of 150." );
291                initialHeight = 150;
292            } else {
293                initialHeight = Integer.parseInt( value );
294            }
295            value = clientOptions.getProperty( "poi_x" );
296            if ( value == null ) {
297                LOG.logInfo( "The property 'poi_x' can not be found or has no value. Setting poi_x to a value of 424453." );
298                poi_x = 424453;
299            } else {
300                poi_x = Double.parseDouble( value );
301            }
302    
303            value = clientOptions.getProperty( "poi_y" );
304            if ( value == null ) {
305                LOG.logInfo( "The property 'poi_y' can not be found or has no value. Setting poi_y to a value of 150." );
306                poi_y = 4512876;
307            } else {
308                poi_y = Double.parseDouble( value );
309            }
310    
311            value = clientOptions.getProperty( "initialPitch" );
312            if ( value == null ) {
313                LOG.logInfo( "The property 'initialPitch' can not be found or has no value. Setting initialPitch to a value of 50." );
314                initialPitch = 50;
315            } else {
316                initialPitch = Integer.parseInt( value );
317            }
318    
319            value = clientOptions.getProperty( "initialRoll" );
320            if ( value == null ) {
321                LOG.logInfo( "The property 'initialRoll' can not be found or has no value. Setting initialRoll to a value of 0." );
322                initialRoll = 0;
323            } else {
324                initialRoll = Integer.parseInt( value );
325            }
326    
327            value = clientOptions.getProperty( "initialYaw" );
328            if ( value == null ) {
329                LOG.logInfo( "The property 'initialYaw' can not be found or has no value. Setting initialYaw to a value of 180." );
330                initialYaw = 180;
331            } else {
332                initialYaw = Integer.parseInt( value );
333            }
334    
335            value = clientOptions.getProperty( "initialDistance" );
336            if ( value == null ) {
337                LOG.logInfo( "The property 'initialDistance' can not be found or has no value. Setting initialDistance to a value of 1000." );
338                initialDistance = 1000;
339            } else {
340                initialDistance = Integer.parseInt( value );
341            }
342    
343        }
344    
345        private void findDataSets( Dataset rootSet, List<Dataset> foundSets ) {
346            if ( rootSet != null ) {
347                Dataset[] childSets = rootSet.getDatasets();
348                for ( Dataset ds : childSets ) {
349                    if ( !foundSets.contains( ds ) ) {
350                        if( ds.getQueryable() ){
351                            foundSets.add( ds );
352                        }
353                        findDataSets( ds, foundSets );
354                    }
355                }
356            }
357        }
358    
359        /**
360         * @return a WPVSClientConfig instance following a singleton pattern.
361         * @throws SAXException
362         *             if the creation of the capabilities document fails
363         * @throws IOException
364         *             if the wpvs capabilities document cannot be read
365         * @throws InvalidCapabilitiesException
366         *             if the wpvs capabilitiesdocument cannot be parsed.
367         */
368        public static synchronized WPVSClientConfig getInstance()
369                                throws InvalidCapabilitiesException, IOException, SAXException {
370            if ( clientConfig == null ) {
371                clientConfig = new WPVSClientConfig();
372            }
373            return clientConfig;
374        }
375    
376        /**
377         *
378         * @return initial bounding box for GetView request
379         */
380        public final String[] getInitialBBox() {
381            return initialBBox;
382        }
383    
384        /**
385         *
386         * @return WMS GetMap request fragment for overview map
387         */
388        public final String getWmsGetMapFragment() {
389            return WMS_GetMap_Fragment;
390        }
391    
392        /**
393         *
394         * @return capabilities of the WPVS
395         */
396        public final WPVSCapabilities getWpvsCapabilities() {
397            return WPVS_Capabilities;
398        }
399    
400        /**
401         * @return the overViewHeight.
402         */
403        public final int getOverViewHeight() {
404            return overViewHeight;
405        }
406    
407        /**
408         * @return the overViewWidth.
409         */
410        public final int getOverViewWidth() {
411            return overViewWidth;
412        }
413    
414        /**
415         * @return the viewHeight.
416         */
417        public final int getViewHeight() {
418            return viewHeight;
419        }
420    
421        /**
422         * @return the viewWidth.
423         */
424        public final int getViewWidth() {
425            return viewWidth;
426        }
427    
428        /**
429         * @return the wpvsBaseURL.
430         */
431        public final String getWpvsBaseURL() {
432            return wpvsBaseURL;
433        }
434    
435        /**
436         * @return the availableDatasets.
437         */
438        public final String[] getAvailableDatasets() {
439            return availableDatasets;
440        }
441    
442        /**
443         * @return the defaultCRS.
444         */
445        public final String getDefaultCRS() {
446            return defaultCRS;
447        }
448    
449        /**
450         * @return the elevationModel.
451         */
452        public final String getElevationModel() {
453            return elevationModel;
454        }
455    
456        /**
457         * @return the serviceIdentification.
458         */
459        public final String getServiceIdentification() {
460            return serviceIdentification;
461        }
462    
463        /**
464         * @return the initialElevation.
465         */
466        public final int getDistanceAboveSeaLevel() {
467            return distanceAboveSeaLevel;
468        }
469    
470        /**
471         * @return the initialBBoxString.
472         */
473        public final String getInitialBBoxAsString() {
474            return initialBBoxString;
475        }
476    
477        /**
478         * @return the initialPitch.
479         */
480        public final int getInitialPitch() {
481            return initialPitch;
482        }
483    
484        /**
485         * @return the initialDistance.
486         */
487        public final int getInitialDistance() {
488            return initialDistance;
489        }
490    
491        /**
492         * @return the initialRoll.
493         */
494        public final int getInitialRoll() {
495            return initialRoll;
496        }
497    
498        /**
499         * @return the initialYaw.
500         */
501        public final int getInitialYaw() {
502            return initialYaw;
503        }
504    
505        /**
506         * @return the initialHeight.
507         */
508        public final int getInitialHeight() {
509            return initialHeight;
510        }
511    
512        /**
513         * @return the poi_x.
514         */
515        public final double getPOIX() {
516            return poi_x;
517        }
518    
519        /**
520         * @return the poi_y.
521         */
522        public final double getPOIY() {
523            return poi_y;
524        }
525    
526    }