net.sf.brunneng.jom.diff.DiffNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of java-object-merger Show documentation
Show all versions of java-object-merger Show documentation
Tool for merging objects of possible different type but similar structure
package net.sf.brunneng.jom.diff;
import net.sf.brunneng.jom.JomUtils;
import net.sf.brunneng.jom.MergingContext;
import net.sf.brunneng.jom.configuration.Configuration;
import net.sf.brunneng.jom.snapshot.DataNode;
import net.sf.brunneng.jom.snapshot.Property;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
/**
* Abstract node for diff tree.
*
This class is from library internals, and should not be used in general use cases.
* @param type of destination
* @param type of source
*/
public abstract class DiffNode {
private DiffNode parent;
private List children = new ArrayList();
private ChangeType changeType;
private DestT dest;
private SrcT src;
private ConvertedObject convertedSrcObject;
private Configuration configuration;
private boolean skip;
private boolean applied;
private Object resultDestObject;
public DiffNode(DiffNode parent, DestT dest, SrcT src) {
this.parent = parent;
this.dest = dest;
this.src = src;
}
public DiffNode getParent() {
return parent;
}
public void setParent(DiffNode parent) {
this.parent = parent;
}
public List getChildren() {
return children;
}
public void setChildren(List children) {
this.children = children;
}
public void addChild(DiffNode child) {
children.add(child);
}
public ChangeType getChangeType() {
return changeType;
}
public void setChangeType(ChangeType changeType) {
this.changeType = changeType;
}
public DestT getDest() {
return dest;
}
public void setDest(DestT dest) {
this.dest = dest;
}
public SrcT getSrc() {
return src;
}
public void setSrc(SrcT src) {
this.src = src;
}
/**
* @return is this node should be skipped during applying of diff?
*/
public boolean isSkip() {
return skip;
}
/**
* @param skip is this node should be skipped during applying of diff?
*/
public void setSkip(boolean skip) {
this.skip = skip;
}
public void visit(IVisitorCallback callback) {
visitInternal(callback);
}
private VisitorNavigationCommand visitInternal(IVisitorCallback callback) {
VisitorNavigationCommand command = callback.onVisit(this);
if (VisitorNavigationCommand.NEXT.equals(command)) {
for (DiffNode child : children) {
command = child.visitInternal(callback);
if (VisitorNavigationCommand.STOP.equals(command)) {
break;
}
}
}
return command;
}
public DiffNode findDiffNodeByDestProperty(Property property) {
DiffNode res = null;
for (DiffNode child : children) {
res = child.findDiffNodeByDestProperty(property);
if (res != null) {
break;
}
}
return res;
}
public DiffNode findDiffNodeBySrcProperty(Property property) {
DiffNode res = null;
for (DiffNode child : children) {
res = child.findDiffNodeBySrcProperty(property);
if (res != null) {
break;
}
}
return res;
}
public final Class getDestObjectClass() {
return JomUtils.toClass(getDestObjectType());
}
public abstract Type getDestObjectType();
public abstract DataNode getDestDataNode();
public abstract DataNode getSrcDataNode();
public Object getNotConvertedDestObject() {
return getDestDataNode().getObject();
}
public Object getNotConvertedSrcObject() {
return getSrcDataNode().getObject();
}
public Configuration getConfiguration(MergingContext context) throws MultipleConfigurationException {
Configuration res = configuration;
if (res != null) {
return res;
}
Configuration destConfiguration = getDestConfiguration();
Configuration srcConfiguration = getSrcConfiguration();
if (destConfiguration == srcConfiguration) {
res = destConfiguration;
}
else if (destConfiguration != null && srcConfiguration == null) {
res = destConfiguration;
}
else if (destConfiguration == null && srcConfiguration != null) {
res = srcConfiguration;
}
else {
if (destConfiguration.hasParent(srcConfiguration)) {
res = destConfiguration;
}
else if (srcConfiguration.hasParent(destConfiguration)) {
res = srcConfiguration;
}
else {
throw new MultipleConfigurationException(String.format("Two configurations '%s' and '%s' " +
"from different branches was found for diff node %s",
destConfiguration.getId(), srcConfiguration.getId(), this.toString()));
}
}
if (res == null && context != null) {
res = context.getRootConfiguration();
}
return res;
}
/**
* @return destination property descriptor of current node or nearest parent which have property descriptor.
* null - if property descriptor not found.
*/
public PropertyDescriptor findDestPropertyDescriptor() {
return parent != null ? parent.findDestPropertyDescriptor() : null;
}
/**
* @return source property descriptor of current node or nearest parent which have property descriptor.
* null - if property descriptor not found.
*/
public List findSrcPropertiesDescriptors() {
return parent != null ? parent.findSrcPropertiesDescriptors() : null;
}
public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
}
protected abstract Configuration getDestConfiguration();
protected abstract Configuration getSrcConfiguration();
public ConvertedObject getConvertedSrcObject() {
return convertedSrcObject;
}
public void setConvertedSrcObject(ConvertedObject convertedSrcObject) {
this.convertedSrcObject = convertedSrcObject;
}
/**
* @return resulting destination object -> new/existing value of property or
* new/existing collection/map entry.
* This is new object in case of ADD or REPLACE change, existing object in case of MODIFY change, or null in case
* of DELETE change.
* Note: this object is set after applying of diff!
* @see ChangeType
*/
public Object getResultDestObject() {
return resultDestObject;
}
public void setResultDestObject(Object resultDestObject) {
this.resultDestObject = resultDestObject;
}
/**
* @return is this diff node applied? If yes, then it will not be applied again anymore.
*/
public boolean isApplied() {
return applied;
}
public void setApplied(boolean applied) {
this.applied = applied;
}
@Override
public String toString() {
return new DiffFineStringPresenter().toString(this);
}
}