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