1 19 20 package org.openide.nodes; 21 22 import java.beans.Beans ; 23 import java.beans.PropertyEditor ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Modifier ; 27 import org.openide.util.Exceptions; 28 import org.openide.util.NbBundle; 29 30 34 public abstract class PropertySupport<T> extends Node.Property<T> { 35 36 private boolean canR; 37 38 39 private boolean canW; 40 41 48 public PropertySupport( 49 String name, Class <T> type, String displayName, String shortDescription, boolean canR, boolean canW 50 ) { 51 super(type); 52 this.setName(name); 53 setDisplayName(displayName); 54 setShortDescription(shortDescription); 55 this.canR = canR; 56 this.canW = canW; 57 } 58 59 63 public boolean canRead() { 64 return canR; 65 } 66 67 71 public boolean canWrite() { 72 return canW; 73 } 74 75 79 static <T> T cast(Class <T> c, Object o) { 80 if (c.isPrimitive()) { 81 return (T) o; 83 } else { 84 return c.cast(o); 85 } 86 } 87 88 89 public static class Reflection<T> extends Node.Property<T> { 90 91 protected Object instance; 92 93 94 private Method setter; 95 96 97 private Method getter; 98 99 100 private Class <? extends PropertyEditor > propertyEditorClass; 101 102 110 public Reflection(Object instance, Class <T> valueType, Method getter, Method setter) { 111 super(valueType); 112 113 if ((getter != null) && !Modifier.isPublic(getter.getModifiers())) { 114 throw new IllegalArgumentException ("Cannot use a non-public getter " + getter); } 116 117 if ((setter != null) && !Modifier.isPublic(setter.getModifiers())) { 118 throw new IllegalArgumentException ("Cannot use a non-public setter " + setter); } 120 121 this.instance = instance; 122 this.setter = setter; 123 this.getter = getter; 124 } 125 126 136 public Reflection(Object instance, Class <T> valueType, String getter, String setter) 137 throws NoSuchMethodException { 138 this( 139 instance, valueType, 140 ( 141 getter == null) ? null : findAccessibleClass(instance.getClass()).getMethod(getter), 143 ( 144 setter == null) ? null : findAccessibleClass(instance.getClass()).getMethod( 146 setter, new Class <?>[] { valueType } 147 ) 148 ); 149 } 150 151 153 163 public Reflection(Object instance, Class <T> valueType, String property) 164 throws NoSuchMethodException { 165 this( 166 instance, valueType, findGetter(instance, valueType, property), 167 findAccessibleClass(instance.getClass()).getMethod( 168 firstLetterToUpperCase(property, "set"), valueType 169 ) 170 ); 171 } 172 173 174 private static <C> Class <? super C> findAccessibleClass(Class <C> clazz) { 175 if (Modifier.isPublic(clazz.getModifiers())) { 176 return clazz; 177 } else { 178 Class <? super C> sup = clazz.getSuperclass(); 179 180 if (sup == null) { 181 return Object .class; } 183 184 return findAccessibleClass(sup); 185 } 186 } 187 188 191 private static String firstLetterToUpperCase(String s, String pref) { 192 switch (s.length()) { 193 case 0: 194 return pref; 195 196 case 1: 197 return pref + Character.toUpperCase(s.charAt(0)); 198 199 default: 200 return pref + Character.toUpperCase(s.charAt(0)) + s.substring(1); 201 } 202 } 203 204 private static Method findGetter(Object instance, Class valueType, String property) 206 throws NoSuchMethodException { 207 NoSuchMethodException nsme; 208 209 try { 210 return findAccessibleClass(instance.getClass()).getMethod( 211 firstLetterToUpperCase(property, "get") 212 ); 213 } catch (NoSuchMethodException e) { 214 if (valueType != boolean.class) { 215 throw e; 216 } else { 217 nsme = e; 218 } 219 } 220 221 try { 223 return findAccessibleClass(instance.getClass()).getMethod( 224 firstLetterToUpperCase(property, "is") 225 ); 226 } catch (NoSuchMethodException e) { 227 throw e; 228 } 229 } 230 231 234 public boolean canRead() { 235 return getter != null; 236 } 237 238 244 public T getValue() throws IllegalAccessException , IllegalArgumentException , InvocationTargetException { 245 if (getter == null) { 246 throw new IllegalAccessException (); 247 } 248 249 Object valideInstance = Beans.getInstanceOf(instance, getter.getDeclaringClass()); 250 251 try { 252 try { 253 return cast(getValueType(), getter.invoke(valideInstance)); 254 } catch (IllegalAccessException ex) { 255 try { 256 getter.setAccessible(true); 257 258 return cast(getValueType(), getter.invoke(valideInstance)); 259 } finally { 260 getter.setAccessible(false); 261 } 262 } 263 } catch (IllegalArgumentException iae) { 264 StringBuffer sb = new StringBuffer ("Attempted to invoke method "); 266 sb.append(getter.getName()); 267 sb.append(" from class "); 268 sb.append(getter.getDeclaringClass().getName()); 269 sb.append(" on an instance of "); 270 sb.append(valideInstance.getClass().getName()); 271 sb.append(" Problem:"); 272 sb.append(iae.getMessage()); 273 throw (IllegalArgumentException ) new IllegalArgumentException (sb.toString()).initCause(iae); 274 } 275 } 276 277 280 public boolean canWrite() { 281 return setter != null; 282 } 283 284 290 public void setValue(T val) 291 throws IllegalAccessException , IllegalArgumentException , InvocationTargetException { 292 if (setter == null) { 293 throw new IllegalAccessException (); 294 } 295 296 Object valideInstance = Beans.getInstanceOf(instance, setter.getDeclaringClass()); 297 298 try { 299 setter.invoke(valideInstance, val); 300 } catch (IllegalAccessException ex) { 301 try { 302 setter.setAccessible(true); 303 setter.invoke(valideInstance, val); 304 } finally { 305 setter.setAccessible(false); 306 } 307 } 308 } 309 310 314 public PropertyEditor getPropertyEditor() { 315 if (propertyEditorClass != null) { 316 try { 317 return propertyEditorClass.newInstance(); 318 } catch (InstantiationException ex) { 319 Exceptions.printStackTrace(ex); 320 } catch (IllegalAccessException iex) { 321 Exceptions.printStackTrace(iex); 322 } 323 } 324 325 return super.getPropertyEditor(); 326 } 327 328 331 public void setPropertyEditorClass(Class <? extends PropertyEditor > clazz) { 332 propertyEditorClass = clazz; 333 } 334 } 335 336 340 public static abstract class ReadWrite<T> extends PropertySupport<T> { 341 347 public ReadWrite(String name, Class <T> type, String displayName, String shortDescription) { 348 super(name, type, displayName, shortDescription, true, true); 349 } 350 } 351 352 355 public static abstract class ReadOnly<T> extends PropertySupport<T> { 356 362 public ReadOnly(String name, Class <T> type, String displayName, String shortDescription) { 363 super(name, type, displayName, shortDescription, true, false); 364 } 365 366 372 @Override 373 public void setValue(T val) 374 throws IllegalAccessException , IllegalArgumentException , InvocationTargetException { 375 throw new IllegalAccessException ("Cannot write to ReadOnly property"); } 377 } 378 379 382 public static abstract class WriteOnly<T> extends PropertySupport<T> { 383 389 public WriteOnly(String name, Class <T> type, String displayName, String shortDescription) { 390 super(name, type, displayName, shortDescription, false, true); 391 } 392 393 399 @Override 400 public T getValue() throws IllegalAccessException , IllegalArgumentException , InvocationTargetException { 401 throw new IllegalAccessException ("Cannod read from WriteOnly property"); } 403 } 404 405 408 public static final class Name extends PropertySupport<String > { 409 410 private final Node node; 411 412 415 public Name(final Node node) { 416 this( 417 node, NbBundle.getBundle(PropertySupport.class).getString("CTL_StandardName"), 418 NbBundle.getBundle(PropertySupport.class).getString("CTL_StandardHint") 419 ); 420 } 421 422 427 public Name(final Node node, final String propName, final String hint) { 428 super(Node.PROP_NAME, String .class, propName, hint, true, node.canRename()); 429 this.node = node; 430 } 431 432 435 public String getValue() throws IllegalAccessException , IllegalArgumentException , InvocationTargetException { 436 return node.getName(); 437 } 438 439 442 public void setValue(String val) 443 throws IllegalAccessException , IllegalArgumentException , InvocationTargetException { 444 Object oldName = node.getName(); 445 node.setName(val); 446 node.firePropertyChange(Node.PROP_NAME, oldName, val); 447 } 448 } 449 } 451 | Popular Tags |