@Test public void detectsMutationOfOriginal() { SampleClass testObject = new SampleClass(); testObject.setFoo("bar"); SampleClass enhanced = enhancer.enhance(testObject); ((Snapshot) enhanced).snapshot(); assertDirty(enhanced, false); assertEquals("bar", enhanced.getFoo()); testObject.setFoo(null); assertNull(enhanced.getFoo()); assertDirty(enhanced, true); ((Snapshot) enhanced).snapshot(); assertDirty(enhanced, false); testObject.setNumberObject(1234L); assertDirty(enhanced, true); assertEquals(1234L, enhanced.getNumberObject().longValue()); ((Snapshot) enhanced).snapshot(); assertDirty(enhanced, false); }
public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } protected  Enhancer(Class<T> baseClass); }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } protected  Enhancer(Class<T> baseClass); abstract boolean needsEnhancement(Object object); void validateClassIsEnhanceable(Class<T> baseClass); final Class<T> getBaseClass(); Class<? extends T> getEnhancedClass(); T newInstance(); T enhance(T t); }
Enhancer { public T enhance(T t) { if (!needsEnhancement(t)) { return t; } try { return getEnhancedClass().getConstructor(baseClass).newInstance(t); } catch (Exception e) { throw new RuntimeException(String.format("Could not enhance object %s (%s)", t, t.getClass()), e); } } protected  Enhancer(Class<T> baseClass); abstract boolean needsEnhancement(Object object); void validateClassIsEnhanceable(Class<T> baseClass); final Class<T> getBaseClass(); Class<? extends T> getEnhancedClass(); T newInstance(); T enhance(T t);  }