001 /*
002 * Copyright 2011-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2011-2013 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 */
021 package com.unboundid.util.args;
022
023
024
025 import java.text.ParseException;
026 import java.util.ArrayList;
027 import java.util.Collections;
028 import java.util.List;
029
030 import com.unboundid.util.Debug;
031 import com.unboundid.util.Mutable;
032 import com.unboundid.util.StaticUtils;
033 import com.unboundid.util.ThreadSafety;
034 import com.unboundid.util.ThreadSafetyLevel;
035
036 import 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)
051 public 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 }