KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > repository > cli > Main


1 /*
2  * Copyright 2004 Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.avalon.repository.cli;
19
20 import java.io.File JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.Properties JavaDoc;
24 import java.util.Locale JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.StringTokenizer JavaDoc;
27 import java.net.URL JavaDoc;
28
29 import javax.naming.directory.Attributes JavaDoc;
30
31 import org.apache.avalon.repository.Artifact;
32 import org.apache.avalon.repository.provider.InitialContext;
33 import org.apache.avalon.repository.RepositoryException;
34 import org.apache.avalon.repository.main.DefaultInitialContextFactory;
35 import org.apache.avalon.repository.main.DefaultBuilder;
36 import org.apache.avalon.repository.meta.ArtifactDescriptor;
37 import org.apache.avalon.repository.util.RepositoryUtils;
38
39 import org.apache.avalon.util.env.Env;
40 import org.apache.avalon.util.exception.ExceptionHelper;
41 import org.apache.avalon.util.i18n.ResourceManager;
42 import org.apache.avalon.util.i18n.Resources;
43
44 import org.apache.commons.cli.BasicParser;
45 import org.apache.commons.cli.CommandLine;
46 import org.apache.commons.cli.CommandLineParser;
47 import org.apache.commons.cli.HelpFormatter;
48 import org.apache.commons.cli.Option;
49 import org.apache.commons.cli.OptionBuilder;
50 import org.apache.commons.cli.Options;
51
52
53 /**
54  * Merlin command line handler.
55  *
56  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
57  * @version $Revision: 1.8 $
58  */

