1 7 package java.beans; 8 9 import java.util.*; 10 import java.lang.reflect.*; 11 import java.beans.*; 12 import java.io.*; 13 import sun.reflect.misc.*; 14 15 16 43 44 public class DefaultPersistenceDelegate extends PersistenceDelegate { 45 private String [] constructor; 46 private Boolean definesEquals; 47 48 53 public DefaultPersistenceDelegate() { 54 this(new String [0]); 55 } 56 57 78 public DefaultPersistenceDelegate(String [] constructorPropertyNames) { 79 this.constructor = constructorPropertyNames; 80 } 81 82 private static boolean definesEquals(Class type) { 83 try { 84 type.getDeclaredMethod("equals", new Class []{Object .class}); 85 return true; 86 } 87 catch(NoSuchMethodException e) { 88 return false; 89 } 90 } 91 92 private boolean definesEquals(Object instance) { 93 if (definesEquals != null) { 94 return (definesEquals == Boolean.TRUE); 95 } 96 else { 97 boolean result = definesEquals(instance.getClass()); 98 definesEquals = result ? Boolean.TRUE : Boolean.FALSE; 99 return result; 100 } 101 } 102 103 117 protected boolean mutatesTo(Object oldInstance, Object newInstance) { 118 return (constructor.length == 0) || !definesEquals(oldInstance) ? 121 super.mutatesTo(oldInstance, newInstance) : 122 oldInstance.equals(newInstance); 123 } 124 125 137 protected Expression instantiate(Object oldInstance, Encoder out) { 138 int nArgs = constructor.length; 139 Class type = oldInstance.getClass(); 140 Object [] constructorArgs = new Object [nArgs]; 142 for(int i = 0; i < nArgs; i++) { 143 149 String name = constructor[i]; 150 151 Field f = null; 152 try { 153 f = type.getDeclaredField(name); 155 f.setAccessible(true); 156 } 157 catch (NoSuchFieldException e) {} 158 try { 159 constructorArgs[i] = (f != null && !Modifier.isStatic(f.getModifiers())) ? 160 f.get(oldInstance) : 161 MethodUtil.invoke(ReflectionUtils.getPublicMethod(type, "get" + NameGenerator.capitalize(name), 162 new Class [0]), oldInstance, new Object [0]); 163 } 164 catch (Exception e) { 165 out.getExceptionListener().exceptionThrown(e); 166 } 167 } 168 return new Expression (oldInstance, oldInstance.getClass(), "new", constructorArgs); 169 } 170 171 private boolean isTransient(Class type, PropertyDescriptor pd) { 174 if (type == null) { 175 return false; 176 } 177 188 String pName = pd.getName(); 189 BeanInfo info = MetaData.getBeanInfo(type); 190 PropertyDescriptor [] propertyDescriptors = info.getPropertyDescriptors(); 191 for (int i = 0; i < propertyDescriptors.length; ++i ) { 192 PropertyDescriptor pd2 = propertyDescriptors[i]; 193 if (pName.equals(pd2.getName())) { 194 Object value = pd2.getValue("transient"); 195 if (value != null) { 196 return Boolean.TRUE.equals(value); 197 } 198 } 199 } 200 return isTransient(type.getSuperclass(), pd); 201 } 202 203 private static boolean equals(Object o1, Object o2) { 204 return (o1 == null) ? (o2 == null) : o1.equals(o2); 205 } 206 207 private void doProperty(Class type, PropertyDescriptor pd, Object oldInstance, Object newInstance, Encoder out) throws Exception { 208 Method getter = pd.getReadMethod(); 209 Method setter = pd.getWriteMethod(); 210 211 if (getter != null && setter != null && !isTransient(type, pd)) { 212 Expression oldGetExp = new Expression (oldInstance, getter.getName(), new Object []{}); 213 Expression newGetExp = new Expression (newInstance, getter.getName(), new Object []{}); 214 Object oldValue = oldGetExp.getValue(); 215 Object newValue = newGetExp.getValue(); 216 out.writeExpression(oldGetExp); 217 if (!equals(newValue, out.get(oldValue))) { 218 Object e = (Object [])pd.getValue("enumerationValues"); 220 if (e instanceof Object [] && Array.getLength(e) % 3 == 0) { 221 Object [] a = (Object [])e; 222 for(int i = 0; i < a.length; i = i + 3) { 223 try { 224 Field f = type.getField((String )a[i]); 225 if (f.get(null).equals(oldValue)) { 226 out.remove(oldValue); 227 out.writeExpression(new Expression (oldValue, f, "get", new Object []{null})); 228 } 229 } 230 catch (Exception ex) {} 231 } 232 } 233 invokeStatement(oldInstance, setter.getName(), new Object []{oldValue}, out); 234 } 235 } 236 } 237 238 static void invokeStatement(Object instance, String methodName, Object [] args, Encoder out) { 239 out.writeStatement(new Statement (instance, methodName, args)); 240 } 241 242 private void initBean(Class type, Object oldInstance, Object newInstance, Encoder out) { 244 BeanInfo info = MetaData.getBeanInfo(type); 246 247 PropertyDescriptor [] propertyDescriptors = info.getPropertyDescriptors(); 249 for (int i = 0; i < propertyDescriptors.length; ++i ) { 250 try { 251 doProperty(type, propertyDescriptors[i], oldInstance, newInstance, out); 252 } 253 catch (Exception e) { 254 out.getExceptionListener().exceptionThrown(e); 255 } 256 } 257 258 282 if (!java.awt.Component .class.isAssignableFrom(type)) { 283 return; } 285 EventSetDescriptor [] eventSetDescriptors = info.getEventSetDescriptors(); 286 for (int e = 0; e < eventSetDescriptors.length; e++) { 287 EventSetDescriptor d = eventSetDescriptors[e]; 288 Class listenerType = d.getListenerType(); 289 290 291 if (listenerType == java.awt.event.ComponentListener .class) { 294 continue; 295 } 296 297 if (listenerType == javax.swing.event.ChangeListener .class && 305 type == javax.swing.JMenuItem .class) { 306 continue; 307 } 308 309 EventListener[] oldL = new EventListener[0]; 310 EventListener[] newL = new EventListener[0]; 311 try { 312 Method m = d.getGetListenerMethod(); 313 oldL = (EventListener[])MethodUtil.invoke(m, oldInstance, new Object []{}); 314 newL = (EventListener[])MethodUtil.invoke(m, newInstance, new Object []{}); 315 } 316 catch (Throwable e2) { 317 try { 318 Method m = type.getMethod("getListeners", new Class []{Class .class}); 319 oldL = (EventListener[])MethodUtil.invoke(m, oldInstance, new Object []{listenerType}); 320 newL = (EventListener[])MethodUtil.invoke(m, newInstance, new Object []{listenerType}); 321 } 322 catch (Exception e3) { 323 return; 324 } 325 } 326 327 String addListenerMethodName = d.getAddListenerMethod().getName(); 330 for (int i = newL.length; i < oldL.length; i++) { 331 invokeStatement(oldInstance, addListenerMethodName, new Object []{oldL[i]}, out); 333 } 334 335 String removeListenerMethodName = d.getRemoveListenerMethod().getName(); 336 for (int i = oldL.length; i < newL.length; i++) { 337 invokeStatement(oldInstance, removeListenerMethodName, new Object []{oldL[i]}, out); 338 } 339 } 340 } 341 342 388 protected void initialize(Class <?> type, 389 Object oldInstance, Object newInstance, 390 Encoder out) 391 { 392 super.initialize(type, oldInstance, newInstance, out); 394 if (oldInstance.getClass() == type) { initBean(type, oldInstance, newInstance, out); 396 } 397 } 398 } 399 | Popular Tags |