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.completers.EmptyCompleter;
024 import org.crsh.cmdline.matcher.CmdSyntaxException;
025 import org.crsh.cmdline.spi.Completer;
026 import org.crsh.cmdline.spi.Value;
027
028 import java.io.IOException;
029 import java.lang.annotation.Annotation;
030 import java.lang.reflect.ParameterizedType;
031 import java.lang.reflect.Type;
032 import java.util.List;
033
034 /**
035 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a>
036 * @version $Revision$
037 */
038 public abstract class ParameterDescriptor<B extends TypeBinding> {
039
040 /** . */
041 private final B binding;
042
043 /** . */
044 private final Description description;
045
046 /** . */
047 private final SimpleValueType type;
048
049 /** . */
050 private final Multiplicity multiplicity;
051
052 /** . */
053 private final boolean required;
054
055 /** . */
056 private final boolean password;
057
058 /** . */
059 private final Type javaType;
060
061 /** . */
062 private final Class<?> javaValueType;
063
064 /** . */
065 private final Class<? extends Completer> completerType;
066
067 /** The annotation when it exists. */
068 private final Annotation annotation;
069
070 /** . */
071 private final boolean unquote;
072
073 /** . */
074 CommandDescriptor<?, B> owner;
075
076 public ParameterDescriptor(
077 B binding,
078 Type javaType,
079 Description description,
080 boolean required,
081 boolean password,
082 boolean unquote,
083 Class<? extends Completer> completerType,
084 Annotation annotation) throws IllegalValueTypeException, IllegalParameterException {
085
086 //
087 Class<?> javaValueType;
088 Multiplicity multiplicity;
089 if (javaType instanceof Class<?>) {
090 javaValueType = (Class<Object>)javaType;
091 multiplicity = Multiplicity.SINGLE;
092 } else if (javaType instanceof ParameterizedType) {
093 ParameterizedType parameterizedType = (ParameterizedType)javaType;
094 Type rawType = parameterizedType.getRawType();
095 if (rawType instanceof Class<?>) {
096 Class<?> classRawType = (Class<Object>)rawType;
097 if (List.class.equals(classRawType)) {
098 Type elementType = parameterizedType.getActualTypeArguments()[0];
099 if (elementType instanceof Class<?>) {
100 javaValueType = (Class<Object>)elementType;
101 multiplicity = Multiplicity.MULTI;
102 } else {
103 throw new IllegalValueTypeException();
104 }
105 } else {
106 throw new IllegalValueTypeException();
107 }
108 } else {
109 throw new IllegalValueTypeException();
110 }
111 } else {
112 throw new IllegalValueTypeException();
113 }
114
115 //
116 SimpleValueType valueType;
117 if (javaValueType == String.class) {
118 valueType = SimpleValueType.STRING;
119 } else if (javaValueType == Integer.class || javaValueType == int.class) {
120 valueType = SimpleValueType.INTEGER;
121 } else if (javaValueType == Boolean.class || javaValueType == boolean.class) {
122 valueType = SimpleValueType.BOOLEAN;
123 } else if (Enum.class.isAssignableFrom(javaValueType)) {
124 valueType = SimpleValueType.ENUM;
125 } else if (Value.class.isAssignableFrom(javaValueType)) {
126 valueType = SimpleValueType.VALUE;
127 } else {
128 throw new IllegalValueTypeException("Type " + javaValueType.getName() + " is not handled at the moment");
129 }
130
131 //
132 if (completerType == EmptyCompleter.class) {
133 completerType = valueType.getCompleter();
134 }
135
136 //
137 this.binding = binding;
138 this.javaType = javaType;
139 this.description = description;
140 this.type = valueType;
141 this.multiplicity = multiplicity;
142 this.required = required;
143 this.password = password;
144 this.completerType = completerType;
145 this.annotation = annotation;
146 this.javaValueType = javaValueType;
147 this.unquote = unquote;
148 }
149
150 public Object parse(String s) throws Exception {
151 return type.parse(javaValueType, s);
152 }
153
154 public abstract Object parse(List<String> values) throws CmdSyntaxException;
155
156 public CommandDescriptor<?, B> getOwner() {
157 return owner;
158 }
159
160 public Type getJavaType() {
161 return javaType;
162 }
163
164 public Class<?> getJavaValueType() {
165 return javaValueType;
166 }
167
168 public final B getBinding() {
169 return binding;
170 }
171
172 public final String getUsage() {
173 return description != null ? description.getUsage() : "";
174 }
175
176 public Description getDescription() {
177 return description;
178 }
179
180 public Annotation getAnnotation() {
181 return annotation;
182 }
183
184 public final boolean isRequired() {
185 return required;
186 }
187
188 public boolean isUnquote() {
189 return unquote;
190 }
191
192 public final boolean isPassword() {
193 return password;
194 }
195
196 public final SimpleValueType getType() {
197 return type;
198 }
199
200 public final Multiplicity getMultiplicity() {
201 return multiplicity;
202 }
203
204 public final boolean isSingleValued() {
205 return multiplicity == Multiplicity.SINGLE;
206 }
207
208 public final boolean isMultiValued() {
209 return multiplicity == Multiplicity.MULTI;
210 }
211
212 public final Class<? extends Completer> getCompleterType() {
213 return completerType;
214 }
215
216 public abstract void printUsage(Appendable writer) throws IOException;
217 }