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.completers.EmptyCompleter; 023 import org.crsh.cmdline.completers.EnumCompleter; 024 import org.crsh.cmdline.spi.Completer; 025 import org.crsh.cmdline.spi.Value; 026 027 import java.lang.reflect.Constructor; 028 029 /** 030 * @author <a href="mailto:julien.viet@exoplatform.com">Julien Viet</a> 031 * @version $Revision$ 032 */ 033 public abstract class SimpleValueType<T> { 034 035 /** . */ 036 public static final SimpleValueType<String> STRING = new SimpleValueType<String>(String.class, EmptyCompleter.class) { 037 @Override 038 public <S extends String> String parse(Class<S> type, String s) { 039 return s; 040 } 041 }; 042 043 /** . */ 044 public static final SimpleValueType<Integer> INTEGER = new SimpleValueType<Integer>(Integer.class, EmptyCompleter.class) { 045 @Override 046 public <S extends Integer> Integer parse(Class<S> type, String s) { 047 return Integer.parseInt(s); 048 } 049 }; 050 051 /** . */ 052 public static final SimpleValueType<Boolean> BOOLEAN = new SimpleValueType<Boolean>(Boolean.class, EmptyCompleter.class) { 053 @Override 054 public <S extends Boolean> Boolean parse(Class<S> type, String s) { 055 return Boolean.parseBoolean(s); 056 } 057 }; 058 059 /** . */ 060 public static final SimpleValueType<Enum> ENUM = new SimpleValueType<Enum>(Enum.class, EnumCompleter.class) { 061 @Override 062 public <S extends Enum> Enum parse(Class<S> type, String s) { 063 return Enum.valueOf(type, s); 064 } 065 }; 066 067 /** . */ 068 public static final SimpleValueType<Value> VALUE = new SimpleValueType<Value>(Value.class, EmptyCompleter.class) { 069 @Override 070 public <S extends Value> Value parse(Class<S> type, String s) throws Exception { 071 Constructor<S> ctor = type.getConstructor(String.class); 072 return ctor.newInstance(s); 073 } 074 }; 075 076 /** . */ 077 private static final SimpleValueType<?>[] types = { STRING, INTEGER, BOOLEAN, ENUM, VALUE}; 078 079 public static SimpleValueType<?> get(Class<?> clazz) { 080 SimpleValueType<?> bestType = null; 081 int bestDegree = Integer.MAX_VALUE; 082 for (SimpleValueType<?> type : types) { 083 int degree = type.getRelativeDegree(clazz); 084 if (degree != -1 && degree < bestDegree) { 085 bestType = type; 086 bestDegree = degree; 087 } 088 } 089 return bestType; 090 } 091 092 /** . */ 093 private final Class<T> javaType; 094 095 /** . */ 096 private final Class<? extends Completer> completer; 097 098 private SimpleValueType(Class<T> javaType, Class<? extends Completer> completer) { 099 if (javaType == null) { 100 throw new NullPointerException(); 101 } 102 103 // 104 this.completer = completer; 105 this.javaType = javaType; 106 } 107 108 public int getRelativeDegree(Class<?> clazz) { 109 if (javaType == clazz) { 110 return 0; 111 } else if (javaType.isAssignableFrom(clazz)) { 112 int degree = 0; 113 for (Class<?> current = clazz;current != javaType;current = current.getSuperclass()) { 114 degree++; 115 } 116 return degree; 117 } else { 118 return -1; 119 } 120 } 121 122 public Class<? extends Completer> getCompleter() { 123 return completer; 124 } 125 126 public Class<T> getJavaType() { 127 return javaType; 128 } 129 130 public abstract <S extends T> T parse(Class<S> type, String s) throws Exception; 131 132 }