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.option; 18: 19: import java.util.ArrayList; 20: import java.util.Comparator; 21: import java.util.Iterator; 22: import java.util.List; 23: import java.util.Set; 24: 25: import net.dpml.cli.Argument; 26: import net.dpml.cli.Option; 27: import net.dpml.cli.OptionException; 28: import net.dpml.cli.WriteableCommandLine; 29: import net.dpml.cli.resource.ResourceConstants; 30: import net.dpml.cli.resource.ResourceHelper; 31: 32: /** 33: * An Argument implementation that allows a variable size Argument to precede a 34: * fixed size argument. The canonical example of it's use is in the unix 35: * <code>cp</code> command where a number of source can be specified with 36: * exactly one destination specfied at the end. 37: * @author <a href="@PUBLISHER-URL@">@PUBLISHER-NAME@</a> 38: * @version @PROJECT-VERSION@ 39: */ 40: public class SourceDestArgument extends ArgumentImpl 41: { 42: private final Argument m_source; 43: private final Argument m_dest; 44: 45: /** 46: * Creates a SourceDestArgument using defaults where possible. 47: * 48: * @param source the variable size Argument 49: * @param dest the fixed size Argument 50: */ 51: public SourceDestArgument( 52: final Argument source, final Argument dest ) 53: { 54: this( 55: source, 56: dest, 57: DEFAULT_INITIAL_SEPARATOR, 58: DEFAULT_SUBSEQUENT_SEPARATOR, 59: DEFAULT_CONSUME_REMAINING, 60: null ); 61: } 62: 63: /** 64: * Creates a SourceDestArgument using the specified parameters. 65: * 66: * @param source the variable size Argument 67: * @param dest the fixed size Argument 68: * @param initialSeparator the inistial separator to use 69: * @param subsequentSeparator the subsequent separator to use 70: * @param consumeRemaining the token triggering consume remaining behaviour 71: * @param defaultValues the default values for the SourceDestArgument 72: */ 73: public SourceDestArgument( 74: final Argument source, final Argument dest, final char initialSeparator, 75: final char subsequentSeparator, final String consumeRemaining, 76: final List defaultValues ) 77: { 78: super( 79: "SourceDestArgument", null, sum( source.getMinimum(), dest.getMinimum() ), 80: sum( source.getMaximum(), dest.getMaximum() ), initialSeparator, 81: subsequentSeparator, null, consumeRemaining, defaultValues, 0 ); 82: 83: m_source = source; 84: m_dest = dest; 85: 86: if( dest.getMinimum() != dest.getMaximum() ) 87: { 88: throw new IllegalArgumentException( 89: ResourceHelper.getResourceHelper().getMessage( 90: ResourceConstants.SOURCE_DEST_MUST_ENFORCE_VALUES ) ); 91: } 92: } 93: 94: private static int sum( final int a, final int b ) 95: { 96: return Math.max( a, Math.max( b, a + b ) ); 97: } 98: 99: /** 100: * Appends usage information to the specified StringBuffer 101: * 102: * @param buffer the buffer to append to 103: * @param helpSettings a set of display settings @see DisplaySetting 104: * @param comp a comparator used to sort the Options 105: */ 106: public void appendUsage( 107: final StringBuffer buffer, final Set helpSettings, final Comparator comp ) 108: { 109: final int length = buffer.length(); 110: 111: m_source.appendUsage( buffer, helpSettings, comp ); 112: 113: if( buffer.length() != length ) 114: { 115: buffer.append( ' ' ); 116: } 117: 118: m_dest.appendUsage( buffer, helpSettings, comp ); 119: } 120: 121: /** 122: * Builds up a list of HelpLineImpl instances to be presented by HelpFormatter. 123: * 124: * @see net.dpml.cli.HelpLine 125: * @see net.dpml.cli.util.HelpFormatter 126: * @param depth the initial indent depth 127: * @param helpSettings the HelpSettings that should be applied 128: * @param comp a comparator used to sort options when applicable. 129: * @return a List of HelpLineImpl objects 130: */ 131: public List helpLines( 132: int depth, Set helpSettings, Comparator comp ) 133: { 134: final List helpLines = new ArrayList(); 135: helpLines.addAll( m_source.helpLines( depth, helpSettings, comp ) ); 136: helpLines.addAll( m_dest.helpLines( depth, helpSettings, comp ) ); 137: return helpLines; 138: } 139: 140: /** 141: * Checks that the supplied CommandLine is valid with respect to the 142: * suppled option. 143: * 144: * @param commandLine the CommandLine to check. 145: * @param option the option to evaluate 146: * @throws OptionException if the CommandLine is not valid. 147: */ 148: public void validate( WriteableCommandLine commandLine, Option option ) 149: throws OptionException 150: { 151: final List values = commandLine.getValues( option ); 152: 153: final int limit = values.size() - m_dest.getMinimum(); 154: int count = 0; 155: 156: final Iterator i = values.iterator(); 157: 158: while( count++ < limit ) 159: { 160: commandLine.addValue( m_source, i.next() ); 161: } 162: 163: while( i.hasNext() ) 164: { 165: commandLine.addValue( m_dest, i.next() ); 166: } 167: 168: m_source.validate( commandLine, m_source ); 169: m_dest.validate( commandLine, m_dest ); 170: } 171: 172: /** 173: * Indicates whether this Option will be able to process the particular 174: * argument. 175: * 176: * @param commandLine the CommandLine object to store defaults in 177: * @param arg the argument to be tested 178: * @return true if the argument can be processed by this Option 179: */ 180: public boolean canProcess( 181: final WriteableCommandLine commandLine, final String arg ) 182: { 183: return m_source.canProcess( commandLine, arg ) || m_dest.canProcess( commandLine, arg ); 184: } 185: }