1/* 2 * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26/* 27 * This file is available under and governed by the GNU General Public 28 * License version 2 only, as published by the Free Software Foundation. 29 * However, the following notice accompanied the original version of this 30 * file: 31 * 32 * The MIT License 33 * 34 * Copyright (c) 2004-2014 Paul R. Holser, Jr. 35 * 36 * Permission is hereby granted, free of charge, to any person obtaining 37 * a copy of this software and associated documentation files (the 38 * "Software"), to deal in the Software without restriction, including 39 * without limitation the rights to use, copy, modify, merge, publish, 40 * distribute, sublicense, and/or sell copies of the Software, and to 41 * permit persons to whom the Software is furnished to do so, subject to 42 * the following conditions: 43 * 44 * The above copyright notice and this permission notice shall be 45 * included in all copies or substantial portions of the Software. 46 * 47 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 48 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 49 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 50 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 51 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 52 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 53 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 54 */ 55 56package jdk.internal.joptsimple; 57 58import java.util.List; 59 60import static java.util.Arrays.*; 61import static java.util.Collections.*; 62import static jdk.internal.joptsimple.internal.Reflection.*; 63 64/** 65 * <p>Specification of a command line's non-option arguments.</p> 66 * 67 * <p>Instances are returned from {@link OptionParser} methods to allow the formation of parser directives as 68 * sentences in a "fluent interface" language. For example:</p> 69 * 70 * <pre> 71 * <code> 72 * OptionParser parser = new OptionParser(); 73 * parser.nonOptions( "files to be processed" ).<strong>ofType( File.class )</strong>; 74 * </code> 75 * </pre> 76 * 77 * <p>If no methods are invoked on an instance of this class, then that instance's option will treat the non-option 78 * arguments as {@link String}s.</p> 79 * 80 * @param <V> represents the type of the non-option arguments 81 * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a> 82 */ 83public class NonOptionArgumentSpec<V> extends AbstractOptionSpec<V> { 84 static final String NAME = "[arguments]"; 85 86 private ValueConverter<V> converter; 87 private String argumentDescription = ""; 88 89 NonOptionArgumentSpec() { 90 this(""); 91 } 92 93 NonOptionArgumentSpec( String description ) { 94 super( asList( NAME ), description ); 95 } 96 97 /** 98 * <p>Specifies a type to which the non-option arguments are to be converted.</p> 99 * 100 * <p>JOpt Simple accepts types that have either:</p> 101 * 102 * <ol> 103 * <li>a public static method called {@code valueOf} which accepts a single argument of type {@link String} 104 * and whose return type is the same as the class on which the method is declared. The {@code java.lang} 105 * primitive wrapper classes have such methods.</li> 106 * 107 * <li>a public constructor which accepts a single argument of type {@link String}.</li> 108 * </ol> 109 * 110 * <p>This class converts arguments using those methods in that order; that is, {@code valueOf} would be invoked 111 * before a one-{@link String}-arg constructor would.</p> 112 * 113 * <p>Invoking this method will trump any previous calls to this method or to 114 * {@link #withValuesConvertedBy(ValueConverter)}.</p> 115 * 116 * @param <T> represents the runtime class of the desired option argument type 117 * @param argumentType desired type of arguments to this spec's option 118 * @return self, so that the caller can add clauses to the fluent interface sentence 119 * @throws NullPointerException if the type is {@code null} 120 * @throws IllegalArgumentException if the type does not have the standard conversion methods 121 */ 122 @SuppressWarnings( "unchecked" ) 123 public <T> NonOptionArgumentSpec<T> ofType( Class<T> argumentType ) { 124 converter = (ValueConverter<V>) findConverter( argumentType ); 125 return (NonOptionArgumentSpec<T>) this; 126 } 127 128 /** 129 * <p>Specifies a converter to use to translate non-option arguments into Java objects. This is useful 130 * when converting to types that do not have the requisite factory method or constructor for 131 * {@link #ofType(Class)}.</p> 132 * 133 * <p>Invoking this method will trump any previous calls to this method or to {@link #ofType(Class)}. 134 * 135 * @param <T> represents the runtime class of the desired non-option argument type 136 * @param aConverter the converter to use 137 * @return self, so that the caller can add clauses to the fluent interface sentence 138 * @throws NullPointerException if the converter is {@code null} 139 */ 140 @SuppressWarnings( "unchecked" ) 141 public final <T> NonOptionArgumentSpec<T> withValuesConvertedBy( ValueConverter<T> aConverter ) { 142 if ( aConverter == null ) 143 throw new NullPointerException( "illegal null converter" ); 144 145 converter = (ValueConverter<V>) aConverter; 146 return (NonOptionArgumentSpec<T>) this; 147 } 148 149 /** 150 * <p>Specifies a description for the non-option arguments that this spec represents. This description is used 151 * when generating help information about the parser.</p> 152 * 153 * @param description describes the nature of the argument of this spec's option 154 * @return self, so that the caller can add clauses to the fluent interface sentence 155 */ 156 public NonOptionArgumentSpec<V> describedAs( String description ) { 157 argumentDescription = description; 158 return this; 159 } 160 161 @Override 162 protected final V convert( String argument ) { 163 return convertWith( converter, argument ); 164 } 165 166 @Override 167 void handleOption( OptionParser parser, ArgumentList arguments, OptionSet detectedOptions, 168 String detectedArgument ) { 169 170 detectedOptions.addWithArgument( this, detectedArgument ); 171 } 172 173 public List<?> defaultValues() { 174 return emptyList(); 175 } 176 177 public boolean isRequired() { 178 return false; 179 } 180 181 public boolean acceptsArguments() { 182 return false; 183 } 184 185 public boolean requiresArgument() { 186 return false; 187 } 188 189 public String argumentDescription() { 190 return argumentDescription; 191 } 192 193 public String argumentTypeIndicator() { 194 return argumentTypeIndicatorFrom( converter ); 195 } 196 197 public boolean representsNonOptions() { 198 return true; 199 } 200} 201