Coverage Report - org.apache.maven.it.util.cli.Commandline
 
Classes in this File Line Coverage Branch Coverage Complexity
Commandline
0%
0/175
0%
0/93
2.711
Commandline$Argument
0%
0/14
0%
0/4
2.711
Commandline$Marker
0%
0/10
0%
0/6
2.711
 
 1  
 package org.apache.maven.it.util.cli;
 2  
 
 3  
 /*
 4  
  * The MIT License
 5  
  *
 6  
  * Copyright (c) 2004, The Codehaus
 7  
  *
 8  
  * Permission is hereby granted, free of charge, to any person obtaining a copy of
 9  
  * this software and associated documentation files (the "Software"), to deal in
 10  
  * the Software without restriction, including without limitation the rights to
 11  
  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 12  
  * of the Software, and to permit persons to whom the Software is furnished to do
 13  
  * so, subject to the following conditions:
 14  
  *
 15  
  * The above copyright notice and this permission notice shall be included in all
 16  
  * copies or substantial portions of the Software.
 17  
  *
 18  
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 19  
  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 20  
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 21  
  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 22  
  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 23  
  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 24  
  * SOFTWARE.
 25  
  */
 26  
 
 27  
 /********************************************************************************
 28  
  * CruiseControl, a Continuous Integration Toolkit
 29  
  * Copyright (c) 2001-2003, ThoughtWorks, Inc.
 30  
  * 651 W Washington Ave. Suite 500
 31  
  * Chicago, IL 60661 USA
 32  
  * All rights reserved.
 33  
  *
 34  
  * Redistribution and use in source and binary forms, with or without
 35  
  * modification, are permitted provided that the following conditions
 36  
  * are met:
 37  
  *
 38  
  *     + Redistributions of source code must retain the above copyright
 39  
  *       notice, this list of conditions and the following disclaimer.
 40  
  *
 41  
  *     + Redistributions in binary form must reproduce the above
 42  
  *       copyright notice, this list of conditions and the following
 43  
  *       disclaimer in the documentation and/or other materials provided
 44  
  *       with the distribution.
 45  
  *
 46  
  *     + Neither the name of ThoughtWorks, Inc., CruiseControl, nor the
 47  
  *       names of its contributors may be used to endorse or promote
 48  
  *       products derived from this software without specific prior
 49  
  *       written permission.
 50  
  *
 51  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 52  
  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 53  
  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 54  
  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
 55  
  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 56  
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 57  
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 58  
  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 59  
  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 60  
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 61  
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 62  
  ********************************************************************************/
 63  
 
 64  
 /* ====================================================================
 65  
  * Copyright 2003-2004 The Apache Software Foundation.
 66  
  *
 67  
  * Licensed under the Apache License, Version 2.0 (the "License");
 68  
  * you may not use this file except in compliance with the License.
 69  
  * You may obtain a copy of the License at
 70  
  *
 71  
  *      http://www.apache.org/licenses/LICENSE-2.0
 72  
  *
 73  
  * Unless required by applicable law or agreed to in writing, software
 74  
  * distributed under the License is distributed on an "AS IS" BASIS,
 75  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 76  
  * See the License for the specific language governing permissions and
 77  
  * limitations under the License.
 78  
  * ====================================================================
 79  
  */
 80  
 
 81  
 import org.apache.maven.it.util.cli.shell.CommandShell;
 82  
 import org.apache.maven.it.util.cli.shell.CmdShell;
 83  
 import org.apache.maven.it.util.cli.shell.Shell;
 84  
 
 85  
 import java.io.File;
 86  
 import java.io.IOException;
 87  
 import java.util.ArrayList;
 88  
 import java.util.Arrays;
 89  
 import java.util.Iterator;
 90  
 import java.util.List;
 91  
 import java.util.Properties;
 92  
 import java.util.StringTokenizer;
 93  
 import java.util.Vector;
 94  
 import java.util.Hashtable;
 95  
 
 96  
 /**
 97  
  * <p/>
 98  
  * Commandline objects help handling command lines specifying processes to
 99  
  * execute.
 100  
  * </p>
 101  
  * <p/>
 102  
  * The class can be used to define a command line as nested elements or as a
 103  
  * helper to define a command line by an application.
 104  
  * </p>
 105  
  * <p/>
 106  
  * <code>
 107  
  * &lt;someelement&gt;<br>
 108  
  * &nbsp;&nbsp;&lt;acommandline executable="/executable/to/run"&gt;<br>
 109  
  * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 1" /&gt;<br>
 110  
  * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument line="argument_1 argument_2 argument_3" /&gt;<br>
 111  
  * &nbsp;&nbsp;&nbsp;&nbsp;&lt;argument value="argument 4" /&gt;<br>
 112  
  * &nbsp;&nbsp;&lt;/acommandline&gt;<br>
 113  
  * &lt;/someelement&gt;<br>
 114  
  * </code>
 115  
  * </p>
 116  
  * <p/>
 117  
  * The element <code>someelement</code> must provide a method
 118  
  * <code>createAcommandline</code> which returns an instance of this class.
 119  
  * </p>
 120  
  *
 121  
  * @author thomas.haas@softwired-inc.com
 122  
  * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
 123  
  */
 124  
 public class Commandline
 125  
     implements Cloneable
 126  
 {
 127  
     protected static final String OS_NAME = "os.name";
 128  
 
 129  
     protected static final String WINDOWS = "Windows";
 130  
 
 131  0
     protected String executable = null;
 132  
 
 133  0
     protected Vector arguments = new Vector();
 134  
 
 135  0
     protected Hashtable envVars = new Hashtable();
 136  
 
 137  0
     private File workingDir = null;
 138  
 
 139  0
     private long pid = -1;
 140  
 
 141  
     private Shell shell;
 142  
 
 143  
     /**
 144  
      * Create a new command line object.
 145  
      * Shell is autodetected from operating system
 146  
      *
 147  
      * @param toProcess
 148  
      */
 149  
     public Commandline( String toProcess )
 150  
     {
 151  0
         super();
 152  0
         setDefaultShell();
 153  0
         String[] tmp = new String[0];
 154  
         try
 155  
         {
 156  0
             tmp = translateCommandline( toProcess );
 157  
         }
 158  0
         catch ( Exception e )
 159  
         {
 160  0
             System.err.println( "Error translating Commandline." );
 161  0
         }
 162  0
         if ( tmp != null && tmp.length > 0 )
 163  
         {
 164  0
             setExecutable( tmp[0] );
 165  0
             for ( int i = 1; i < tmp.length; i++ )
 166  
             {
 167  0
                 createArgument().setValue( tmp[i] );
 168  
             }
 169  
         }
 170  0
     }
 171  
 
 172  
     /**
 173  
      * Create a new command line object.
 174  
      * Shell is autodetected from operating system
 175  
      */
 176  
     public Commandline()
 177  
     {
 178  0
         super();
 179  0
         setDefaultShell();
 180  0
     }
 181  
 
 182  
     public long getPid()
 183  
     {
 184  0
         if ( pid == -1 )
 185  
         {
 186  0
             pid = Long.parseLong( String.valueOf( System.currentTimeMillis() ) );
 187  
         }
 188  
 
 189  0
         return pid;
 190  
     }
 191  
 
 192  
     public void setPid( long pid )
 193  
     {
 194  0
         this.pid = pid;
 195  0
     }
 196  
 
 197  
     /**
 198  
      * Used for nested xml command line definitions.
 199  
      */
 200  0
     public static class Argument
 201  
     {
 202  
 
 203  
         private String[] parts;
 204  
 
 205  
         /**
 206  
          * Sets a single commandline argument.
 207  
          *
 208  
          * @param value a single commandline argument.
 209  
          */
 210  
         public void setValue( String value )
 211  
         {
 212  0
             if ( value != null )
 213  
             {
 214  0
                 parts = new String[]{value};
 215  
             }
 216  0
         }
 217  
 
 218  
         /**
 219  
          * Line to split into several commandline arguments.
 220  
          *
 221  
          * @param line line to split into several commandline arguments
 222  
          */
 223  
         public void setLine( String line )
 224  
         {
 225  0
             if ( line == null )
 226  
             {
 227  0
                 return;
 228  
             }
 229  
             try
 230  
             {
 231  0
                 parts = translateCommandline( line );
 232  
             }
 233  0
             catch ( Exception e )
 234  
             {
 235  0
                 System.err.println( "Error translating Commandline." );
 236  0
             }
 237  0
         }
 238  
 
 239  
         /**
 240  
          * Sets a single commandline argument to the absolute filename
 241  
          * of the given file.
 242  
          *
 243  
          * @param value a single commandline argument.
 244  
          */
 245  
         public void setFile( File value )
 246  
         {
 247  0
             parts = new String[]{value.getAbsolutePath()};
 248  0
         }
 249  
 
 250  
         /**
 251  
          * Returns the parts this Argument consists of.
 252  
          */
 253  
         public String[] getParts()
 254  
         {
 255  0
             return parts;
 256  
         }
 257  
     }
 258  
 
 259  
     /**
 260  
      * Class to keep track of the position of an Argument.
 261  
      */
 262  
     // <p>This class is there to support the srcfile and targetfile
 263  
     // elements of &lt;execon&gt; and &lt;transform&gt; - don't know
 264  
     // whether there might be additional use cases.</p> --SB
 265  
     public class Marker
 266  
     {
 267  
 
 268  
         private int position;
 269  
 
 270  0
         private int realPos = -1;
 271  
 
 272  
         Marker( int position )
 273  0
         {
 274  0
             this.position = position;
 275  0
         }
 276  
 
 277  
         /**
 278  
          * Return the number of arguments that preceeded this marker.
 279  
          * <p/>
 280  
          * <p>The name of the executable - if set - is counted as the
 281  
          * very first argument.</p>
 282  
          */
 283  
         public int getPosition()
 284  
         {
 285  0
             if ( realPos == -1 )
 286  
             {
 287  0
                 realPos = ( executable == null ? 0 : 1 );
 288  0
                 for ( int i = 0; i < position; i++ )
 289  
                 {
 290  0
                     Argument arg = (Argument) arguments.elementAt( i );
 291  0
                     realPos += arg.getParts().length;
 292  
                 }
 293  
             }
 294  0
             return realPos;
 295  
         }
 296  
     }
 297  
 
 298  
 
 299  
     /**
 300  
      * <p>Sets the shell or command-line interpretor for the detected operating system,
 301  
      * and the shell arguments.</p>
 302  
      */
 303  
     private void setDefaultShell()
 304  
     {
 305  0
         String os = System.getProperty( OS_NAME );
 306  
 
 307  
         //If this is windows set the shell to command.com or cmd.exe with correct arguments.
 308  0
         if ( os.indexOf( WINDOWS ) > -1 )
 309  
         {
 310  0
             if ( os.indexOf( "95" ) > -1 || os.indexOf( "98" ) > -1 || os.indexOf( "Me" ) > -1 )
 311  
             {
 312  0
                 setShell( new CommandShell() );
 313  
             }
 314  
             else
 315  
             {
 316  0
                 setShell( new CmdShell() );
 317  
             }
 318  
         }
 319  0
     }
 320  
 
 321  
     /**
 322  
      * Creates an argument object.
 323  
      * <p/>
 324  
      * <p>Each commandline object has at most one instance of the
 325  
      * argument class.  This method calls
 326  
      * <code>this.createArgument(false)</code>.</p>
 327  
      *
 328  
      * @return the argument object.
 329  
      * @see #createArgument(boolean)
 330  
      */
 331  
     public Argument createArgument()
 332  
     {
 333  0
         return this.createArgument( false );
 334  
     }
 335  
 
 336  
     /**
 337  
      * Creates an argument object and adds it to our list of args.
 338  
      * <p/>
 339  
      * <p>Each commandline object has at most one instance of the
 340  
      * argument class.</p>
 341  
      *
 342  
      * @param insertAtStart if true, the argument is inserted at the
 343  
      *                      beginning of the list of args, otherwise it is appended.
 344  
      */
 345  
     public Argument createArgument( boolean insertAtStart )
 346  
     {
 347  0
         Argument argument = new Argument();
 348  0
         if ( insertAtStart )
 349  
         {
 350  0
             arguments.insertElementAt( argument, 0 );
 351  
         }
 352  
         else
 353  
         {
 354  0
             arguments.addElement( argument );
 355  
         }
 356  0
         return argument;
 357  
     }
 358  
 
 359  
     /**
 360  
      * Sets the executable to run.
 361  
      */
 362  
     public void setExecutable( String executable )
 363  
     {
 364  0
         if ( executable == null || executable.length() == 0 )
 365  
         {
 366  0
             return;
 367  
         }
 368  0
         this.executable = executable.replace( '/', File.separatorChar ).replace( '\\', File.separatorChar );
 369  0
     }
 370  
 
 371  
     public String getExecutable()
 372  
     {
 373  0
         return executable;
 374  
     }
 375  
 
 376  
     public void addArguments( String[] line )
 377  
     {
 378  0
         for ( int i = 0; i < line.length; i++ )
 379  
         {
 380  0
             createArgument().setValue( line[i] );
 381  
         }
 382  0
     }
 383  
 
 384  
     /**
 385  
      * Add an environment variable
 386  
      */
 387  
     public void addEnvironment( String name,
 388  
                                 String value )
 389  
     {
 390  0
         envVars.put( name, name + "=" + value );
 391  0
     }
 392  
 
 393  
     /**
 394  
      * Add system environment variables
 395  
      */
 396  
     public void addSystemEnvironment()
 397  
         throws Exception
 398  
     {
 399  0
         Properties envVars = CommandLineUtils.getSystemEnvVars();
 400  
 
 401  0
         for ( Iterator i = envVars.keySet().iterator(); i.hasNext(); )
 402  
         {
 403  0
             String key = (String) i.next();
 404  
 
 405  0
             if ( !this.envVars.containsKey( key ) )
 406  
             {
 407  0
                 this.envVars.put( key, key + "=" + envVars.getProperty( key ) );
 408  
             }
 409  0
         }
 410  0
     }
 411  
 
 412  
     /**
 413  
      * Return the list of environment variables
 414  
      */
 415  
     public String[] getEnvironmentVariables()
 416  
         throws CommandLineException
 417  
     {
 418  
         try
 419  
         {
 420  0
             addSystemEnvironment();
 421  
         }
 422  0
         catch ( Exception e )
 423  
         {
 424  0
             throw new CommandLineException( "Error setting up environmental variables", e );
 425  0
         }
 426  
 
 427  0
         return (String[]) envVars.values().toArray( new String[envVars.size()] );
 428  
     }
 429  
 
 430  
     /**
 431  
      * Returns the executable and all defined arguments.
 432  
      */
 433  
     public String[] getCommandline()
 434  
     {
 435  0
         final String[] args = getArguments();
 436  0
         if ( executable == null )
 437  
         {
 438  0
             return args;
 439  
         }
 440  0
         final String[] result = new String[args.length + 1];
 441  0
         result[0] = executable;
 442  0
         System.arraycopy( args, 0, result, 1, args.length );
 443  0
         return result;
 444  
     }
 445  
 
 446  
     /**
 447  
      * Returns the shell, executable and all defined arguments.
 448  
      */
 449  
     public String[] getShellCommandline()
 450  
     {
 451  
 
 452  0
         if ( getShell() == null )
 453  
         {
 454  0
             if ( executable != null )
 455  
             {
 456  0
                 List commandLine = new ArrayList();
 457  0
                 commandLine.add( executable );
 458  0
                 commandLine.addAll( Arrays.asList( getArguments() ) );
 459  0
                 return (String[]) commandLine.toArray( new String[0] );
 460  
             }
 461  
             else
 462  
             {
 463  0
                 return getArguments();
 464  
             }
 465  
 
 466  
         }
 467  
         else
 468  
         {
 469  0
             return (String[]) getShell().getShellCommandLine( executable, getArguments() ).toArray( new String[0] );
 470  
         }
 471  
     }
 472  
 
 473  
     /**
 474  
      * Returns all arguments defined by <code>addLine</code>,
 475  
      * <code>addValue</code> or the argument object.
 476  
      */
 477  
     public String[] getArguments()
 478  
     {
 479  0
         Vector result = new Vector( arguments.size() * 2 );
 480  0
         for ( int i = 0; i < arguments.size(); i++ )
 481  
         {
 482  0
             Argument arg = (Argument) arguments.elementAt( i );
 483  0
             String[] s = arg.getParts();
 484  0
             if ( s != null )
 485  
             {
 486  0
                 for ( int j = 0; j < s.length; j++ )
 487  
                 {
 488  0
                     result.addElement( s[j] );
 489  
                 }
 490  
             }
 491  
         }
 492  
 
 493  0
         String[] res = new String[result.size()];
 494  0
         result.copyInto( res );
 495  0
         return res;
 496  
     }
 497  
 
 498  
     public String toString()
 499  
     {
 500  0
         return toString( getCommandline() );
 501  
     }
 502  
 
 503  
     /**
 504  
      * <p>Put quotes around the given String if necessary.</p>
 505  
      * <p>If the argument doesn't include spaces or quotes, return it
 506  
      * as is. If it contains double quotes, use single quotes - else
 507  
      * surround the argument by double quotes.</p>
 508  
      *
 509  
      * @throws CommandLineException if the argument contains both, single
 510  
      *                              and double quotes.
 511  
      */
 512  
     public static String quoteArgument( String argument )
 513  
         throws CommandLineException
 514  
     {
 515  0
         if ( argument.indexOf( '\"' ) > -1 )
 516  
         {
 517  0
             if ( argument.indexOf( '\'' ) > -1 )
 518  
             {
 519  0
                 throw new CommandLineException( "Can't handle single and double quotes in same argument" );
 520  
             }
 521  
             else
 522  
             {
 523  0
                 return '\'' + argument + '\'';
 524  
             }
 525  
         }
 526  0
         else if ( containsAny( argument, "'<>&|*? " ) )
 527  
         {
 528  0
             return '\"' + argument + '\"';
 529  
         }
 530  
         else
 531  
         {
 532  0
             return argument;
 533  
         }
 534  
     }
 535  
 
 536  
     private static boolean containsAny( String argument, String chars )
 537  
     {
 538  0
         for ( int i = chars.length() - 1; i >= 0; i-- )
 539  
         {
 540  0
             if ( argument.indexOf( chars.charAt( i ) ) >= 0 )
 541  
             {
 542  0
                 return true;
 543  
             }
 544  
         }
 545  0
         return false;
 546  
     }
 547  
 
 548  
     public static String toString( String[] line )
 549  
     {
 550  
         // empty path return empty string
 551  0
         if ( line == null || line.length == 0 )
 552  
         {
 553  0
             return "";
 554  
         }
 555  
 
 556  
         // path containing one or more elements
 557  0
         final StringBuffer result = new StringBuffer();
 558  0
         for ( int i = 0; i < line.length; i++ )
 559  
         {
 560  0
             if ( i > 0 )
 561  
             {
 562  0
                 result.append( ' ' );
 563  
             }
 564  
             try
 565  
             {
 566  0
                 result.append( quoteArgument( line[i] ) );
 567  
             }
 568  0
             catch ( Exception e )
 569  
             {
 570  0
                 System.err.println( "Error quoting argument." );
 571  0
             }
 572  
         }
 573  0
         return result.toString();
 574  
     }
 575  
 
 576  
     public static String[] translateCommandline( String toProcess )
 577  
         throws Exception
 578  
     {
 579  0
         if ( toProcess == null || toProcess.length() == 0 )
 580  
         {
 581  0
             return new String[0];
 582  
         }
 583  
 
 584  
         // parse with a simple finite state machine
 585  
 
 586  0
         final int normal = 0;
 587  0
         final int inQuote = 1;
 588  0
         final int inDoubleQuote = 2;
 589  0
         int state = normal;
 590  0
         StringTokenizer tok = new StringTokenizer( toProcess, "\"\' ", true );
 591  0
         Vector v = new Vector();
 592  0
         StringBuffer current = new StringBuffer();
 593  
 
 594  0
         while ( tok.hasMoreTokens() )
 595  
         {
 596  0
             String nextTok = tok.nextToken();
 597  0
             switch ( state )
 598  
             {
 599  
                 case inQuote:
 600  0
                     if ( "\'".equals( nextTok ) )
 601  
                     {
 602  0
                         state = normal;
 603  
                     }
 604  
                     else
 605  
                     {
 606  0
                         current.append( nextTok );
 607  
                     }
 608  0
                     break;
 609  
                 case inDoubleQuote:
 610  0
                     if ( "\"".equals( nextTok ) )
 611  
                     {
 612  0
                         state = normal;
 613  
                     }
 614  
                     else
 615  
                     {
 616  0
                         current.append( nextTok );
 617  
                     }
 618  0
                     break;
 619  
                 default:
 620  0
                     if ( "\'".equals( nextTok ) )
 621  
                     {
 622  0
                         state = inQuote;
 623  
                     }
 624  0
                     else if ( "\"".equals( nextTok ) )
 625  
                     {
 626  0
                         state = inDoubleQuote;
 627  
                     }
 628  0
                     else if ( " ".equals( nextTok ) )
 629  
                     {
 630  0
                         if ( current.length() != 0 )
 631  
                         {
 632  0
                             v.addElement( current.toString() );
 633  0
                             current.setLength( 0 );
 634  
                         }
 635  
                     }
 636  
                     else
 637  
                     {
 638  0
                         current.append( nextTok );
 639  
                     }
 640  
                     break;
 641  
             }
 642  0
         }
 643  
 
 644  0
         if ( current.length() != 0 )
 645  
         {
 646  0
             v.addElement( current.toString() );
 647  
         }
 648  
 
 649  0
         if ( state == inQuote || state == inDoubleQuote )
 650  
         {
 651  0
             throw new CommandLineException( "unbalanced quotes in " + toProcess );
 652  
         }
 653  
 
 654  0
         String[] args = new String[v.size()];
 655  0
         v.copyInto( args );
 656  0
         return args;
 657  
     }
 658  
 
 659  
     public int size()
 660  
     {
 661  0
         return getCommandline().length;
 662  
     }
 663  
 
 664  
     public Object clone()
 665  
     {
 666  0
         Commandline c = new Commandline();
 667  0
         c.setExecutable( executable );
 668  0
         c.addArguments( getArguments() );
 669  0
         return c;
 670  
     }
 671  
 
 672  
     /**
 673  
      * Clear out the whole command line.
 674  
      */
 675  
     public void clear()
 676  
     {
 677  0
         executable = null;
 678  0
         arguments.removeAllElements();
 679  0
     }
 680  
 
 681  
     /**
 682  
      * Clear out the arguments but leave the executable in place for another operation.
 683  
      */
 684  
     public void clearArgs()
 685  
     {
 686  0
         arguments.removeAllElements();
 687  0
     }
 688  
 
 689  
     /**
 690  
      * Return a marker.
 691  
      * <p/>
 692  
      * <p>This marker can be used to locate a position on the
 693  
      * commandline - to insert something for example - when all
 694  
      * parameters have been set.</p>
 695  
      */
 696  
     public Marker createMarker()
 697  
     {
 698  0
         return new Marker( arguments.size() );
 699  
     }
 700  
 
 701  
     /**
 702  
      * Sets execution directory.
 703  
      */
 704  
     public void setWorkingDirectory( String path )
 705  
     {
 706  0
         if ( path != null )
 707  
         {
 708  0
             workingDir = new File( path );
 709  
         }
 710  0
     }
 711  
 
 712  
     public File getWorkingDirectory()
 713  
     {
 714  0
         return workingDir;
 715  
     }
 716  
 
 717  
     /**
 718  
      * Executes the command.
 719  
      */
 720  
     public Process execute()
 721  
         throws CommandLineException
 722  
     {
 723  
         Process process;
 724  
 
 725  
         //addEnvironment( "MAVEN_TEST_ENVAR", "MAVEN_TEST_ENVAR_VALUE" );
 726  
 
 727  0
         String[] environment = getEnvironmentVariables();
 728  
 
 729  
         try
 730  
         {
 731  0
             if ( workingDir == null )
 732  
             {
 733  0
                 process = Runtime.getRuntime().exec( getShellCommandline(), environment );
 734  
             }
 735  
             else
 736  
             {
 737  0
                 if ( !workingDir.exists() )
 738  
                 {
 739  0
                     throw new CommandLineException(
 740  
                         "Working directory \"" + workingDir.getPath() + "\" does not exist!" );
 741  
                 }
 742  0
                 else if ( !workingDir.isDirectory() )
 743  
                 {
 744  0
                     throw new CommandLineException(
 745  
                         "Path \"" + workingDir.getPath() + "\" does not specify a directory." );
 746  
                 }
 747  
 
 748  0
                 process = Runtime.getRuntime().exec( getShellCommandline(), environment, workingDir );
 749  
             }
 750  
         }
 751  0
         catch ( IOException ex )
 752  
         {
 753  0
             throw new CommandLineException( "Error while executing process.", ex );
 754  0
         }
 755  
 
 756  0
         return process;
 757  
     }
 758  
 
 759  
     public Properties getSystemEnvVars()
 760  
         throws Exception
 761  
     {
 762  0
         return CommandLineUtils.getSystemEnvVars();
 763  
     }
 764  
 
 765  
     /**
 766  
      * Allows to set the shell to be used in this command line.
 767  
      *
 768  
      * @param shell
 769  
      * @since 1.2
 770  
      */
 771  
     public void setShell( Shell shell )
 772  
     {
 773  0
         this.shell = shell;
 774  0
     }
 775  
 
 776  
     /**
 777  
      * Get the shell to be used in this command line.
 778  
      *
 779  
      * @since 1.2
 780  
      */
 781  
     public Shell getShell()
 782  
     {
 783  0
         return shell;
 784  
     }
 785  
 }