59 public class Main
60 {
61     //----------------------------------------------------------
62
// static
63
//----------------------------------------------------------
64

65     private static Resources REZ =
66         ResourceManager.getPackageResources( Main.class );
67
68     private static final File JavaDoc USER_HOME =
69       new File JavaDoc( System.getProperty( "user.home" ) );
70
71     private static final String JavaDoc AVALON_PROPERTIES = "avalon.properties";
72
73     private static final String JavaDoc IMPLEMENTATION_KEY = "avalon.repository.implementation";
74
75     private static Options CL_OPTIONS = buildCommandLineOptions();
76
77     private static Options buildCommandLineOptions()
78     {
79         Options options = new Options();
80
81         Option help = new Option(
82            "help",
83            REZ.getString( "cli-help-description" ) );
84
85         Option verify = new Option(
86            "verify",
87            REZ.getString( "cli-verify-description" ) );
88
89         Option version = new Option(
90            "version",
91            REZ.getString( "cli-version-description" ) );
92
93         Option locale = OptionBuilder
94            .hasArg()
95            .withArgName( "code" )
96            .withDescription( REZ.getString( "cli-language-description" ) )
97            .create( "lang" );
98
99         Option info = new Option(
100            "info",
101            REZ.getString( "cli-info-description" ) );
102
103         Option implementation = OptionBuilder
104            .hasArg()
105            .withArgName( "artifact" )
106            .withDescription( REZ.getString( "cli-implementation-description" ) )
107            .create( "impl" );
108
109         Option home = OptionBuilder
110            .hasArg()
111            .withArgName( REZ.getString( "directory" ) )
112            .withDescription( REZ.getString( "cli-home-description" ) )
113            .create( "home" );
114
115         Option cache = OptionBuilder
116            .hasArg()
117            .withArgName( REZ.getString( "directory" ) )
118            .withDescription( REZ.getString( "cli-cache-description" ) )
119            .create( "cache" );
120
121         Option hosts = OptionBuilder
122            .hasArg()
123            .withArgName( REZ.getString( "urls" ) )
124            .withDescription( REZ.getString( "cli-hosts-description" ) )
125            .create( "hosts" );
126
127         Option install = OptionBuilder
128            .hasArg()
129            .withArgName( REZ.getString( "url" ) )
130            .withDescription( REZ.getString( "cli-install-description" ) )
131            .create( "install" );
132
133         options.addOption( help );
134         options.addOption( locale );
135         options.addOption( version );
136         options.addOption( info );
137         options.addOption( implementation );
138         options.addOption( install );
139         options.addOption( home );
140         options.addOption( cache );
141         options.addOption( hosts );
142         options.addOption( verify );
143         return options;
144     }
145
146     private static Main MAIN = null;
147
148    /**
149     * Main command line enty point.
150     * @param args the command line arguments
151     */

152     public static void main( String JavaDoc[] args )
153     {
154         try
155         {
156             //
157
// parse the commandline
158
//
159

160             CommandLineParser parser = new BasicParser();
161             CommandLine line = parser.parse( CL_OPTIONS, args );
162
163             File JavaDoc dir = getWorkingDirectory( line );
164             File JavaDoc cache = getCacheDirectory( line );
165             Artifact artifact = getDefaultImplementation( dir, line );
166
167             if( line.hasOption( "version" ) )
168             {
169                 Main.printVersionInfo( cache, artifact );
170                 return;
171             }
172             else if( line.hasOption( "help" ) )
173             {
174                 doHelp( line );
175                 return;
176             }
177             else
178             {
179                 //
180
// setup the initial context
181
//
182

183                 ClassLoader JavaDoc parent = Main.class.getClassLoader();
184                 String JavaDoc[] hosts = getHostsPath( line );
185                 
186                 DefaultInitialContextFactory factory =
187                   new DefaultInitialContextFactory( "avalon", dir );
188                 factory.setCacheDirectory( cache );
189                 factory.setHosts( hosts );
190                 
191                 InitialContext context = factory.createInitialContext();
192
193                 //
194
// process the commandline and do the real work
195
//
196

197                 MAIN = new Main( context, line );
198             }
199         }
200         catch( Throwable JavaDoc e )
201         {
202             String JavaDoc msg =
203               ExceptionHelper.packException( e, true );
204             System.err.println( msg );
205             System.exit( -1 );
206         }
207     }
208
209     private static void doHelp( CommandLine line )
210     {
211         if( line.hasOption( "lang" ) )
212         {
213             ResourceManager.clearResourceCache();
214             String JavaDoc language = line.getOptionValue( "lang" );
215             Locale JavaDoc locale = new Locale JavaDoc( language, "" );
216             Locale.setDefault( locale );
217             REZ = ResourceManager.getPackageResources( Main.class );
218         }
219
220         HelpFormatter formatter = new HelpFormatter();
221         formatter.printHelp(
222           "repository [artifact]",
223           " ",
224           buildCommandLineOptions(),
225           "",
226           true );
227     }
228
229     //----------------------------------------------------------
230
// constructor
231
//----------------------------------------------------------
232

233    /**
234     * Creation of a new kernel cli handler.
235     * @param context the repository inital context
236     * @param line the command line construct
237     * @exception Exception if an error occurs
238     */

239     public Main(
240       InitialContext context, CommandLine line ) throws Exception JavaDoc
241     {
242         if( line.hasOption( "info" ) )
243         {
244             StringBuffer JavaDoc buffer =
245               new StringBuffer JavaDoc( InitialContext.LINE );
246             buffer.append( "\nAvalon Repository" );
247             buffer.append( InitialContext.LINE );
248             prepareInfoListing( buffer, context );
249             buffer.append( InitialContext.LINE );
250             System.out.println( buffer.toString() );
251         }
252
253         if( line.hasOption( "install" ) )
254         {
255             doInstall( context, line );
256         }
257         else if( line.hasOption( "verify" ) )
258         {
259             doVerify( context );
260         }
261         else
262         {
263             doHelp( line );
264         }
265     }
266
267     private void prepareInfoListing( StringBuffer JavaDoc buffer, InitialContext context )
268     {
269         buffer.append( "\n${avalon.repository.cache} = " );
270         buffer.append( context.getInitialCacheDirectory() );
271         buffer.append( "\n${avalon.dir} = " );
272         buffer.append( context.getInitialWorkingDirectory() );
273         String JavaDoc[] hosts = context.getInitialHosts();
274         buffer.append( "\n${avalon.repository.hosts} = (" );
275         buffer.append( hosts.length );
276         buffer.append( ")" );
277         for( int i=0; i<hosts.length; i++ )
278         {
279             buffer.append( "\n " + hosts[i] );
280         }
281     }
282
283     private void doInstall( InitialContext context, CommandLine line )
284       throws Exception JavaDoc
285     {
286         final URL JavaDoc url = getInstallTarget( line );
287         try
288         {
289             context.install( url );
290         }
291         catch( Throwable JavaDoc e )
292         {
293             final String JavaDoc error =
294               "Install failure: "
295               + url;
296             throw new RepositoryException( error, e );
297         }
298     }
299
300     private void doVerify( InitialContext context )
301       throws Exception JavaDoc
302     {
303         RepositoryVerifier verifier =
304           new RepositoryVerifier( context );
305         verifier.verify();
306     }
307
308
309     //----------------------------------------------------------
310
// implementation
311
//----------------------------------------------------------
312

313    /**
314     * Resolve the merlin.dir value.
315     * @param line the command line construct
316     * @return the working directory
317     */

318     private static File JavaDoc getWorkingDirectory( CommandLine line ) throws Exception JavaDoc
319     {
320         if( line.hasOption( "home" ) )
321         {
322             String JavaDoc dir = line.getOptionValue( "home" );
323             return new File JavaDoc( dir ).getCanonicalFile();
324         }
325         else
326         {
327             return getBaseDirectory();
328         }
329     }
330
331     private static String JavaDoc[] getHostsPath( CommandLine line )
332     {
333         if( line.hasOption( "hosts" ) )
334         {
335             String JavaDoc hosts = line.getOptionValue( "hosts" );
336             return expandHosts( hosts );
337         }
338         else
339         {
340             return null;
341         }
342     }
343
344     private static String JavaDoc[] expandHosts( String JavaDoc arg )
345     {
346         ArrayList JavaDoc list = new ArrayList JavaDoc();
347         StringTokenizer JavaDoc tokenizer = new StringTokenizer JavaDoc( arg, "," );
348         while( tokenizer.hasMoreTokens() )
349         {
350             String JavaDoc next = tokenizer.nextToken();
351             list.add( next );
352         }
353         return (String JavaDoc[]) list.toArray( new String JavaDoc[0] );
354     }
355
356    /**
357     * Return the url from the install parameter.
358     * @param line the command line construct
359     * @return the install target url
360     */

361     private URL JavaDoc getInstallTarget( CommandLine line ) throws IOException JavaDoc
362     {
363         String JavaDoc spec = line.getOptionValue( "install" );
364         return new URL JavaDoc( spec );
365     }
366
367    /**
368     * Resolve the default implementation taking into account
369     * command line arguments, local and hom properties, and
370     * application defaults.
371     * @param line the command line construct
372     * @return the artifact reference
373     */

374     private static Artifact getDefaultImplementation(
375       File JavaDoc base, CommandLine line ) throws Exception JavaDoc
376     {
377         if( line.hasOption( "impl" ) )
378         {
379             String JavaDoc spec = line.getOptionValue( "impl" );
380             return Artifact.createArtifact( spec );
381         }
382         else
383         {
384             return DefaultBuilder.createImplementationArtifact(
385                 Main.class.getClassLoader(),
386                 getAvalonHome(),
387                 getBaseDirectory(),
388                 AVALON_PROPERTIES,
389                 IMPLEMENTATION_KEY );
390         }
391     }
392
393    /**
394     * Print out version information to System.out. This function is
395     * invoked in response to the inclusion of the -version switch on
396     * the command line.
397     *
398     * @param cache the local system cache
399     * @param artifact the merlin implementation artifact descriptor
400     */

401     private static void printVersionInfo( File JavaDoc cache, Artifact artifact )
402     {
403         try
404         {
405             Attributes JavaDoc attr = RepositoryUtils.getAttributes( cache, artifact );
406             ArtifactDescriptor desc = new ArtifactDescriptor( attr );
407             System.out.println( "\n Implementation: "
408               + artifact.getGroup()
409               + ":" + artifact.getName()
410               + ";" + artifact.getVersion()
411               + " (" + desc.getBuild() + ")"
412             );
413         }
414         catch( Throwable JavaDoc e )
415         {
416             System.out.println( "\nImplementation: "
417               + artifact.getGroup()
418               + ":" + artifact.getName()
419               + ";" + artifact.getVersion() );
420         }
421     }
422
423    /**
424     * Return the avalon repository cache directory taking into
425     * account the supplied command-line, and avalon.properties files in
426     * the current and home directories.
427     *
428     * @param line the command line construct
429     * @return the merlin system root repository directory
430     */

431     private static File JavaDoc getCacheDirectory( CommandLine line )
432     {
433         if( line.hasOption( "cache" ) )
434         {
435             String JavaDoc system = line.getOptionValue( "cache" );
436             return new File JavaDoc( system );
437         }
438         else
439         {
440             return new File JavaDoc( getAvalonHome( ), "repository" );
441         }
442     }
443
444    /**
445     * Return the avalon home directory.
446     * @return the avalon home directory
447     */

448     private static File JavaDoc getAvalonHome()
449     {
450         return new File JavaDoc( getAvalonHomePath() );
451     }
452
453    /**
454     * Return the installation directory path.
455     * @return the merlin install directory path
456     */

457     private static String JavaDoc getAvalonHomePath()
458     {
459         return getHomePath( "AVALON_HOME", ".avalon" );
460     }
461
462    /**
463     * Return the merlin home directory path.
464     * @return the merlin install directory path
465     */

466     private static String JavaDoc getHomePath( final String JavaDoc var, final String JavaDoc dir )
467     {
468         try
469         {
470             String JavaDoc avalon =
471               System.getProperty(
472                 "avalon.home",
473                 Env.getEnvVariable( var ) );
474             if( null != avalon ) return avalon;
475             return System.getProperty( "user.home" )
476               + File.separator + dir;
477         }
478         catch( Throwable JavaDoc e )
479         {
480             final String JavaDoc error =
481               "Internal error while attempting to access AVALON_HOME environment.";
482             final String JavaDoc message =
483               ExceptionHelper.packException( error, e, true );
484             throw new RuntimeException JavaDoc( message );
485         }
486     }
487
488    /**
489     * Return the functional base directory. The implementation looks
490     * for the ${avalon.dir} system property and if not found, looks for
491     * the ${basedir} system property, and as a last resort, returns the
492     * JVM ${user.dir} value.
493     *
494     * @return the merlin install directory
495     */

496     private static File JavaDoc getBaseDirectory()
497     {
498         final String JavaDoc path = System.getProperty( "avalon.dir" );
499         if( null != path )
500         {
501             return new File JavaDoc( path );
502         }
503         final String JavaDoc base = System.getProperty( "basedir" );
504         if( null != base )
505         {
506             return new File JavaDoc( base );
507         }
508         return new File JavaDoc( System.getProperty( "user.dir" ) );
509     }
510
511    /**
512     * Return a property file from a fir with a supplied filename.
513     * @param dir the directory
514     * @param filename the filename
515     * @return a possibly empty properties instance
516     */

517     private static Properties JavaDoc getLocalProperties(
518       File JavaDoc dir, String JavaDoc filename )
519     {
520         Properties JavaDoc properties = new Properties JavaDoc();
521         if( null == dir ) return properties;
522         File JavaDoc file = new File JavaDoc( dir, filename );
523         if( !file.exists() ) return properties;
524         try
525         {
526             properties.load( new FileInputStream JavaDoc( file ) );
527             return properties;
528         }
529         catch( Throwable JavaDoc e )
530         {
531             final String JavaDoc error =
532               "Unexpected exception while attempting to read properties from: "
533               + file + ". Cause: " + e.toString();
534             throw new IllegalStateException JavaDoc( error );
535         }
536     }
537 }
538
Popular Tags