Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/main/java/de/danielbechler/diff/BeanDiffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package de.danielbechler.diff;

import de.danielbechler.diff.accessor.*;
import de.danielbechler.diff.accessor.exception.ExceptionListener;
import de.danielbechler.diff.introspect.*;
import de.danielbechler.diff.node.*;
import de.danielbechler.util.*;
Expand All @@ -34,11 +35,11 @@ final class BeanDiffer implements Differ<Node>
private BeanPropertyComparisonDelegator beanPropertyComparisonDelegator;
private DefaultNodeFactory defaultNodeFactory = new DefaultNodeFactory();

public BeanDiffer(final DifferDelegator delegator, final NodeInspector nodeInspector)
public BeanDiffer(final DifferDelegator delegator, final NodeInspector nodeInspector, final ExceptionListener exceptionListener)
{
Assert.notNull(delegator, "delegator");
Assert.notNull(nodeInspector, "configuration");
this.beanPropertyComparisonDelegator = new BeanPropertyComparisonDelegator(delegator, nodeInspector);
this.beanPropertyComparisonDelegator = new BeanPropertyComparisonDelegator(delegator, nodeInspector, exceptionListener);
this.nodeInspector = nodeInspector;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
package de.danielbechler.diff;

import de.danielbechler.diff.accessor.*;
import de.danielbechler.diff.accessor.exception.ExceptionListener;
import de.danielbechler.diff.accessor.exception.PropertyReadException;
import de.danielbechler.diff.accessor.exception.PropertyWriteException;
import de.danielbechler.diff.node.*;
import de.danielbechler.util.*;

Expand All @@ -26,14 +29,17 @@ class BeanPropertyComparisonDelegator
private final DifferDelegator delegator;
private final NodeInspector nodeInspector;
private PropertyNodeFactory propertyNodeFactory = new PropertyNodeFactory();
private final ExceptionListener exceptionListener;

public BeanPropertyComparisonDelegator(final DifferDelegator delegator, final NodeInspector nodeInspector)
public BeanPropertyComparisonDelegator(final DifferDelegator delegator, final NodeInspector nodeInspector, final ExceptionListener exceptionListener)
{
Assert.notNull(delegator, "delegator");
Assert.notNull(nodeInspector, "nodeInspector");
Assert.notNull(exceptionListener, "exceptionListener");

this.delegator = delegator;
this.nodeInspector = nodeInspector;
this.exceptionListener = exceptionListener;
}

public Node compare(final Node beanNode, final Instances beanInstances, final Accessor propertyAccessor)
Expand All @@ -51,7 +57,13 @@ public Node compare(final Node beanNode, final Instances beanInstances, final Ac
}
else
{
return delegator.delegate(beanNode, beanInstances.access(propertyAccessor));
try {
return delegator.delegate(beanNode, beanInstances.access(propertyAccessor));
} catch(PropertyReadException e) {
return exceptionListener.onPropertyReadException(e, propertyNode);
} catch(PropertyWriteException e) {
return exceptionListener.onPropertyWriteException(e, propertyNode);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/java/de/danielbechler/diff/DifferFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ else if (Map.class.isAssignableFrom(type))
}
else
{
return new BeanDiffer(delegator, configuration);
return new BeanDiffer(delegator, configuration, configuration.getExceptionListener());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,7 @@ private void invokeWriteMethod(final Object target, final Object value)
}
catch (Exception e)
{
logFailedSet(value);

final PropertyWriteException ex = new PropertyWriteException(e);
final PropertyWriteException ex = new PropertyWriteException(e, value);
ex.setPropertyName(propertyName);
ex.setTargetType(getType());
throw ex;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package de.danielbechler.diff.accessor.exception;

import de.danielbechler.diff.node.*;
import org.slf4j.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import de.danielbechler.diff.node.Node;

/**
* Handler for recoverable exceptional states which logs the warning or info messages into log. The exception
Expand All @@ -19,4 +21,15 @@ public void onCircularReferenceException(final Node node)
+ "this instance along the current path.";
logger.warn(message, node.getPropertyPath());
}
}

public Node onPropertyWriteException(final PropertyWriteException ex, final Node propertyNode)
{
logger.info("Couldn't set new value '{}' for property '{}'", ex.getNewValue(), ex.getPropertyName());
throw ex;
}

public Node onPropertyReadException(final PropertyReadException ex, final Node propertyNode)
{
throw ex;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,26 @@ public interface ExceptionListener
* @param node The node which has been detected to cause a circular reference.
*/
void onCircularReferenceException(Node node);
}

/**
* Called when PropertyWriteException happens.
*
* @param e
* PropertyWriteException itself.
* @param propertyNode
* Node of the property that we were unable to write to.
* @return Resulting node.
*/
Node onPropertyWriteException(PropertyWriteException e, Node propertyNode);

/**
* Called when PropertyReadException happens.
*
* @param ex
* The PropertyReadException itself.
* @param propertyNode
* Node of the property that we were unable to read.
* @return Node as a result of wrong read.
*/
Node onPropertyReadException(PropertyReadException ex, Node propertyNode);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,22 @@
public class PropertyWriteException extends PropertyException
{
private static final long serialVersionUID = 1L;
private final Object newValue;

public PropertyWriteException(final Throwable cause)
public PropertyWriteException(final Throwable cause, final Object newValue)
{
super(cause);
this.newValue = newValue;
}

@Override
public String getMessage()
{
return "Error while invoking write method. ";
}

public Object getNewValue()
{
return newValue;
}
}
11 changes: 7 additions & 4 deletions src/test/java/de/danielbechler/diff/BeanDifferShould.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@
package de.danielbechler.diff;

import de.danielbechler.diff.accessor.*;
import de.danielbechler.diff.accessor.exception.DefaultExceptionListener;
import de.danielbechler.diff.introspect.*;
import de.danielbechler.diff.mock.*;
import de.danielbechler.diff.node.*;
import de.danielbechler.diff.path.*;

import org.mockito.Mock;
import org.testng.annotations.*;

Expand Down Expand Up @@ -51,7 +53,7 @@ public void setUp()
{
initMocks(this);
configuration = new Configuration();
differ = new BeanDiffer(delegator, configuration);
differ = new BeanDiffer(delegator, configuration, configuration.getExceptionListener());
differ.setIntrospector(introspector);
}

Expand Down Expand Up @@ -165,12 +167,13 @@ public void compare_bean_via_introspection_and_delegate_comparison_of_properties

when(defaultNodeFactory.createNode(Node.ROOT, beanInstances)).thenReturn(beanNode);
when(configuration.isIntrospectible(beanNode)).thenReturn(true);
when(configuration.getExceptionListener()).thenReturn(new DefaultExceptionListener());
doReturn(beanType).when(beanInstances).getType();
when(introspector.introspect(beanType)).thenReturn(asList(propertyAccessor));
when(beanPropertyComparer.compare(beanNode, beanInstances, propertyAccessor)).thenReturn(propertyNode);
when(configuration.isReturnable(propertyNode)).thenReturn(true);

differ = new BeanDiffer(delegator, configuration);
differ = new BeanDiffer(delegator, configuration, configuration.getExceptionListener());
differ.setIntrospector(introspector);
differ.setBeanPropertyComparisonDelegator(beanPropertyComparer);
differ.setDefaultNodeFactory(defaultNodeFactory);
Expand All @@ -183,12 +186,12 @@ public void compare_bean_via_introspection_and_delegate_comparison_of_properties
@Test(expectedExceptions = IllegalArgumentException.class)
public void fail_construction_without_delegator()
{
new BeanDiffer(null, configuration);
new BeanDiffer(null, configuration, configuration.getExceptionListener());
}

@Test(expectedExceptions = IllegalArgumentException.class)
public void fail_construction_without_configuration()
{
new BeanDiffer(delegator, null);
new BeanDiffer(delegator, null, new DefaultExceptionListener());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package de.danielbechler.diff;

import de.danielbechler.diff.accessor.*;
import de.danielbechler.diff.accessor.exception.DefaultExceptionListener;
import de.danielbechler.diff.node.*;

import org.mockito.Mock;
import org.testng.annotations.*;

Expand All @@ -42,8 +44,8 @@ public class BeanPropertyComparisonDelegatorShould
protected void setUp() throws Exception
{
initMocks(this);

beanPropertyComparisonDelegator = new BeanPropertyComparisonDelegator(delegator, configuration);
when(configuration.getExceptionListener()).thenReturn(new DefaultExceptionListener());
beanPropertyComparisonDelegator = new BeanPropertyComparisonDelegator(delegator, configuration, configuration.getExceptionListener());
beanPropertyComparisonDelegator.setPropertyNodeFactory(propertyNodeFactory);
}

Expand Down Expand Up @@ -94,13 +96,13 @@ public void delegate_property_comparison()
@Test(expectedExceptions = IllegalArgumentException.class)
public void fail_if_constructed_without_delegator()
{
new BeanPropertyComparisonDelegator(null, configuration);
new BeanPropertyComparisonDelegator(null, configuration, configuration.getExceptionListener());
}

@Test(expectedExceptions = IllegalArgumentException.class)
public void fail_if_constructed_without_configuration()
{
new BeanPropertyComparisonDelegator(delegator, null);
new BeanPropertyComparisonDelegator(delegator, null, new DefaultExceptionListener());
}

@Test(expectedExceptions = IllegalArgumentException.class)
Expand Down
4 changes: 4 additions & 0 deletions src/test/java/de/danielbechler/diff/DifferFactoryShould.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@

package de.danielbechler.diff;

import de.danielbechler.diff.accessor.exception.DefaultExceptionListener;
import de.danielbechler.diff.mock.*;

import org.mockito.Mock;
import org.testng.annotations.*;

import java.util.*;

import static org.fest.assertions.api.Assertions.*;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.*;

/** @author Daniel Bechler */
Expand All @@ -38,6 +41,7 @@ public class DifferFactoryShould
public void initDifferFactory()
{
initMocks(this);
when(configuration.getExceptionListener()).thenReturn(new DefaultExceptionListener());
differFactory = new DifferFactory(configuration);
}

Expand Down