1 19 package org.openide.options; 20 21 import org.openide.util.HelpCtx; 22 import org.openide.util.NbBundle; 23 import org.openide.util.SharedClassObject; 24 25 import java.beans.BeanInfo ; 26 import java.beans.IntrospectionException ; 27 import java.beans.PropertyDescriptor ; 28 29 import java.io.IOException ; 30 import java.io.ObjectInput ; 31 import java.io.ObjectOutput ; 32 33 import java.lang.reflect.InvocationTargetException ; 34 import java.lang.reflect.Method ; 35 36 import java.util.HashMap ; 37 import java.util.Map ; 38 import java.util.logging.Level ; 39 import java.util.logging.Logger ; 40 import org.openide.util.Exceptions; 41 42 43 60 public abstract class SystemOption extends SharedClassObject implements HelpCtx.Provider { 61 62 static final long serialVersionUID = 558589201969066966L; 63 64 65 private static final Object PROP_LOADING = new Object (); 66 67 68 private static final Object PROP_STORING = new Object (); 69 70 71 private static final Object PROP_ORIGINAL_VALUES = new Object (); 72 73 74 private static final Object NULL = new Object (); 75 76 77 public SystemOption() { 78 } 79 80 87 protected void firePropertyChange(String name, Object oldValue, Object newValue) { 88 if ((name != null) && (getProperty("org.openide.util.SharedClassObject.initialize") == null)) { 90 Map originalValues = (Map ) getProperty(PROP_ORIGINAL_VALUES); 91 92 if (originalValues == null) { 93 originalValues = new HashMap (); 94 putProperty(PROP_ORIGINAL_VALUES, originalValues); 95 } 96 97 if (originalValues.get(name) == null) { 98 if (getProperty(name) == null) { 99 originalValues.put(name, new Box(oldValue)); 101 } else { 102 originalValues.put(name, (oldValue == null) ? NULL : oldValue); 104 } 105 } 106 } 107 108 if (getProperty(PROP_LOADING) != null) { 109 putProperty(PROP_LOADING, PROP_LOADING); 112 113 return; 115 } 116 117 super.firePropertyChange(name, oldValue, newValue); 118 } 119 120 131 protected void reset() { 132 synchronized (getLock()) { 133 Map m = (Map ) getProperty(PROP_ORIGINAL_VALUES); 134 135 if ((m == null) || m.isEmpty()) { 136 return; 137 } 138 139 java.util.Iterator it = m.entrySet().iterator(); 140 WHILE: 141 while (it.hasNext()) { 142 Map.Entry e = (Map.Entry ) it.next(); 143 144 if (e.getValue() instanceof Box) { 145 Object value = ((Box) e.getValue()).value; 146 147 try { 148 BeanInfo info = org.openide.util.Utilities.getBeanInfo(getClass(), SystemOption.class); 150 PropertyDescriptor [] desc = info.getPropertyDescriptors(); 151 152 for (int i = 0; i < desc.length; i++) { 153 if (e.getKey().equals(desc[i].getName())) { 154 Method write = desc[i].getWriteMethod(); 156 157 if (write != null) { 158 write.invoke(this, new Object [] { value }); 159 } 160 161 continue WHILE; 162 } 163 } 164 } catch (InvocationTargetException ex) { 165 Logger.getLogger(SystemOption.class.getName()).log(Level.WARNING, null, ex); 167 } catch (IllegalAccessException ex) { 168 Logger.getLogger(SystemOption.class.getName()).log(Level.WARNING, null, ex); 169 } catch (IntrospectionException ex) { 170 Logger.getLogger(SystemOption.class.getName()).log(Level.WARNING, null, ex); 171 } 172 } else { 173 putProperty(e.getKey(), (e.getValue() == NULL) ? null : e.getValue()); 174 } 175 } 176 177 putProperty(PROP_ORIGINAL_VALUES, null); 179 } 180 181 super.firePropertyChange(null, null, null); 182 } 183 184 188 public void writeExternal(ObjectOutput out) throws IOException { 189 try { 190 BeanInfo info = org.openide.util.Utilities.getBeanInfo(getClass(), SystemOption.class); 192 PropertyDescriptor [] desc = info.getPropertyDescriptors(); 193 194 putProperty(PROP_STORING, this); 195 196 Object [] param = new Object [0]; 197 198 synchronized (getLock()) { 199 for (int i = 0; i < desc.length; i++) { 201 if (desc[i].getWriteMethod() == null) { 203 continue; 204 } 205 String propName = desc[i].getName(); 206 Object value = getProperty(propName); 207 boolean fromRead; 208 Method read = desc[i].getReadMethod(); 213 214 if (read == null) { 215 continue; 216 } 217 if ((value == null) || isInstance(desc[i].getPropertyType(), 218 value)) { 219 fromRead = true; 220 try { 221 value = read.invoke(this, param); 222 } 223 catch (InvocationTargetException ex) { 224 throw (IOException ) new IOException (NbBundle.getMessage(SystemOption.class, 225 "EXC_InGetter", 226 getClass(), 227 desc[i].getName())).initCause(ex); 228 } 229 catch (IllegalAccessException ex) { 230 throw (IOException ) new IOException (NbBundle.getMessage(SystemOption.class, 231 "EXC_InGetter", 232 getClass(), 233 desc[i].getName())).initCause(ex); 234 } 235 } else { 236 fromRead = false; 237 } 238 out.writeObject(propName); 240 out.writeObject(value); 242 out.writeObject(fromRead ? Boolean.TRUE 244 : Boolean.FALSE); 245 } 246 } 247 } catch (IntrospectionException ex) { 248 } finally { 250 putProperty(PROP_STORING, null); 251 } 252 253 out.writeObject(null); 255 } 256 257 260 private static boolean isInstance(Class c, Object o) { 261 return c.isInstance(o) || ((c == Byte.TYPE) && (o instanceof Byte )) || 262 ((c == Short.TYPE) && (o instanceof Short )) || ((c == Integer.TYPE) && (o instanceof Integer )) || 263 ((c == Long.TYPE) && (o instanceof Long )) || ((c == Float.TYPE) && (o instanceof Float )) || 264 ((c == Double.TYPE) && (o instanceof Double )) || ((c == Boolean.TYPE) && (o instanceof Boolean )) || 265 ((c == Character.TYPE) && (o instanceof Character )); 266 } 267 268 275 public void readExternal(ObjectInput in) throws IOException , ClassNotFoundException { 276 HashMap map = new HashMap (); 278 279 try { 280 synchronized (getLock()) { 281 putProperty(PROP_LOADING, this); 283 284 try { 285 BeanInfo info = org.openide.util.Utilities.getBeanInfo(getClass(), SystemOption.class); 287 PropertyDescriptor [] desc = info.getPropertyDescriptors(); 288 289 for (int i = 0; i < desc.length; i++) { 291 Method m = desc[i].getWriteMethod(); 292 293 299 map.put(desc[i].getName(), m); 300 } 301 } catch (IntrospectionException ex) { 302 Logger.getLogger(SystemOption.class.getName()).log(Level.WARNING, null, ex); 305 } 306 307 String preread = null; 308 309 do { 310 String name; 312 313 if (preread != null) { 314 name = preread; 315 preread = null; 316 } else { 317 name = (String ) in.readObject(); 318 } 319 320 if (name == null) { 322 break; 323 } 324 325 Object value = in.readObject(); 327 328 Object useMethodObject = in.readObject(); 330 boolean useMethod; 331 boolean nullRead = false; 333 if (useMethodObject == null) { 334 useMethod = true; 335 nullRead = true; 336 } else if (useMethodObject instanceof String ) { 337 useMethod = true; 338 preread = (String ) useMethodObject; 339 } else { 340 useMethod = ((Boolean ) useMethodObject).booleanValue(); 341 } 342 343 if (useMethod) { 344 Method write = (Method ) map.get(name); 346 347 if (write != null) { 348 try { 350 write.invoke(this, new Object [] { value }); 351 } catch (Exception ex) { 352 String msg = "Cannot call " + write + " for property " + getClass().getName() + "." + 353 name; Exceptions.attachMessage(ex, msg); 355 Logger.getLogger(SystemOption.class.getName()).log(Level.WARNING, null, ex); 356 } 357 } 358 } else { 359 putProperty(name, value, false); 360 } 361 362 if (nullRead) { 363 break; 364 } 365 } while (true); 366 } 367 } finally { 368 if (this != getProperty(PROP_LOADING)) { 370 putProperty(PROP_LOADING, null); 373 firePropertyChange(null, null, null); 374 } else { 375 putProperty(PROP_LOADING, null); 377 } 378 } 379 } 380 381 protected boolean clearSharedData() { 382 return false; 383 } 384 385 390 public final String getName() { 391 return displayName(); 392 } 393 394 398 public abstract String displayName(); 399 400 403 public HelpCtx getHelpCtx() { 404 return new HelpCtx(SystemOption.class); 405 } 406 407 413 protected final boolean isReadExternal() { 414 return getProperty(PROP_LOADING) != null; 415 } 416 417 422 protected final boolean isWriteExternal() { 423 return getProperty(PROP_STORING) != null; 424 } 425 426 429 private static final class Box extends Object { 430 public Object value; 431 432 public Box(Object v) { 433 this.value = v; 434 } 435 } 436 } 438 | Popular Tags |