protected <U> U unwrapProxy(U proxy, java.lang.Class<U> proxyInterface) { return ModificationProxy.unwrap(proxy); }; }
synchronized (proxyObject) { for (Map.Entry<String, Object> e : properties().entrySet()) { String p = e.getKey(); Object v = e.getValue(); Method g = getter(p); c.clear(); for (Object o : (Collection) v) { c.add(unwrap(o)); m.clear(); for (Object key : proxied.keySet()) { Object uk = unwrap(key); final Object value = proxied.get(key); Object uv = unwrap(value); m.put(uk, uv); Method s = setter(p, g.getReturnType()); Info modified = (Info) unwrap(v); if (original == modified) { ModificationProxy h = handler(v); if (h != null && h.isDirty()) { h.commit();
private <T extends CatalogInfo> T wrapInModificationProxy(T ci, Class<T> clazz) { if (ci != null) { return ModificationProxy.create(ci, clazz); } else { return null; } }
protected <T extends CatalogInfo> T commitProxy(T object) { // this object is a proxy ModificationProxy h = (ModificationProxy) Proxy.getInvocationHandler(object); // get the real object T real = (T) h.getProxyObject(); // commit to the original object h.commit(); return real; }
public void save(GeoServerInfo global) { ModificationProxy proxy = (ModificationProxy) Proxy.getInvocationHandler(global); List propertyNames = proxy.getPropertyNames(); List oldValues = proxy.getOldValues(); List newValues = proxy.getNewValues(); geoServer.fireGlobalModified(global, propertyNames, oldValues, newValues); proxy.commit(); }
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; }
if (properties != null && properties().containsKey(property)) { return properties().get(property); } else { properties().put(property, wrap); oldCollectionValues().put(property, clone); return wrap; } else if (Map.class.isAssignableFrom(method.getReturnType())) { properties().put(property, wrap); oldCollectionValues().put(property, clone); return wrap; properties().put(property, args[0]); if (result != null && shouldProxyProperty(result.getClass())) { Object o = ModificationProxy.unwrap(result); if (o == result) { result = ModificationProxy.create(result, (Class) method.getReturnType()); properties().put(property, result);
private Object readResolve() throws ObjectStreamException { CatalogInfo replacement = replaceCatalogInfo((CatalogInfo) proxyObject); if (replacement != null) { proxyObject = unwrap(replacement); Object value = property.getValue(); if (value instanceof CatalogInfo) { CatalogInfo replacement = replaceCatalogInfo((CatalogInfo) value); if (replacement != null) { property.setValue(unwrap(replacement)); Collection clone = cloneCollection((Collection) value); property.setValue(clone); } else if (value instanceof MetadataMap) { MetadataMap clone = cloneMetadataMap((MetadataMap) value); property.setValue(clone); if (value instanceof Collection) { Collection oldCollection = (Collection) value; Collection clone = cloneCollection(oldCollection); oce.setValue(clone); } else if (value instanceof MetadataMap) { MetadataMap clone = cloneMetadataMap((MetadataMap) value); oce.setValue(clone);
/** * Helper method that removes from a list the catalog objects not visible in the current * context. This method takes care of the proper modification proxy unwrapping \ wrapping. * * @param objects list of catalog object, wrapped with a modification proxy * @param type the class of the list objects * @param filter filter that checks if an element should be visible * @return a list wrapped with a modification proxy that contains the visible catalog objects */ private <T extends CatalogInfo> List<T> filterIsolated( List<T> objects, Class<T> type, Function<T, T> filter) { // unwrap the catalog objects list List<T> unwrapped = ModificationProxy.unwrap(objects); // filter the non visible catalog objects and wrap the resulting list with a modification // proxy return ModificationProxy.createList( unwrapped .stream() .filter(store -> filter.apply(store) != null) .collect(Collectors.toList()), type); }
private Collection cloneCollection(Collection oldCollection) { Class<? extends Collection> oldCollectionClass = oldCollection.getClass(); try { Collection clone = oldCollectionClass.newInstance(); for (Object o : oldCollection) { if (o instanceof CatalogInfo) { CatalogInfo replacement = replaceCatalogInfo((CatalogInfo) o); if (replacement != null) { clone.add(unwrap(replacement)); } else { clone.add(o); } } else { clone.add(o); } } return clone; } catch (Exception e) { throw new RuntimeException( "Unexpected failure while cloning collection of class " + oldCollectionClass, e); } }
ModificationProxy oldHandler = handler(object); if (Objects.isNull(oldHandler)) { return innerWrap.apply(object); } else { T newProxyObject = innerWrap.apply((T) oldHandler.getProxyObject()); T newProxy = create(newProxyObject, clazz); ModificationProxy newHandler = handler(newProxy); if (Objects.nonNull(oldHandler.oldCollectionValues)) { newHandler.oldCollectionValues =
@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")); }
@Test public void testRewrapEmptyProxyIdentity() throws Exception { TestBean bean = new TestBeanImpl("Mr. Bean", "Uhh", "Bean"); TestBean proxy = ModificationProxy.create(bean, TestBean.class); TestBean result = ModificationProxy.rewrap(proxy, b -> b, TestBean.class); assertThat(result, modProxy(sameInstance(bean))); assertThat(result.getValue(), equalTo("Mr. Bean")); assertThat(result.getListValue(), contains("Uhh", "Bean")); }
@Override public boolean matches(Object item) { ModificationProxy handler = ModificationProxy.handler(item); if (handler == null) { return false; } return objectMatcher.matches(handler.getProxyObject()); }
<K> Map<K, T> getMapForValue(ConcurrentHashMap<Class<T>, Map<K, T>> maps, T value) { Class<T> vc; if (Proxy.isProxyClass(value.getClass())) { ModificationProxy h = (ModificationProxy) Proxy.getInvocationHandler(value); Object po = (T) h.getProxyObject(); vc = (Class<T>) po.getClass(); } else { vc = (Class<T>) value.getClass(); } return getMapForValue(maps, vc); }
@Test public void test() throws Exception { BeanImpl bean = new BeanImpl(); ModificationProxy handler = new ModificationProxy(bean); Class proxyClass = Proxy.getProxyClass(Bean.class.getClassLoader(), new Class[] {Bean.class}); Bean proxy = (Bean) proxyClass .getConstructor(new Class[] {InvocationHandler.class}) .newInstance(new Object[] {handler}); bean.setFoo("one"); bean.setBar(1); proxy.setFoo("two"); proxy.setBar(2); proxy.getScratch().add("x"); proxy.getScratch().add("y"); assertEquals("one", bean.getFoo()); assertEquals(Integer.valueOf(1), bean.getBar()); assertTrue(bean.getScratch().isEmpty()); assertEquals("two", proxy.getFoo()); assertEquals(Integer.valueOf(2), proxy.getBar()); assertEquals(2, proxy.getScratch().size()); handler.commit(); assertEquals("two", bean.getFoo()); assertEquals(Integer.valueOf(2), bean.getBar()); assertEquals(2, bean.getScratch().size()); }
/** * Wraps an object in a proxy. * * @throws RuntimeException If creating the proxy fails. */ public static <T> T create(T proxyObject, Class<T> clazz) { return ProxyUtils.createProxy(proxyObject, clazz, new ModificationProxy(proxyObject)); }
@Override public void save(SettingsInfo settings) { ModificationProxy proxy = (ModificationProxy) Proxy.getInvocationHandler(settings); List propertyNames = proxy.getPropertyNames(); List oldValues = proxy.getOldValues(); List newValues = proxy.getNewValues(); settings = (SettingsInfo) proxy.getProxyObject(); geoServer.fireSettingsModified(settings, propertyNames, oldValues, newValues); proxy.commit(); }
/** 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; }