43 import java.lang.reflect.Field; 44 import java.lang.reflect.Method; 45 import java.lang.reflect.Modifier; 46 import java.lang.reflect.InvocationTargetException; 47 48 import java.security.AccessController; 49 import java.security.PrivilegedAction; 50 51 import java.util.*; 52 53 import javax.swing.Box; 54 import javax.swing.JLayeredPane; 55 import javax.swing.border.MatteBorder; 56 import javax.swing.plaf.ColorUIResource; 57 58 import sun.swing.PrintColorUIResource; 59 60 import static sun.reflect.misc.ReflectUtil.isPackageAccessible; 61 62 /* 63 * Like the <code>Intropector</code>, the <code>MetaData</code> class 64 * contains <em>meta</em> objects that describe the way 65 * classes should express their state in terms of their 66 * own public APIs. 67 * 68 * @see java.beans.Intropector 69 * 70 * @author Philip Milne 71 * @author Steve Langley 72 */ 73 class MetaData { 74 75 static final class NullPersistenceDelegate extends PersistenceDelegate { 76 // Note this will be called by all classes when they reach the 77 // top of their superclass chain. 78 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { 79 } 80 protected Expression instantiate(Object oldInstance, Encoder out) { return null; } 81 82 public void writeObject(Object oldInstance, Encoder out) { 83 // System.out.println("NullPersistenceDelegate:writeObject " + oldInstance); 84 } 85 } 86 87 /** 88 * The persistence delegate for <CODE>enum</CODE> classes. 89 * 90 * @author Sergey A. Malenkov 91 */ 92 static final class EnumPersistenceDelegate extends PersistenceDelegate { 93 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 94 return oldInstance == newInstance; 95 } 96 97 protected Expression instantiate(Object oldInstance, Encoder out) { 98 Enum<?> e = (Enum<?>) oldInstance; 99 return new Expression(e, Enum.class, "valueOf", new Object[]{e.getDeclaringClass(), e.name()}); 100 } 101 } 102 103 static final class PrimitivePersistenceDelegate extends PersistenceDelegate { 104 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 105 return oldInstance.equals(newInstance); 106 } 107 108 protected Expression instantiate(Object oldInstance, Encoder out) { 245 } 246 247 // Methods 248 static final class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate { 249 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 250 return oldInstance.equals(newInstance); 251 } 252 253 protected Expression instantiate(Object oldInstance, Encoder out) { 254 Method m = (Method)oldInstance; 255 return new Expression(oldInstance, 256 m.getDeclaringClass(), 257 "getMethod", 258 new Object[]{m.getName(), m.getParameterTypes()}); 259 } 260 } 261 262 // Dates 263 264 /** 265 * The persistence delegate for <CODE>java.util.Date</CODE> classes. 266 * Do not extend DefaultPersistenceDelegate to improve performance and 267 * to avoid problems with <CODE>java.sql.Date</CODE>, 268 * <CODE>java.sql.Time</CODE> and <CODE>java.sql.Timestamp</CODE>. 269 * 270 * @author Sergey A. Malenkov 271 */ 272 static class java_util_Date_PersistenceDelegate extends PersistenceDelegate { 273 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 274 if (!super.mutatesTo(oldInstance, newInstance)) { 275 return false; 276 } 277 Date oldDate = (Date)oldInstance; 278 Date newDate = (Date)newInstance; 279 280 return oldDate.getTime() == newDate.getTime(); 281 } 282 283 protected Expression instantiate(Object oldInstance, Encoder out) { 284 Date date = (Date)oldInstance; 285 return new Expression(date, date.getClass(), "new", new Object[] {date.getTime()}); 286 } 287 } 288 289 /** 290 * The persistence delegate for <CODE>java.sql.Timestamp</CODE> classes. 291 * It supports nanoseconds. 292 * 293 * @author Sergey A. Malenkov 294 */ 295 static final class java_sql_Timestamp_PersistenceDelegate extends java_util_Date_PersistenceDelegate { 296 private static final Method getNanosMethod = getNanosMethod(); 297 298 private static Method getNanosMethod() { 299 try { 300 Class<?> c = Class.forName("java.sql.Timestamp", true, null); 301 return c.getMethod("getNanos"); 302 } catch (ClassNotFoundException e) { 303 return null; 304 } catch (NoSuchMethodException e) { 305 throw new AssertionError(e); 306 } 307 } 308 309 /** 310 * Invoke Timstamp getNanos. 554 static final class CheckedMap_PersistenceDelegate extends java_util_Collections { 555 protected Expression instantiate(Object oldInstance, Encoder out) { 556 Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); 557 Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); 558 Map<?,?> map = new HashMap<>((Map<?,?>) oldInstance); 559 return new Expression(oldInstance, Collections.class, "checkedMap", new Object[]{map, keyType, valueType}); 560 } 561 } 562 563 static final class CheckedSortedMap_PersistenceDelegate extends java_util_Collections { 564 protected Expression instantiate(Object oldInstance, Encoder out) { 565 Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); 566 Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); 567 SortedMap<?,?> map = new TreeMap<>((SortedMap<?,?>) oldInstance); 568 return new Expression(oldInstance, Collections.class, "checkedSortedMap", new Object[]{map, keyType, valueType}); 569 } 570 } 571 } 572 573 /** 574 * The persistence delegate for <CODE>java.util.EnumMap</CODE> classes. 575 * 576 * @author Sergey A. Malenkov 577 */ 578 static final class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { 579 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 580 return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); 581 } 582 583 protected Expression instantiate(Object oldInstance, Encoder out) { 584 return new Expression(oldInstance, EnumMap.class, "new", new Object[] {getType(oldInstance)}); 585 } 586 587 private static Object getType(Object instance) { 588 return MetaData.getPrivateFieldValue(instance, "java.util.EnumMap.keyType"); 589 } 590 } 591 592 /** 593 * The persistence delegate for <CODE>java.util.EnumSet</CODE> classes. 594 * 595 * @author Sergey A. Malenkov 596 */ 597 static final class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { 598 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 599 return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); 600 } 601 602 protected Expression instantiate(Object oldInstance, Encoder out) { 603 return new Expression(oldInstance, EnumSet.class, "noneOf", new Object[] {getType(oldInstance)}); 604 } 605 606 private static Object getType(Object instance) { 607 return MetaData.getPrivateFieldValue(instance, "java.util.EnumSet.elementType"); 608 } 609 } 610 611 // Collection 612 static class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegate { 613 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { | 43 import java.lang.reflect.Field; 44 import java.lang.reflect.Method; 45 import java.lang.reflect.Modifier; 46 import java.lang.reflect.InvocationTargetException; 47 48 import java.security.AccessController; 49 import java.security.PrivilegedAction; 50 51 import java.util.*; 52 53 import javax.swing.Box; 54 import javax.swing.JLayeredPane; 55 import javax.swing.border.MatteBorder; 56 import javax.swing.plaf.ColorUIResource; 57 58 import sun.swing.PrintColorUIResource; 59 60 import static sun.reflect.misc.ReflectUtil.isPackageAccessible; 61 62 /* 63 * Like the {@code Intropector}, the {@code MetaData} class 64 * contains <em>meta</em> objects that describe the way 65 * classes should express their state in terms of their 66 * own public APIs. 67 * 68 * @see java.beans.Intropector 69 * 70 * @author Philip Milne 71 * @author Steve Langley 72 */ 73 class MetaData { 74 75 static final class NullPersistenceDelegate extends PersistenceDelegate { 76 // Note this will be called by all classes when they reach the 77 // top of their superclass chain. 78 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { 79 } 80 protected Expression instantiate(Object oldInstance, Encoder out) { return null; } 81 82 public void writeObject(Object oldInstance, Encoder out) { 83 // System.out.println("NullPersistenceDelegate:writeObject " + oldInstance); 84 } 85 } 86 87 /** 88 * The persistence delegate for {@code enum} classes. 89 * 90 * @author Sergey A. Malenkov 91 */ 92 static final class EnumPersistenceDelegate extends PersistenceDelegate { 93 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 94 return oldInstance == newInstance; 95 } 96 97 protected Expression instantiate(Object oldInstance, Encoder out) { 98 Enum<?> e = (Enum<?>) oldInstance; 99 return new Expression(e, Enum.class, "valueOf", new Object[]{e.getDeclaringClass(), e.name()}); 100 } 101 } 102 103 static final class PrimitivePersistenceDelegate extends PersistenceDelegate { 104 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 105 return oldInstance.equals(newInstance); 106 } 107 108 protected Expression instantiate(Object oldInstance, Encoder out) { 245 } 246 247 // Methods 248 static final class java_lang_reflect_Method_PersistenceDelegate extends PersistenceDelegate { 249 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 250 return oldInstance.equals(newInstance); 251 } 252 253 protected Expression instantiate(Object oldInstance, Encoder out) { 254 Method m = (Method)oldInstance; 255 return new Expression(oldInstance, 256 m.getDeclaringClass(), 257 "getMethod", 258 new Object[]{m.getName(), m.getParameterTypes()}); 259 } 260 } 261 262 // Dates 263 264 /** 265 * The persistence delegate for {@code java.util.Date} classes. 266 * Do not extend DefaultPersistenceDelegate to improve performance and 267 * to avoid problems with {@code java.sql.Date}, 268 * {@code java.sql.Time} and {@code java.sql.Timestamp}. 269 * 270 * @author Sergey A. Malenkov 271 */ 272 static class java_util_Date_PersistenceDelegate extends PersistenceDelegate { 273 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 274 if (!super.mutatesTo(oldInstance, newInstance)) { 275 return false; 276 } 277 Date oldDate = (Date)oldInstance; 278 Date newDate = (Date)newInstance; 279 280 return oldDate.getTime() == newDate.getTime(); 281 } 282 283 protected Expression instantiate(Object oldInstance, Encoder out) { 284 Date date = (Date)oldInstance; 285 return new Expression(date, date.getClass(), "new", new Object[] {date.getTime()}); 286 } 287 } 288 289 /** 290 * The persistence delegate for {@code java.sql.Timestamp} classes. 291 * It supports nanoseconds. 292 * 293 * @author Sergey A. Malenkov 294 */ 295 static final class java_sql_Timestamp_PersistenceDelegate extends java_util_Date_PersistenceDelegate { 296 private static final Method getNanosMethod = getNanosMethod(); 297 298 private static Method getNanosMethod() { 299 try { 300 Class<?> c = Class.forName("java.sql.Timestamp", true, null); 301 return c.getMethod("getNanos"); 302 } catch (ClassNotFoundException e) { 303 return null; 304 } catch (NoSuchMethodException e) { 305 throw new AssertionError(e); 306 } 307 } 308 309 /** 310 * Invoke Timstamp getNanos. 554 static final class CheckedMap_PersistenceDelegate extends java_util_Collections { 555 protected Expression instantiate(Object oldInstance, Encoder out) { 556 Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); 557 Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); 558 Map<?,?> map = new HashMap<>((Map<?,?>) oldInstance); 559 return new Expression(oldInstance, Collections.class, "checkedMap", new Object[]{map, keyType, valueType}); 560 } 561 } 562 563 static final class CheckedSortedMap_PersistenceDelegate extends java_util_Collections { 564 protected Expression instantiate(Object oldInstance, Encoder out) { 565 Object keyType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.keyType"); 566 Object valueType = MetaData.getPrivateFieldValue(oldInstance, "java.util.Collections$CheckedMap.valueType"); 567 SortedMap<?,?> map = new TreeMap<>((SortedMap<?,?>) oldInstance); 568 return new Expression(oldInstance, Collections.class, "checkedSortedMap", new Object[]{map, keyType, valueType}); 569 } 570 } 571 } 572 573 /** 574 * The persistence delegate for {@code java.util.EnumMap} classes. 575 * 576 * @author Sergey A. Malenkov 577 */ 578 static final class java_util_EnumMap_PersistenceDelegate extends PersistenceDelegate { 579 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 580 return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); 581 } 582 583 protected Expression instantiate(Object oldInstance, Encoder out) { 584 return new Expression(oldInstance, EnumMap.class, "new", new Object[] {getType(oldInstance)}); 585 } 586 587 private static Object getType(Object instance) { 588 return MetaData.getPrivateFieldValue(instance, "java.util.EnumMap.keyType"); 589 } 590 } 591 592 /** 593 * The persistence delegate for {@code java.util.EnumSet} classes. 594 * 595 * @author Sergey A. Malenkov 596 */ 597 static final class java_util_EnumSet_PersistenceDelegate extends PersistenceDelegate { 598 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 599 return super.mutatesTo(oldInstance, newInstance) && (getType(oldInstance) == getType(newInstance)); 600 } 601 602 protected Expression instantiate(Object oldInstance, Encoder out) { 603 return new Expression(oldInstance, EnumSet.class, "noneOf", new Object[] {getType(oldInstance)}); 604 } 605 606 private static Object getType(Object instance) { 607 return MetaData.getPrivateFieldValue(instance, "java.util.EnumSet.elementType"); 608 } 609 } 610 611 // Collection 612 static class java_util_Collection_PersistenceDelegate extends DefaultPersistenceDelegate { 613 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { |