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