001/* 002 * Copyright 2011-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2011-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.util.args; 022 023 024 025import java.text.ParseException; 026import java.util.ArrayList; 027import java.util.Collections; 028import java.util.List; 029 030import com.unboundid.util.Debug; 031import com.unboundid.util.Mutable; 032import com.unboundid.util.StaticUtils; 033import com.unboundid.util.ThreadSafety; 034import com.unboundid.util.ThreadSafetyLevel; 035 036import static com.unboundid.util.args.ArgsMessages.*; 037 038 039 040/** 041 * This class defines an argument whose values are intended to be argument 042 * strings as might be provided to a command-line application (e.g., 043 * "--arg1 arg1value --arg2 --arg3 arg3value"). Instances of this argument 044 * will have their own argument parser that may be used to process the argument 045 * strings. This type of argument may not be particularly useful for use in 046 * command-line applications, but may be used in other applications that may use 047 * arguments in other ways. 048 */ 049@Mutable() 050@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 051public final class ArgumentListArgument 052 extends Argument 053{ 054 /** 055 * The serial version UID for this serializable class. 056 */ 057 private static final long serialVersionUID = 1926330851837348378L; 058 059 060 061 // The argument parser that will be used to validate values given for this 062 // argument. 063 private final ArgumentParser parser; 064 065 // The list of argument parsers that correspond to values actually provided 066 // to this argument. 067 private final List<ArgumentParser> values; 068 069 // The string representations of the values provided for this argument. 070 private final List<String> valueStrings; 071 072 073 074 /** 075 * Creates a new argument list argument with the provided information. 076 * 077 * @param shortIdentifier The short identifier for this argument. It may 078 * not be {@code null} if the long identifier is 079 * {@code null}. 080 * @param longIdentifier The long identifier for this argument. It may 081 * not be {@code null} if the short identifier is 082 * {@code null}. 083 * @param isRequired Indicates whether this argument is required to 084 * be provided. 085 * @param maxOccurrences The maximum number of times this argument may be 086 * provided on the command line. A value less than 087 * or equal to zero indicates that it may be present 088 * any number of times. 089 * @param valuePlaceholder A placeholder to display in usage information to 090 * indicate that a value must be provided. It must 091 * not be {@code null}. 092 * @param description A human-readable description for this argument. 093 * It must not be {@code null}. 094 * @param parser The argument parser that will be used to 095 * process values provided for this argument. 096 * 097 * @throws ArgumentException If there is a problem with the definition of 098 * this argument. 099 */ 100 public ArgumentListArgument(final Character shortIdentifier, 101 final String longIdentifier, 102 final boolean isRequired, 103 final int maxOccurrences, 104 final String valuePlaceholder, 105 final String description, 106 final ArgumentParser parser) 107 throws ArgumentException 108 { 109 super(shortIdentifier, longIdentifier, isRequired, maxOccurrences, 110 valuePlaceholder, description); 111 112 this.parser = parser.getCleanCopy(); 113 114 values = new ArrayList<ArgumentParser>(); 115 valueStrings = new ArrayList<String>(); 116 } 117 118 119 120 /** 121 * Creates a new argument list argument that is a "clean" copy of the provided 122 * source argument. 123 * 124 * @param source The source argument to use for this argument. 125 */ 126 private ArgumentListArgument(final ArgumentListArgument source) 127 { 128 super(source); 129 130 parser = source.parser; 131 values = new ArrayList<ArgumentParser>(); 132 valueStrings = new ArrayList<String>(); 133 } 134 135 136 137 /** 138 * Retrieves a "clean" copy of the argument parser that will be used to 139 * process values provided for this argument. 140 * 141 * @return A "clean" copy of the argument parser that will be used to process 142 * values provided for this argument. 143 */ 144 public ArgumentParser getCleanParser() 145 { 146 return parser.getCleanCopy(); 147 } 148 149 150 151 /** 152 * {@inheritDoc} 153 */ 154 @Override() 155 protected void addValue(final String valueString) 156 throws ArgumentException 157 { 158 final List<String> argList; 159 try 160 { 161 argList = StaticUtils.toArgumentList(valueString); 162 } 163 catch (final ParseException pe) 164 { 165 Debug.debugException(pe); 166 throw new ArgumentException(ERR_ARG_LIST_MALFORMED_VALUE.get(valueString, 167 getIdentifierString(), pe.getMessage()), pe); 168 } 169 170 final String[] args = new String[argList.size()]; 171 argList.toArray(args); 172 173 final ArgumentParser p = parser.getCleanCopy(); 174 try 175 { 176 p.parse(args); 177 } 178 catch (final ArgumentException ae) 179 { 180 Debug.debugException(ae); 181 throw new ArgumentException(ERR_ARG_LIST_INVALID_VALUE.get(valueString, 182 getIdentifierString(), ae.getMessage()), ae); 183 } 184 185 values.add(p); 186 valueStrings.add(valueString); 187 } 188 189 190 191 /** 192 * Retrieves the list of argument parsers that have been used to process 193 * values provided to this argument. 194 * 195 * @return The list of argument parsers that have been used to process values 196 * provided to this argument. 197 */ 198 public List<ArgumentParser> getValueParsers() 199 { 200 return Collections.unmodifiableList(values); 201 } 202 203 204 205 /** 206 * Retrieves the list of the string representations of the values provided to 207 * this argument. 208 * 209 * @return The list of the string representations of the values provided to 210 * this argument. 211 */ 212 public List<String> getValueStrings() 213 { 214 return Collections.unmodifiableList(valueStrings); 215 } 216 217 218 219 /** 220 * {@inheritDoc} 221 */ 222 @Override() 223 protected boolean hasDefaultValue() 224 { 225 return false; 226 } 227 228 229 230 /** 231 * {@inheritDoc} 232 */ 233 @Override() 234 public String getDataTypeName() 235 { 236 return INFO_ARG_LIST_TYPE_NAME.get(); 237 } 238 239 240 241 /** 242 * {@inheritDoc} 243 */ 244 @Override() 245 public String getValueConstraints() 246 { 247 return INFO_ARG_LIST_CONSTRAINTS.get(); 248 } 249 250 251 252 /** 253 * {@inheritDoc} 254 */ 255 @Override() 256 public ArgumentListArgument getCleanCopy() 257 { 258 return new ArgumentListArgument(this); 259 } 260 261 262 263 /** 264 * {@inheritDoc} 265 */ 266 @Override() 267 public void toString(final StringBuilder buffer) 268 { 269 buffer.append("ArgumentListArgument("); 270 appendBasicToStringInfo(buffer); 271 buffer.append(", parser="); 272 parser.toString(buffer); 273 buffer.append(')'); 274 } 275}