Frames | No Frames |
1: /* 2: * Copyright 2003-2005 The Apache Software Foundation 3: * Copyright 2005 Stephen McConnell 4: * 5: * Licensed under the Apache License, Version 2.0 (the "License"); 6: * you may not use this file except in compliance with the License. 7: * You may obtain a copy of the License at 8: * 9: * http://www.apache.org/licenses/LICENSE-2.0 10: * 11: * Unless required by applicable law or agreed to in writing, software 12: * distributed under the License is distributed on an "AS IS" BASIS, 13: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14: * See the License for the specific language governing permissions and 15: * limitations under the License. 16: */ 17: package net.dpml.cli.commandline; 18: 19: import java.io.IOException; 20: 21: import java.util.LinkedList; 22: import java.util.List; 23: import java.util.ListIterator; 24: 25: import net.dpml.cli.CommandLine; 26: import net.dpml.cli.Group; 27: import net.dpml.cli.Option; 28: import net.dpml.cli.OptionException; 29: import net.dpml.cli.WriteableCommandLine; 30: import net.dpml.cli.resource.ResourceConstants; 31: import net.dpml.cli.util.HelpFormatter; 32: 33: /** 34: * A class that implements the <code>Parser</code> interface can parse a 35: * String array according to the {@link Group}specified and return a 36: * {@link CommandLine}. 37: * 38: * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a> 39: * @version @PROJECT-VERSION@ 40: */ 41: public class Parser 42: { 43: private HelpFormatter m_helpFormatter = new HelpFormatter(); 44: private Option m_helpOption = null; 45: private String m_helpTrigger = null; 46: private Group m_group = null; 47: 48: /** 49: * Parse the arguments according to the specified options and properties. 50: * 51: * @param arguments the command line arguments 52: * @return the list of atomic option and value tokens 53: * @throws OptionException if there are any problems encountered while parsing the 54: * command line tokens. 55: */ 56: public CommandLine parse( final String[] arguments ) throws OptionException 57: { 58: // build a mutable list for the arguments 59: final List argumentList = new LinkedList(); 60: 61: // copy the arguments into the new list 62: for( int i = 0; i < arguments.length; i++ ) 63: { 64: final String argument = arguments[i]; 65: 66: // ensure non intern'd strings are used 67: // so that == comparisons work as expected 68: argumentList.add( new String( argument ) ); 69: } 70: 71: // wet up a command line for this group 72: final WriteableCommandLine commandLine = 73: new WriteableCommandLineImpl( m_group, argumentList ); 74: 75: // pick up any defaults from the model 76: m_group.defaults( commandLine ); 77: 78: // process the options as far as possible 79: final ListIterator iterator = argumentList.listIterator(); 80: Object previous = null; 81: 82: while( m_group.canProcess( commandLine, iterator ) ) 83: { 84: // peek at the next item and backtrack 85: final Object next = iterator.next(); 86: iterator.previous(); 87: // if we have just tried to process this instance 88: if( next == previous ) 89: { 90: // abort 91: break; 92: } 93: // remember previous 94: previous = next; 95: m_group.process( commandLine, iterator ); 96: } 97: 98: // if there are more arguments we have a problem 99: if( iterator.hasNext() ) 100: { 101: final String arg = (String) iterator.next(); 102: throw new OptionException( 103: m_group, 104: ResourceConstants.UNEXPECTED_TOKEN, 105: arg ); 106: } 107: 108: // no need to validate if the help option is present 109: if( !commandLine.hasOption( m_helpOption ) && !commandLine.hasOption( m_helpTrigger ) ) 110: { 111: m_group.validate( commandLine ); 112: } 113: return commandLine; 114: } 115: 116: /** 117: * Parse the arguments according to the specified options and properties and 118: * displays the usage screen if the CommandLine is not valid or the help 119: * option was specified. 120: * 121: * @param arguments the command line arguments 122: * @return a valid CommandLine or null if the parse was unsuccessful 123: * @throws IOException if an error occurs while formatting help 124: */ 125: public CommandLine parseAndHelp( final String[] arguments ) throws IOException 126: { 127: m_helpFormatter.setGroup( m_group ); 128: 129: try 130: { 131: // attempt to parse the command line 132: final CommandLine commandLine = parse( arguments ); 133: if( !commandLine.hasOption( m_helpOption ) && !commandLine.hasOption( m_helpTrigger ) ) 134: { 135: return commandLine; 136: } 137: } 138: catch( final OptionException oe ) 139: { 140: // display help regarding the exception 141: m_helpFormatter.setException( oe ); 142: } 143: 144: // print help 145: m_helpFormatter.print(); 146: return null; 147: } 148: 149: /** 150: * Sets the Group of options to parse against 151: * @param group the group of options to parse against 152: */ 153: public void setGroup( final Group group ) 154: { 155: m_group = group; 156: } 157: 158: /** 159: * Sets the HelpFormatter to use with the simplified parsing. 160: * @see #parseAndHelp(String[]) 161: * @param helpFormatter the HelpFormatter to use with the simplified parsing 162: */ 163: public void setHelpFormatter( final HelpFormatter helpFormatter ) 164: { 165: m_helpFormatter = helpFormatter; 166: } 167: 168: /** 169: * Sets the help option to use with the simplified parsing. For example 170: * <code>--help</code>, <code>-h</code> and <code>-?</code> are often used. 171: * @see #parseAndHelp(String[]) 172: * @param helpOption the help Option 173: */ 174: public void setHelpOption( final Option helpOption ) 175: { 176: m_helpOption = helpOption; 177: } 178: 179: /** 180: * Sets the help option to use with the simplified parsing. For example 181: * <code>--help</code>, <code>-h</code> and <code>-?</code> are often used. 182: * @see #parseAndHelp(String[]) 183: * @param helpTrigger the trigger of the help Option 184: */ 185: public void setHelpTrigger( final String helpTrigger ) 186: { 187: m_helpTrigger = helpTrigger; 188: } 189: }