339
340 /*
341 The Hashtable and AbstractMap classes have no common ancestor yet may
342 be handled with a single persistence delegate: one which uses the methods
343 of the Map insterface exclusively. Attatching the persistence delegates
344 to the interfaces themselves is fraught however since, in the case of
345 the Map, both the AbstractMap and HashMap classes are declared to
346 implement the Map interface, leaving the obvious implementation prone
347 to repeating their initialization. These issues and questions around
348 the ordering of delegates attached to interfaces have lead us to
349 ignore any delegates attached to interfaces and force all persistence
350 delegates to be registered with concrete classes.
351 */
352
353 /**
354 * The base class for persistence delegates for inner classes
355 * that can be created using {@link Collections}.
356 *
357 * @author Sergey A. Malenkov
358 */
359 private static abstract class java_util_Collections extends PersistenceDelegate {
360 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
361 if (!super.mutatesTo(oldInstance, newInstance)) {
362 return false;
363 }
364 if ((oldInstance instanceof List) || (oldInstance instanceof Set) || (oldInstance instanceof Map)) {
365 return oldInstance.equals(newInstance);
366 }
367 Collection<?> oldC = (Collection<?>) oldInstance;
368 Collection<?> newC = (Collection<?>) newInstance;
369 return (oldC.size() == newC.size()) && oldC.containsAll(newC);
370 }
371
372 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
373 // do not initialize these custom collections in default way
374 }
375
376 static final class EmptyList_PersistenceDelegate extends java_util_Collections {
377 protected Expression instantiate(Object oldInstance, Encoder out) {
378 return new Expression(oldInstance, Collections.class, "emptyList", null);
379 }
1302 // it is possible because MatteBorder is assignable from MatteBorderUIResource
1303 internalPersistenceDelegates.put("javax.swing.plaf.BorderUIResource$MatteBorderUIResource",
1304 new javax_swing_border_MatteBorder_PersistenceDelegate());
1305
1306 // it is possible because FontUIResource is supported by java_awt_Font_PersistenceDelegate
1307 internalPersistenceDelegates.put("javax.swing.plaf.FontUIResource",
1308 new java_awt_Font_PersistenceDelegate());
1309
1310 // it is possible because KeyStroke is supported by java_awt_AWTKeyStroke_PersistenceDelegate
1311 internalPersistenceDelegates.put("javax.swing.KeyStroke",
1312 new java_awt_AWTKeyStroke_PersistenceDelegate());
1313
1314 internalPersistenceDelegates.put("java.sql.Date", new java_util_Date_PersistenceDelegate());
1315 internalPersistenceDelegates.put("java.sql.Time", new java_util_Date_PersistenceDelegate());
1316
1317 internalPersistenceDelegates.put("java.util.JumboEnumSet", new java_util_EnumSet_PersistenceDelegate());
1318 internalPersistenceDelegates.put("java.util.RegularEnumSet", new java_util_EnumSet_PersistenceDelegate());
1319 }
1320
1321 @SuppressWarnings("rawtypes")
1322 public synchronized static PersistenceDelegate getPersistenceDelegate(Class type) {
1323 if (type == null) {
1324 return nullPersistenceDelegate;
1325 }
1326 if (Enum.class.isAssignableFrom(type)) {
1327 return enumPersistenceDelegate;
1328 }
1329 if (null != XMLEncoder.primitiveTypeFor(type)) {
1330 return primitivePersistenceDelegate;
1331 }
1332 // The persistence delegate for arrays is non-trivial; instantiate it lazily.
1333 if (type.isArray()) {
1334 if (arrayPersistenceDelegate == null) {
1335 arrayPersistenceDelegate = new ArrayPersistenceDelegate();
1336 }
1337 return arrayPersistenceDelegate;
1338 }
1339 // Handle proxies lazily for backward compatibility with 1.2.
1340 try {
1341 if (java.lang.reflect.Proxy.isProxyClass(type)) {
1342 if (proxyPersistenceDelegate == null) {
|
339
340 /*
341 The Hashtable and AbstractMap classes have no common ancestor yet may
342 be handled with a single persistence delegate: one which uses the methods
343 of the Map insterface exclusively. Attatching the persistence delegates
344 to the interfaces themselves is fraught however since, in the case of
345 the Map, both the AbstractMap and HashMap classes are declared to
346 implement the Map interface, leaving the obvious implementation prone
347 to repeating their initialization. These issues and questions around
348 the ordering of delegates attached to interfaces have lead us to
349 ignore any delegates attached to interfaces and force all persistence
350 delegates to be registered with concrete classes.
351 */
352
353 /**
354 * The base class for persistence delegates for inner classes
355 * that can be created using {@link Collections}.
356 *
357 * @author Sergey A. Malenkov
358 */
359 private abstract static class java_util_Collections extends PersistenceDelegate {
360 protected boolean mutatesTo(Object oldInstance, Object newInstance) {
361 if (!super.mutatesTo(oldInstance, newInstance)) {
362 return false;
363 }
364 if ((oldInstance instanceof List) || (oldInstance instanceof Set) || (oldInstance instanceof Map)) {
365 return oldInstance.equals(newInstance);
366 }
367 Collection<?> oldC = (Collection<?>) oldInstance;
368 Collection<?> newC = (Collection<?>) newInstance;
369 return (oldC.size() == newC.size()) && oldC.containsAll(newC);
370 }
371
372 protected void initialize(Class<?> type, Object oldInstance, Object newInstance, Encoder out) {
373 // do not initialize these custom collections in default way
374 }
375
376 static final class EmptyList_PersistenceDelegate extends java_util_Collections {
377 protected Expression instantiate(Object oldInstance, Encoder out) {
378 return new Expression(oldInstance, Collections.class, "emptyList", null);
379 }
1302 // it is possible because MatteBorder is assignable from MatteBorderUIResource
1303 internalPersistenceDelegates.put("javax.swing.plaf.BorderUIResource$MatteBorderUIResource",
1304 new javax_swing_border_MatteBorder_PersistenceDelegate());
1305
1306 // it is possible because FontUIResource is supported by java_awt_Font_PersistenceDelegate
1307 internalPersistenceDelegates.put("javax.swing.plaf.FontUIResource",
1308 new java_awt_Font_PersistenceDelegate());
1309
1310 // it is possible because KeyStroke is supported by java_awt_AWTKeyStroke_PersistenceDelegate
1311 internalPersistenceDelegates.put("javax.swing.KeyStroke",
1312 new java_awt_AWTKeyStroke_PersistenceDelegate());
1313
1314 internalPersistenceDelegates.put("java.sql.Date", new java_util_Date_PersistenceDelegate());
1315 internalPersistenceDelegates.put("java.sql.Time", new java_util_Date_PersistenceDelegate());
1316
1317 internalPersistenceDelegates.put("java.util.JumboEnumSet", new java_util_EnumSet_PersistenceDelegate());
1318 internalPersistenceDelegates.put("java.util.RegularEnumSet", new java_util_EnumSet_PersistenceDelegate());
1319 }
1320
1321 @SuppressWarnings("rawtypes")
1322 public static synchronized PersistenceDelegate getPersistenceDelegate(Class type) {
1323 if (type == null) {
1324 return nullPersistenceDelegate;
1325 }
1326 if (Enum.class.isAssignableFrom(type)) {
1327 return enumPersistenceDelegate;
1328 }
1329 if (null != XMLEncoder.primitiveTypeFor(type)) {
1330 return primitivePersistenceDelegate;
1331 }
1332 // The persistence delegate for arrays is non-trivial; instantiate it lazily.
1333 if (type.isArray()) {
1334 if (arrayPersistenceDelegate == null) {
1335 arrayPersistenceDelegate = new ArrayPersistenceDelegate();
1336 }
1337 return arrayPersistenceDelegate;
1338 }
1339 // Handle proxies lazily for backward compatibility with 1.2.
1340 try {
1341 if (java.lang.reflect.Proxy.isProxyClass(type)) {
1342 if (proxyPersistenceDelegate == null) {
|