001 /*
002 * Copyright (C) 2010 eXo Platform SAS.
003 *
004 * This is free software; you can redistribute it and/or modify it
005 * under the terms of the GNU Lesser General Public License as
006 * published by the Free Software Foundation; either version 2.1 of
007 * the License, or (at your option) any later version.
008 *
009 * This software is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * You should have received a copy of the GNU Lesser General Public
015 * License along with this software; if not, write to the Free
016 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
017 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
018 */
019
020 package org.crsh.cmdline;
021
022 import org.crsh.cmdline.binding.TypeBinding;
023 import org.crsh.cmdline.matcher.CmdSyntaxException;
024 import org.crsh.cmdline.spi.Completer;
025
026 import java.io.IOException;
027 import java.lang.annotation.Annotation;
028 import java.lang.reflect.Type;
029 import java.util.ArrayList;
030 import java.util.Collections;
031 import java.util.List;
032
033 /**
034 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
035 * @version $Revision$
036 */
037 public class OptionDescriptor<B extends TypeBinding> extends ParameterDescriptor<B> {
038
039 /** . */
040 private final int arity;
041
042 /** . */
043 private final List<String> names;
044
045 public OptionDescriptor(
046 B binding,
047 Type javaType,
048 List<String> names,
049 Description info,
050 boolean required,
051 boolean password,
052 boolean unquote,
053 Class<? extends Completer> completerType,
054 Annotation annotation) throws IllegalValueTypeException, IllegalParameterException {
055 super(
056 binding,
057 javaType,
058 info,
059 required,
060 password,
061 unquote,
062 completerType,
063 annotation);
064
065 //
066 if (getMultiplicity() == Multiplicity.MULTI && getType() == SimpleValueType.BOOLEAN) {
067 throw new IllegalParameterException();
068 }
069
070 //
071 names = new ArrayList<String>(names);
072 for (String name : names) {
073 if (name == null) {
074 throw new IllegalParameterException("Option name must not be null");
075 }
076 if (name.length() == 0) {
077 throw new IllegalParameterException("Option name cannot be empty");
078 }
079 if (name.contains("-")) {
080 throw new IllegalParameterException("Option name must not contain the hyphen character");
081 }
082 }
083
084 //
085 if (getType() == SimpleValueType.BOOLEAN) {
086 arity = 0;
087 } else {
088 arity = 1;
089 }
090
091 //
092 this.names = Collections.unmodifiableList(names);
093 }
094
095 public int getArity() {
096 return arity;
097 }
098
099 public List<String> getNames() {
100 return names;
101 }
102
103 @Override
104 public Object parse(List<String> values) throws CmdSyntaxException {
105 if (arity == 0) {
106 if (values.size() > 0) {
107 throw new CmdSyntaxException("Too many option values: " + values);
108 }
109 // It's a boolean and it is true
110 return Boolean.TRUE;
111 } else {
112 if (getMultiplicity() == Multiplicity.SINGLE) {
113 if (values.size() > 1) {
114 throw new CmdSyntaxException("Too many option values: " + values);
115 }
116 String value = values.get(0);
117 try {
118 return parse(value);
119 } catch (Exception e) {
120 throw new CmdSyntaxException("Could not parse value: <" + value + ">");
121 }
122 } else {
123 List<Object> v = new ArrayList<Object>(values.size());
124 for (String value : values) {
125 try {
126 v.add(parse(value));
127 } catch (Exception e) {
128 throw new CmdSyntaxException("Could not parse value: <" + value + ">");
129 }
130 }
131 return v;
132 }
133 }
134 }
135
136 /**
137 * Prints the option names as an alternative of switches surrounded by a square brace,
138 * for instance: "[-f --foo]"
139 *
140 * @param writer the writer to print to
141 * @throws IOException any io exception
142 */
143 public void printUsage(Appendable writer) throws IOException {
144 writer.append("[");
145 boolean a = false;
146 for (String optionName : names) {
147 if (a) {
148 writer.append(" | ");
149 }
150 writer.append(optionName.length() == 1 ? "-" : "--").append(optionName);
151 a = true;
152 }
153 writer.append("]");
154 }
155
156 @Override
157 public String toString() {
158 return "OptionDescriptor[" + names + "]";
159 }
160 }