View Javadoc

1   package org.apache.maven.cli;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.text.SimpleDateFormat;
26  import java.util.Arrays;
27  import java.util.Date;
28  import java.util.Iterator;
29  import java.util.Locale;
30  import java.util.Properties;
31  import java.util.StringTokenizer;
32  import java.util.Map.Entry;
33  
34  import org.apache.commons.cli.CommandLine;
35  import org.apache.commons.cli.ParseException;
36  import org.apache.maven.Maven;
37  import org.apache.maven.SettingsConfigurationException;
38  import org.apache.maven.artifact.manager.WagonManager;
39  import org.apache.maven.artifact.repository.ArtifactRepository;
40  import org.apache.maven.artifact.repository.ArtifactRepositoryFactory;
41  import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
42  import org.apache.maven.artifact.repository.DefaultArtifactRepository;
43  import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
44  import org.apache.maven.execution.DefaultMavenExecutionRequest;
45  import org.apache.maven.execution.MavenExecutionRequest;
46  import org.apache.maven.execution.ReactorManager;
47  import org.apache.maven.monitor.event.DefaultEventDispatcher;
48  import org.apache.maven.monitor.event.DefaultEventMonitor;
49  import org.apache.maven.monitor.event.EventDispatcher;
50  import org.apache.maven.plugin.Mojo;
51  import org.apache.maven.profiles.DefaultProfileManager;
52  import org.apache.maven.profiles.ProfileManager;
53  import org.apache.maven.reactor.MavenExecutionException;
54  import org.apache.maven.settings.MavenSettingsBuilder;
55  import org.apache.maven.settings.RuntimeInfo;
56  import org.apache.maven.settings.Settings;
57  import org.codehaus.classworlds.ClassWorld;
58  import org.codehaus.plexus.PlexusContainerException;
59  import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException;
60  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
61  import org.codehaus.plexus.embed.Embedder;
62  import org.codehaus.plexus.logging.Logger;
63  import org.codehaus.plexus.logging.LoggerManager;
64  import org.codehaus.plexus.util.IOUtil;
65  import org.codehaus.plexus.util.Os;
66  import org.codehaus.plexus.util.StringUtils;
67  import org.codehaus.plexus.util.cli.CommandLineUtils;
68  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
69  import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
70  import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
71  import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
72  import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
73  import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
74  
75  /**
76   * @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
77   * @version $Id: MavenCli.java 746212 2009-02-20 11:36:05Z brett $
78   * @noinspection UseOfSystemOutOrSystemErr,ACCESS_STATIC_VIA_INSTANCE
79   */
80  public class MavenCli
81  {
82      /** @deprecated use {@link Os#OS_NAME} */
83      public static final String OS_NAME = Os.OS_NAME;
84  
85      /** @deprecated use {@link Os#OS_ARCH} */
86      public static final String OS_ARCH = Os.OS_ARCH;
87  
88      /** @deprecated use {@link Os#OS_VERSION} */
89      public static final String OS_VERSION = Os.OS_VERSION;
90  
91      private static Embedder embedder;
92  
93      public static void main( String[] args )
94      {
95          ClassWorld classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
96  
97          int result = main( args, classWorld );
98  
99          System.exit( result );
100     }
101 
102     /**
103      * @noinspection ConfusingMainMethod
104      */
105     public static int main( String[] args, ClassWorld classWorld )
106     {
107         // ----------------------------------------------------------------------
108         // Setup the command line parser
109         // ----------------------------------------------------------------------
110 
111         CLIManager cliManager = new CLIManager();
112 
113         CommandLine commandLine;
114         try
115         {
116             commandLine = cliManager.parse( args );
117         }
118         catch ( ParseException e )
119         {
120             System.err.println( "Unable to parse command line options: " + e.getMessage() );
121             cliManager.displayHelp();
122             return 1;
123         }
124 
125         boolean debug = commandLine.hasOption( CLIManager.DEBUG );
126 
127         boolean showErrors = debug || commandLine.hasOption( CLIManager.ERRORS );
128 
129         if ( showErrors )
130         {
131             System.out.println( "+ Error stacktraces are turned on." );
132         }
133 
134         // ----------------------------------------------------------------------
135         // Process particular command line options
136         // ----------------------------------------------------------------------
137 
138         if ( commandLine.hasOption( CLIManager.HELP ) )
139         {
140             cliManager.displayHelp();
141             return 0;
142         }
143         
144         if ( commandLine.hasOption( CLIManager.VERSION ) )
145         {
146             showVersion();
147 
148             return 0;
149         }
150         else if ( debug || commandLine.hasOption( CLIManager.SHOW_VERSION ) )
151         {
152             showVersion();
153         }
154 
155         EventDispatcher eventDispatcher = new DefaultEventDispatcher();
156 
157         // Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
158         // Windows paths.
159         String mavenHome = System.getProperty( "maven.home" );
160         if ( mavenHome != null )
161         {
162             System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
163         }
164 
165         // ----------------------------------------------------------------------
166         // Now that we have everything that we need we will fire up plexus and
167         // bring the maven component to life for use.
168         // ----------------------------------------------------------------------
169 
170         embedder = new Embedder();
171 
172         try
173         {
174             embedder.start( classWorld );
175         }
176         catch ( PlexusContainerException e )
177         {
178             showFatalError( "Unable to start the embedded plexus container", e, showErrors );
179 
180             return 1;
181         }
182 
183         // ----------------------------------------------------------------------
184         // The execution properties need to be created before the settings
185         // are constructed.
186         // ----------------------------------------------------------------------
187 
188         Properties executionProperties = new Properties();
189         Properties userProperties = new Properties();
190         populateProperties( commandLine, executionProperties, userProperties );
191 
192         Settings settings;
193 
194         try
195         {
196             settings = buildSettings( commandLine );
197         }
198         catch ( SettingsConfigurationException e )
199         {
200             showError( "Error reading settings.xml: " + e.getMessage(), e, showErrors );
201 
202             return 1;
203         }
204         catch ( ComponentLookupException e )
205         {
206             showFatalError( "Unable to read settings.xml", e, showErrors );
207 
208             return 1;
209         }
210 
211         DefaultSecDispatcher dispatcher;
212         try
213         {
214             if ( commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
215             {
216                 String passwd = commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
217 
218                 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
219 
220                 System.out.println( cipher.encryptAndDecorate( passwd,
221                                                                DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
222                 
223                 return 0;
224             }
225             else if ( commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
226             {
227                 String passwd = commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
228                 
229                 dispatcher = (DefaultSecDispatcher) embedder.lookup( SecDispatcher.ROLE );
230                 String configurationFile = dispatcher.getConfigurationFile();
231                 if ( configurationFile.startsWith( "~" ) )
232                 {
233                     configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
234                 }
235                 String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
236                 embedder.release( dispatcher );
237                 
238                 String master = null;
239                 
240                 SettingsSecurity sec = SecUtil.read( file, true );
241                 if ( sec != null )
242                 {
243                     master = sec.getMaster();
244                 }
245 
246                 if ( master == null )
247                 {
248                     System.err.println( "Master password is not set in the setting security file" );
249                     
250                     return 1;
251                 }
252                 
253                 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
254                 String masterPasswd =
255                     cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
256                 System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
257                 
258                 return 0;
259             }
260         }
261         catch ( Exception e )
262         {
263             showFatalError( "Error encrypting password: " + e.getMessage(), e, showErrors );
264             
265             return 1;
266         }
267             
268         Maven maven = null;
269 
270         MavenExecutionRequest request = null;
271 
272         LoggerManager loggerManager = null;
273 
274         try
275         {
276             // logger must be created first
277             loggerManager = (LoggerManager) embedder.lookup( LoggerManager.ROLE );
278 
279             if ( debug )
280             {
281                 loggerManager.setThreshold( Logger.LEVEL_DEBUG );
282             }
283             else if ( commandLine.hasOption( CLIManager.QUIET ) )
284             {
285                 // TODO: we need to do some more work here. Some plugins use sys out or log errors at info level.
286                 // Ideally, we could use Warn across the board
287                 loggerManager.setThreshold( Logger.LEVEL_ERROR );
288                 // TODO:Additionally, we can't change the mojo level because the component key includes the version and it isn't known ahead of time. This seems worth changing.
289             }
290 
291             ProfileManager profileManager = new DefaultProfileManager( embedder.getContainer(), executionProperties );
292 
293             if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
294             {
295                 String [] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
296 
297                 if ( profileOptionValues != null )
298                 {
299                     for ( int i=0; i < profileOptionValues.length; ++i )
300                     {
301                         StringTokenizer profileTokens = new StringTokenizer( profileOptionValues[i], "," );
302 
303                         while ( profileTokens.hasMoreTokens() )
304                         {
305                             String profileAction = profileTokens.nextToken().trim();
306 
307                             if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
308                             {
309                                 profileManager.explicitlyDeactivate( profileAction.substring( 1 ) );
310                             }
311                             else if ( profileAction.startsWith( "+" ) )
312                             {
313                                 profileManager.explicitlyActivate( profileAction.substring( 1 ) );
314                             }
315                             else
316                             {
317                                 profileManager.explicitlyActivate( profileAction );
318                             }
319                         }
320                     }
321                 }
322             }
323 
324             request = createRequest( commandLine, settings, eventDispatcher, loggerManager, profileManager,
325                                      executionProperties, userProperties, showErrors );
326 
327             setProjectFileOptions( commandLine, request );
328 
329             maven =
330                 createMavenInstance( settings.isInteractiveMode(),
331                                      loggerManager.getLoggerForComponent( WagonManager.ROLE ) );
332         }
333         catch ( ComponentLookupException e )
334         {
335             showFatalError( "Unable to configure the Maven application", e, showErrors );
336 
337             return 1;
338         }
339         finally
340         {
341             if ( loggerManager != null )
342             {
343                 try
344                 {
345                     embedder.release( loggerManager );
346                 }
347                 catch ( ComponentLifecycleException e )
348                 {
349                     showFatalError( "Error releasing logging manager", e, showErrors );
350                 }
351             }
352         }
353 
354         try
355         {
356             maven.execute( request );
357         }
358         catch ( MavenExecutionException e )
359         {
360             return 1;
361         }
362 
363         return 0;
364     }
365 
366     private static Settings buildSettings( CommandLine commandLine )
367         throws ComponentLookupException, SettingsConfigurationException
368     {
369         String userSettingsPath = null;
370 
371         if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
372         {
373             userSettingsPath = commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS );
374         }
375 
376         if ( commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
377         {
378             String globalSettingsPath = commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS );
379             System.setProperty( MavenSettingsBuilder.ALT_GLOBAL_SETTINGS_XML_LOCATION, globalSettingsPath );
380         }
381 
382         Settings settings = null;
383 
384         MavenSettingsBuilder settingsBuilder = (MavenSettingsBuilder) embedder.lookup( MavenSettingsBuilder.ROLE );
385 
386         try
387         {
388             if ( userSettingsPath != null )
389             {
390                 File userSettingsFile = new File( userSettingsPath );
391 
392                 if ( userSettingsFile.exists() && !userSettingsFile.isDirectory() )
393                 {
394                     settings = settingsBuilder.buildSettings( userSettingsFile );
395                 }
396                 else
397                 {
398                     System.out.println( "WARNING: Alternate user settings file: " + userSettingsPath +
399                         " is invalid. Using default path." );
400                 }
401             }
402 
403             if ( settings == null )
404             {
405                 settings = settingsBuilder.buildSettings();
406             }
407         }
408         catch ( IOException e )
409         {
410             throw new SettingsConfigurationException( "Error reading settings file", e );
411         }
412         catch ( XmlPullParserException e )
413         {
414             throw new SettingsConfigurationException( e.getMessage(), e, e.getLineNumber(),
415                                                       e.getColumnNumber() );
416         }
417 
418         // why aren't these part of the runtime info? jvz.
419 
420         if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
421         {
422             settings.setInteractiveMode( false );
423         }
424 
425         if ( commandLine.hasOption( CLIManager.SUPPRESS_PLUGIN_REGISTRY ) )
426         {
427             settings.setUsePluginRegistry( false );
428         }
429 
430         // Create settings runtime info
431 
432         settings.setRuntimeInfo( createRuntimeInfo( commandLine, settings ) );
433 
434         return settings;
435     }
436 
437     private static RuntimeInfo createRuntimeInfo( CommandLine commandLine, Settings settings )
438     {
439         RuntimeInfo runtimeInfo = new RuntimeInfo( settings );
440 
441         if ( commandLine.hasOption( CLIManager.FORCE_PLUGIN_UPDATES ) ||
442             commandLine.hasOption( CLIManager.FORCE_PLUGIN_UPDATES2 ) )
443         {
444             runtimeInfo.setPluginUpdateOverride( Boolean.TRUE );
445         }
446         else if ( commandLine.hasOption( CLIManager.SUPPRESS_PLUGIN_UPDATES ) )
447         {
448             runtimeInfo.setPluginUpdateOverride( Boolean.FALSE );
449         }
450 
451         return runtimeInfo;
452     }
453 
454 
455     private static void showFatalError( String message, Exception e, boolean show )
456     {
457         System.err.println( "FATAL ERROR: " + message );
458         if ( show )
459         {
460             System.err.println( "Error stacktrace:" );
461 
462             e.printStackTrace();
463         }
464         else
465         {
466             System.err.println( "For more information, run with the -e flag" );
467         }
468     }
469 
470     private static void showError( String message, Exception e, boolean show )
471     {
472         System.err.println( message );
473         if ( show )
474         {
475             System.err.println( "Error stacktrace:" );
476 
477             e.printStackTrace();
478         }
479     }
480 
481     private static MavenExecutionRequest createRequest( CommandLine commandLine, Settings settings,
482                                                         EventDispatcher eventDispatcher, LoggerManager loggerManager,
483                                                         ProfileManager profileManager, Properties executionProperties,
484                                                         Properties userProperties, boolean showErrors )
485         throws ComponentLookupException
486     {
487         MavenExecutionRequest request;
488 
489         ArtifactRepository localRepository = createLocalRepository( embedder, settings, commandLine );
490 
491         File userDir = new File( System.getProperty( "user.dir" ) );
492 
493         request = new DefaultMavenExecutionRequest( localRepository, settings, eventDispatcher,
494                                                     commandLine.getArgList(), userDir.getPath(), profileManager,
495                                                     executionProperties, userProperties, showErrors );
496 
497         // TODO [BP]: do we set one per mojo? where to do it?
498         Logger logger = loggerManager.getLoggerForComponent( Mojo.ROLE );
499 
500         if ( logger != null )
501         {
502             request.addEventMonitor( new DefaultEventMonitor( logger ) );
503         }
504 
505         if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
506         {
507             request.setRecursive( false );
508         }
509 
510         if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
511         {
512             request.setFailureBehavior( ReactorManager.FAIL_FAST );
513         }
514         else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
515         {
516             request.setFailureBehavior( ReactorManager.FAIL_AT_END );
517         }
518         else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
519         {
520             request.setFailureBehavior( ReactorManager.FAIL_NEVER );
521         }
522 
523         return request;
524     }
525 
526     private static void setProjectFileOptions( CommandLine commandLine, MavenExecutionRequest request )
527     {
528         if ( commandLine.hasOption( CLIManager.REACTOR ) )
529         {
530             request.setReactorActive( true );
531         }
532         else if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
533         {
534             request.setPomFile( commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE ) );
535         }
536         
537         if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
538         {
539             request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
540         }
541         
542         if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
543         {
544             String projectList = commandLine.getOptionValue( CLIManager.PROJECT_LIST );
545             String[] projects = StringUtils.split( projectList, "," );
546             request.setSelectedProjects( Arrays.asList( projects ) );
547         }
548         
549         if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
550         {
551             request.setMakeBehavior( ReactorManager.MAKE_MODE );
552         }
553         else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
554             && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
555         {
556             request.setMakeBehavior( ReactorManager.MAKE_DEPENDENTS_MODE );
557         }
558         if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
559         {
560             request.setMakeBehavior( ReactorManager.MAKE_BOTH_MODE );
561         }
562     }
563 
564     private static Maven createMavenInstance( boolean interactive, Logger logger )
565         throws ComponentLookupException
566     {
567         // TODO [BP]: doing this here as it is CLI specific, though it doesn't feel like the right place (likewise logger).
568         WagonManager wagonManager = (WagonManager) embedder.lookup( WagonManager.ROLE );
569         if ( interactive )
570         {
571             wagonManager.setDownloadMonitor( new ConsoleDownloadMonitor( logger ) );
572         }
573         else
574         {
575             wagonManager.setDownloadMonitor( new BatchModeDownloadMonitor( logger ) );
576         }
577 
578         wagonManager.setInteractive( interactive );
579 
580         return (Maven) embedder.lookup( Maven.ROLE );
581     }
582 
583     private static ArtifactRepository createLocalRepository( Embedder embedder, Settings settings,
584                                                              CommandLine commandLine )
585         throws ComponentLookupException
586     {
587         // TODO: release
588         // TODO: something in plexus to show all active hooks?
589         ArtifactRepositoryLayout repositoryLayout =
590             (ArtifactRepositoryLayout) embedder.lookup( ArtifactRepositoryLayout.ROLE, "default" );
591 
592         ArtifactRepositoryFactory artifactRepositoryFactory =
593             (ArtifactRepositoryFactory) embedder.lookup( ArtifactRepositoryFactory.ROLE );
594 
595         String url = settings.getLocalRepository();
596 
597         if ( !url.startsWith( "file:" ) )
598         {
599             url = "file://" + url;
600         }
601 
602         ArtifactRepository localRepository = new DefaultArtifactRepository( "local", url, repositoryLayout );
603 
604         boolean snapshotPolicySet = false;
605 
606         if ( commandLine.hasOption( CLIManager.OFFLINE ) )
607         {
608             settings.setOffline( true );
609 
610             snapshotPolicySet = true;
611         }
612 
613         if ( !snapshotPolicySet && commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
614         {
615             artifactRepositoryFactory.setGlobalUpdatePolicy( ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS );
616         }
617 
618         if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
619         {
620             System.out.println( "+ Enabling strict checksum verification on all artifact downloads." );
621 
622             artifactRepositoryFactory.setGlobalChecksumPolicy( ArtifactRepositoryPolicy.CHECKSUM_POLICY_FAIL );
623         }
624         else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
625         {
626             System.out.println( "+ Disabling strict checksum verification on all artifact downloads." );
627 
628             artifactRepositoryFactory.setGlobalChecksumPolicy( ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
629         }
630 
631         return localRepository;
632     }
633 
634     static Properties getBuildProperties()
635     {
636         Properties properties = new Properties();
637         InputStream resourceAsStream = null;
638         try
639         {
640             resourceAsStream = MavenCli.class.getClassLoader().getResourceAsStream( "org/apache/maven/messages/build.properties" );
641 
642             if ( resourceAsStream != null )
643             {
644                 properties.load( resourceAsStream );
645             }
646         }
647         catch ( IOException e )
648         {
649             System.err.println( "Unable determine version from JAR file: " + e.getMessage() );
650         }
651         finally
652         {
653             IOUtil.close( resourceAsStream );
654         }
655 
656         return properties;
657     }
658 
659     private static void showVersion()
660     {
661         Properties properties = getBuildProperties();
662 
663         String timestamp = reduce( properties.getProperty( "timestamp" ) );
664         String version = reduce( properties.getProperty( "version" ) );
665         String rev = reduce( properties.getProperty( "buildNumber" ) );
666 
667         String msg = "Apache Maven ";
668         msg += ( version != null ? version : "<version unknown>" );
669         if ( rev != null || timestamp != null )
670         {
671             msg += " (";
672             msg += ( rev != null ? "r" + rev : "" );
673             if ( timestamp != null )
674             {
675                 SimpleDateFormat fmt = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ssZ" );
676                 String ts = fmt.format( new Date( Long.valueOf( timestamp ).longValue() ) );
677                 msg += ( rev != null ? "; " : "" ) + ts;
678             }
679             msg += ")";
680         }
681 
682         System.out.println( msg );
683 
684         System.out.println( "Java version: " + System.getProperty( "java.version", "<unknown java version>" ) );
685 
686         System.out.println( "Java home: " + System.getProperty( "java.home", "<unknown java home>" ) );
687 
688         System.out.println( "Default locale: " + Locale.getDefault() + ", platform encoding: "
689                             + System.getProperty( "file.encoding", "<unknown encoding>" ) );
690 
691         System.out.println( "OS name: \"" + Os.OS_NAME + "\" version: \"" + Os.OS_VERSION +
692                             "\" arch: \"" + Os.OS_ARCH + "\" Family: \"" + Os.OS_FAMILY + "\"" );
693     }
694 
695     private static String reduce( String s )
696     {
697         return ( s != null ? ( s.startsWith( "${" ) && s.endsWith( "}" ) ? null : s ) : null );
698     }
699 
700     // ----------------------------------------------------------------------
701     // System properties handling
702     // ----------------------------------------------------------------------
703 
704     static void populateProperties( CommandLine commandLine, Properties executionProperties, Properties userProperties )
705     {
706         // add the env vars to the property set, with the "env." prefix
707         // XXX support for env vars should probably be removed from the ModelInterpolator
708         try
709         {
710             Properties envVars = CommandLineUtils.getSystemEnvVars();
711             Iterator i = envVars.entrySet().iterator();
712             while ( i.hasNext() )
713             {
714                 Entry e = (Entry) i.next();
715                 executionProperties.setProperty( "env." + e.getKey().toString(), e.getValue().toString() );
716             }
717         }
718         catch ( IOException e )
719         {
720             System.err.println( "Error getting environment vars for profile activation: " + e );
721         }
722 
723         // ----------------------------------------------------------------------
724         // Options that are set on the command line become system properties
725         // and therefore are set in the session properties. System properties
726         // are most dominant.
727         // ----------------------------------------------------------------------
728 
729         if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
730         {
731             String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
732 
733             if ( defStrs != null )
734             {
735                 for ( int i = 0; i < defStrs.length; ++i )
736                 {
737                     setCliProperty( defStrs[i], userProperties );
738                 }
739             }
740 
741             executionProperties.putAll( userProperties );
742         }
743 
744         executionProperties.putAll( System.getProperties() );
745     }
746 
747     private static void setCliProperty( String property, Properties requestProperties )
748     {
749         String name;
750 
751         String value;
752 
753         int i = property.indexOf( "=" );
754 
755         if ( i <= 0 )
756         {
757             name = property.trim();
758 
759             value = "true";
760         }
761         else
762         {
763             name = property.substring( 0, i ).trim();
764 
765             value = property.substring( i + 1 ).trim();
766         }
767 
768         requestProperties.setProperty( name, value );
769 
770         // ----------------------------------------------------------------------
771         // I'm leaving the setting of system properties here as not to break
772         // the SystemPropertyProfileActivator. This won't harm embedding. jvz.
773         // ----------------------------------------------------------------------
774 
775         System.setProperty( name, value );
776     }
777 }