protected <T> T createProxy(T proxyObject, Class<T> proxyInterface) { if (proxyObject instanceof Proxy) { InvocationHandler h = handler(proxyObject); if (h != null && h instanceof ModificationProxy) { return proxyObject; } } return ModificationProxy.create(proxyObject, proxyInterface); }
/** Flag which indicates whether any properties of the object being proxied are changed. */ public boolean isDirty() { boolean dirty = false; for (Iterator i = properties().entrySet().iterator(); i.hasNext() && !dirty; ) { Map.Entry e = (Map.Entry) i.next(); if (e.getValue() instanceof Proxy) { ModificationProxy h = handler(e.getValue()); if (h != null && !h.isDirty()) { continue; } } else { try { Object orig = unwrap(getter((String) e.getKey()).invoke(proxyObject, null)); if (orig == null) { if (e.getValue() == null) { continue; } } else if (e.getValue() != null && orig.equals(e.getValue())) { continue; } } catch (Exception ex) { throw new RuntimeException(ex); } } dirty = true; } return dirty; }
List<String> getDirtyProperties() { List<String> propertyNames = new ArrayList<String>(); for (String propertyName : properties().keySet()) { // in the case this property is another proxy, check that it is actually dirty Object value = properties.get(propertyName); if (value instanceof Proxy) { ModificationProxy h = handler(value); if (h != null && !h.isDirty()) { // proxy reports it is not dirty, only return this property if the underling // value is not the same as the current value of the property on the object Object curr = unwrap(value); try { Object orig = unwrap(getter(propertyName).invoke(proxyObject, null)); if (curr == orig) { continue; } } catch (Exception e) { throw new RuntimeException(e); } } } propertyNames.add(propertyName); } return propertyNames; }
@Override public boolean matches(Object item) { ModificationProxy handler = ModificationProxy.handler(item); if (handler == null) { return false; } return objectMatcher.matches(handler.getProxyObject()); }
ModificationProxy h = handler(v); if (h != null && h.isDirty()) { h.commit();
if (ModificationProxy.handler(source) != null) { return source;
@Test public void testRewrapCommitToNew() throws Exception { TestBean bean = new TestBeanImpl("Mr. Bean", "Uhh", "Bean"); TestBean newBean = new TestBeanImpl("Johnny English", "Not", "Bond"); TestBean proxy = ModificationProxy.create(bean, TestBean.class); proxy.setValue("Edmond Blackadder"); proxy.setListValue(Arrays.asList("Cunning", "Plan")); // Swap the old bean for the new one TestBean result = ModificationProxy.rewrap(proxy, b -> newBean, TestBean.class); // Commit the changes ModificationProxy.handler(result).commit(); // The changes should not have been committed to either bean assertThat(bean.getValue(), equalTo("Mr. Bean")); assertThat(bean.getListValue(), contains("Uhh", "Bean")); assertThat(newBean.getValue(), equalTo("Edmond Blackadder")); assertThat(newBean.getListValue(), contains("Cunning", "Plan")); }