001/* 002 * Copyright (C) 2012 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 020package org.crsh.plugin; 021 022import java.util.Collections; 023import java.util.HashMap; 024import java.util.Map; 025import java.util.concurrent.TimeUnit; 026 027public abstract class PropertyDescriptor<T> { 028 029 /** The display value returned when a property is secret. */ 030 public static final String SECRET_DISPLAY_VALUE = "*****"; 031 032 public static PropertyDescriptor<String> create(String name, String defaultValue, String description, boolean secret) { 033 return new PropertyDescriptor<String>(String.class, name, defaultValue, description, secret) { 034 @Override 035 protected String doParse(String s) throws Exception { 036 return s; 037 } 038 }; 039 } 040 041 042 public static PropertyDescriptor<String> create(String name, String defaultValue, String description) { 043 return create(name, defaultValue, description, false); 044 } 045 046 public static PropertyDescriptor<Integer> create(String name, Integer defaultValue, String description, boolean secret) { 047 return new PropertyDescriptor<Integer>(Integer.class, name, defaultValue, description, secret) { 048 @Override 049 protected Integer doParse(String s) throws Exception { 050 return Integer.parseInt(s); 051 } 052 }; 053 } 054 055 public static PropertyDescriptor<Integer> create(String name, Integer defaultValue, String description) { 056 return create(name, defaultValue, description, false); 057 } 058 059 /** . */ 060 private static final Map<String, PropertyDescriptor<?>> INTERNAL_ALL = new HashMap<String, PropertyDescriptor<?>>(); 061 062 /** . */ 063 public static final Map<String, PropertyDescriptor<?>> ALL = Collections.unmodifiableMap(INTERNAL_ALL); 064 065 /** . */ 066 public static final PropertyDescriptor<TimeUnit> VFS_REFRESH_UNIT = new PropertyDescriptor<TimeUnit>(TimeUnit.class, "vfs.refresh_unit", TimeUnit.SECONDS, "The refresh time unit") { 067 @Override 068 public TimeUnit doParse(String s) { 069 return TimeUnit.valueOf(s); 070 } 071 }; 072 073 /** . */ 074 public static final PropertyDescriptor<Integer> VFS_REFRESH_PERIOD = PropertyDescriptor.create("vfs.refresh_period", (Integer)null, "The refresh rate period"); 075 076 /** . */ 077 public final Class<T> type; 078 079 /** . */ 080 public final String name; 081 082 /** . */ 083 public final T defaultValue; 084 085 /** . */ 086 public final String description; 087 088 /** . */ 089 public final boolean secret; 090 091 /** 092 * Create a new property descriptor. 093 * 094 * @param type the property type 095 * @param name the property name 096 * @param defaultValue the default value 097 * @param description the description 098 * @throws NullPointerException if the type, name or description is null 099 */ 100 protected PropertyDescriptor(Class<T> type, String name, T defaultValue, String description) throws NullPointerException { 101 this(type, name, defaultValue, description, false); 102 } 103 104 /** 105 * Create a new property descriptor. 106 * 107 * @param type the property type 108 * @param name the property name 109 * @param defaultValue the default value 110 * @param description the description 111 * @param secret the value is secret (like a password) 112 * @throws NullPointerException if the type, name or description is null 113 */ 114 protected PropertyDescriptor(Class<T> type, String name, T defaultValue, String description, boolean secret) throws NullPointerException { 115 if (type == null) { 116 throw new NullPointerException("No null type accepted"); 117 } 118 if (name == null) { 119 throw new NullPointerException("No null name accepted"); 120 } 121 if (description == null) { 122 throw new NullPointerException("No null description accepted"); 123 } 124 125 this.type = type; 126 this.name = name; 127 this.defaultValue = defaultValue; 128 this.description = description; 129 this.secret = secret; 130 131 // 132 INTERNAL_ALL.put(name, this); 133 } 134 135 public final String getName() { 136 return name; 137 } 138 139 public final String getDescription() { 140 return description; 141 } 142 143 public final Class<T> getType() { 144 return type; 145 } 146 147 public final T getDefaultValue() { 148 return defaultValue; 149 } 150 151 public final String getDefaultDisplayValue() { 152 return secret ? SECRET_DISPLAY_VALUE : String.valueOf(defaultValue); 153 } 154 155 /** 156 * Parse a string representation of a value and returns the corresponding typed value. 157 * 158 * @param s the string to parse 159 * @return the corresponding value 160 * @throws NullPointerException if the argument is null 161 * @throws IllegalArgumentException if the string value cannot be parsed for some reason 162 */ 163 public final T parse(String s) throws NullPointerException, IllegalArgumentException { 164 if (s == null) { 165 throw new NullPointerException("Cannot parse null property values"); 166 } 167 try { 168 return doParse(s); 169 } 170 catch (Exception e) { 171 throw new IllegalArgumentException("Illegal property value " + s, e); 172 } 173 } 174 175 @Override 176 public boolean equals(Object obj) { 177 if (obj == this) { 178 return true; 179 } else if (obj instanceof PropertyDescriptor<?>) { 180 PropertyDescriptor<?> that = (PropertyDescriptor<?>)obj; 181 return name.equals(that.name) && type.equals(that.type); 182 } else { 183 return false; 184 } 185 } 186 187 /** 188 * Parse a string representation of a value and returns the correspondig property value. 189 * 190 * @param s the string to parse 191 * @return the corresponding property 192 * @throws NullPointerException if the argument is null 193 * @throws IllegalArgumentException if the string value cannot be parsed for some reason 194 */ 195 public final Property<T> toProperty(String s) throws NullPointerException, IllegalArgumentException { 196 T value = parse(s); 197 return new Property<T>(this, value); 198 } 199 200 /** 201 * Implements the real parsing, the string argument must nto be null. The returned value must not be null instead an 202 * exception must be thrown. 203 * 204 * @param s the string to parse 205 * @return the related value 206 * @throws Exception any exception that would prevent parsing to hapen 207 */ 208 protected abstract T doParse(String s) throws Exception; 209 210 @Override 211 public final String toString() { 212 return "PropertyDescriptor[name=" + name + ",type=" + type.getName() + ",description=" + description + "]"; 213 } 214}