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 }