001    //$HeadURL: $
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     This library is distributed in the hope that it will be useful,
015     but WITHOUT ANY WARRANTY; without even the implied warranty of
016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     Lesser General Public License for more details.
018     You should have received a copy of the GNU Lesser General Public
019     License along with this library; if not, write to the Free Software
020     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021     Contact:
022    
023     Andreas Poth
024     lat/lon GmbH
025     Aennchenstr. 19
026     53177 Bonn
027     Germany
028     E-Mail: poth@lat-lon.de
029    
030     Prof. Dr. Klaus Greve
031     Department of Geography
032     University of Bonn
033     Meckenheimer Allee 166
034     53115 Bonn
035     Germany
036     E-Mail: greve@giub.uni-bonn.de
037     ---------------------------------------------------------------------------*/
038    
039    package org.deegree.crs.configuration;
040    
041    import java.io.BufferedWriter;
042    import java.io.File;
043    import java.io.FileWriter;
044    import java.io.IOException;
045    import java.io.InputStream;
046    import java.util.HashMap;
047    import java.util.List;
048    import java.util.Map;
049    import java.util.Properties;
050    
051    import org.deegree.crs.coordinatesystems.CoordinateSystem;
052    import org.deegree.crs.exceptions.CRSConfigurationException;
053    import org.deegree.framework.log.ILogger;
054    import org.deegree.framework.log.LoggerFactory;
055    import org.deegree.i18n.Messages;
056    
057    /**
058     * The <code>CRSConfiguration</code> creates, instantiates and supplies a configured CRS-Provider. Because only one
059     * crs-configuration is needed inside the JVM, this implementation uses a singleton pattern.
060     * <p>
061     * The configuration will try to read the file: crs_providers.properties. It uses following strategie to load this file,
062     * first the root directory (e.g. '/' or WEB-INF/classes ) will be searched. If no file was found there, it will try to
063     * load from the package. The properties file must denote a property with name 'CRS_PROVIDER' followed by a '=' and a
064     * fully qualified name denoting the class (an instance of CRSProvider) which should be available in the classpath. This
065     * class must have an empty constructor.
066     * </p>
067     * 
068     * @author <a href="mailto:bezema@lat-lon.de">Rutger Bezema</a>
069     * 
070     * @author last edited by: $Author:$
071     * 
072     * @version $Revision:$, $Date:$
073     * 
074     */
075    
076    public class CRSConfiguration {
077        private static ILogger LOG = LoggerFactory.getLogger( CRSConfiguration.class );
078    
079        private CRSProvider provider;
080    
081        //
082        private final static String PROVIDER_CONFIG = "crs_providers.properties";
083    
084        private static CRSConfiguration CONFIG = null;
085    
086        /**
087         * @param provider
088         *            to get the CRS's from.
089         */
090        private CRSConfiguration( CRSProvider provider ) {
091            this.provider = provider;
092        }
093    
094        /**
095         * creates or returns an instance of the CRSConfiguration by reading the DEFAULT property configured in the
096         * 'crs_providers.properties'. If no key is given (or no string could be loaded), the {@link DeegreeCRSProvider}
097         * will be used.
098         * 
099         * @param csAccessKey
100         * @return an instance of a CRS-Configuration with the configured CRSProvider.
101         * @throws CRSConfigurationException
102         *             if --anything-- went wrong while instantiating the CRSProvider.
103         */
104        public synchronized static CRSConfiguration getCRSConfiguration()
105                                                                         throws CRSConfigurationException {
106            if ( CONFIG != null ) {
107                return CONFIG;
108            }
109            CRSProvider provider = null;
110    
111            LOG.logDebug( "Trying to load configured CRS provider from configuration (/crs_providers.properties)." );
112            InputStream is = CRSConfiguration.class.getResourceAsStream( "/" + PROVIDER_CONFIG );
113            if ( is == null ) {
114                LOG.logDebug( "Trying to load configured CRS provider from configuration (org.deegree.crs.configuration.crs_providers.properties)." );
115                is = CRSConfiguration.class.getResourceAsStream( PROVIDER_CONFIG );
116            }
117            if ( is == null ) {
118                LOG.logWarning( Messages.getMessage( "CRS_CONFIG_NO_PROVIDER_DEFS_FOUND", PROVIDER_CONFIG ) );
119                // create the standard deegree-crs-provider.
120                provider = new DeegreeCRSProvider( null );
121            } else {
122                Properties props = new Properties();
123                try {
124                    props.load( is );
125                } catch ( IOException e ) {
126                    LOG.logError( e.getMessage(), e );
127                } finally {
128                    try {
129                        is.close();
130                    } catch ( IOException e ) {
131                        // no output if the stream can't be closed, just leave it as it is.
132                    }
133                }
134    
135                String className = props.getProperty( "CRS_PROVIDER" );
136                if ( className == null || "".equals( className.trim() ) ) {
137                    LOG.logWarning( Messages.getMessage( "CRS_CONFIG_NO_PROVIDER_FOUND", PROVIDER_CONFIG ) );
138                    provider = new DeegreeCRSProvider( null );
139                } else if ( "org.deegree.crs.configuration.DeegreeCRSProvider".equals( className ) ){
140                    LOG.logDebug( "The configured CRS provider is a Deegree CRSProvider with name: "+ className );
141                    provider = new DeegreeCRSProvider( null );
142                } else{
143                    // use reflection to instantiate the configured provider.
144                    try {
145                        LOG.logDebug( "Trying to load configured CRS provider from classname: "+ className );
146                        provider = (CRSProvider) Class.forName( className ).newInstance();
147                    } catch ( InstantiationException e ) {
148                        LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ) );
149                    } catch ( IllegalAccessException e ) {
150                        LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e );
151                    } catch ( ClassNotFoundException e ) {
152    
153                        LOG.logError( Messages.getMessage( "CRS_CONFIG_INSTANTIATION_ERROR", className, e.getMessage() ), e );
154                    } finally {
155                        if ( provider == null ) {
156                            LOG.logInfo( "The configured class: " + className
157                                         + " was not created. Trying to create a deegree-crs-provider" );
158                            provider = new DeegreeCRSProvider( null );
159                        }
160                    }
161                }
162            }
163            if ( provider != null ) {
164                CONFIG = new CRSConfiguration( provider );
165            } else {
166                LOG.logError( Messages.getMessage( "CRS_CONFIG_NO_PROIVER_ERROR" ) );
167                throw new CRSConfigurationException( Messages.getMessage( "CRS_CONFIG_NO_PROIVER_ERROR" ) );
168            }
169            return CONFIG;
170    
171        }
172    
173        /**
174         * export the given file to the deegree-crs format.
175         * 
176         * @param args
177         */
178        public static void main( String[] args ) {
179            if ( args.length == 0 ) {
180                outputHelp();
181            }
182            Map<String, String> params = new HashMap<String, String>( 5 );
183            for ( int i = 0; i < args.length; i++ ) {
184                String arg = args[i];
185                if ( args != null && !"".equals( arg.trim() ) ) {
186                    arg = arg.trim();
187                    if ( arg.equalsIgnoreCase( "-?" ) || arg.equalsIgnoreCase( "-h" ) ) {
188                        outputHelp();
189                    } else {
190                        if ( i + 1 < args.length ) {
191                            String val = args[++i];
192                            if ( val != null && !"".equals( val.trim() ) ) {
193                                params.put( arg, val.trim() );
194                            } else {
195                                System.out.println( "Invalid value for parameter: " + arg );
196                            }
197                        } else {
198                            System.out.println( "No value for parameter: " + arg );
199                        }
200                    }
201                }
202            }
203            String inFormat = params.get( "-inFormat" );
204            if ( inFormat == null || "".equals( inFormat.trim() ) ) {
205                System.out.println( "No input format (inFormat) defined, setting to proj4" );
206                inFormat = "proj4";
207            }
208            String inFile = params.get( "-inFile" );
209            if ( inFile == null || "".equals( inFile.trim() ) ) {
210                System.out.println( "No input file set, exiting\n" );
211                outputHelp();
212                System.exit( 1 );
213            }
214            File inputFile = new File( inFile );
215    
216            String outFile = params.get( "-outFile" );
217            String outFormat = params.get( "-outFormat" );
218            if ( outFormat == null || "".equals( outFormat.trim() ) ) {
219                System.out.println( "No output format (outFormat) defined, setting to deegree" );
220                outFormat = "deegree";
221            }
222    
223            CRSProvider in = new PROJ4CRSProvider( inputFile );
224            if ( "deegree".equalsIgnoreCase( inFormat ) ) {
225                try {
226                    in = new DeegreeCRSProvider( inputFile );
227                } catch ( CRSConfigurationException e ) {
228                    e.printStackTrace();
229                }
230            }
231    
232            CRSProvider out = new DeegreeCRSProvider();
233            if ( "proj4".equalsIgnoreCase( outFormat ) ) {
234                out = new PROJ4CRSProvider();
235            }
236    
237            try {
238                List<CoordinateSystem> allSystems = in.getAvailableCRSs();
239                StringBuilder sb = new StringBuilder( allSystems.size() * 2000 );
240                out.export( sb, allSystems );
241                if ( outFile != null && !"".equals( outFile.trim() ) ) {
242                    File outputFile = new File( outFile );
243                    BufferedWriter writer = new BufferedWriter( new FileWriter( outputFile ) );
244                    writer.write( sb.toString() );
245                    writer.flush();
246                    writer.close();
247                } else {
248                    System.out.println( sb.toString() );
249                }
250            } catch ( CRSConfigurationException e ) {
251                e.printStackTrace();
252            } catch ( IOException e ) {
253                e.printStackTrace();
254            }
255    
256            // CRSConfiguration config = new CRSConfiguration(
257        }
258    
259        private static void outputHelp() {
260            StringBuilder sb = new StringBuilder();
261            sb.append( "The CRSConfiguration program can be used to create a deegree-crs-configuration, from other crs definition-formats. Following parameters are supported:\n" );
262            sb.append( "-inFile the /path/to/crs-definitions-file\n" );
263            sb.append( "-inFormat the format of the input file, valid values are proj4(default),deegree \n" );
264            sb.append( "-outFormat the format of the output file, valid values are deegree (default)\n" );
265            sb.append( "-outFile the /path/to/the/output/file or standard output if not supplied.\n" );
266            sb.append( "-?|-h output this text\n" );
267            sb.append( "example usage: java -cp deegree.jar org.deegree.crs.configuration.CRSConfiguration -inFormat 'proj4' -inFile '/home/proj4/nad/epsg' -outFormat 'deegree' -outFile '/home/deegree/crs-definitions.xml'\n" );
268            System.out.println( sb.toString() );
269            System.exit( 1 );
270        }
271    
272        /**
273         * @return the crs provider.
274         */
275        public final CRSProvider getProvider() {
276            return provider;
277        }
278    }