/* Copyright (c) 2013-2014 Boundless and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/org/documents/edl-v10.html
*
* Contributors:
* Victor Olaya (Boundless) - initial implementation
*/
package org.locationtech.geogig.api.plumbing;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import org.locationtech.geogig.api.AbstractGeoGigOp;
import org.locationtech.geogig.api.NodeRef;
import org.locationtech.geogig.api.RevFeature;
import org.locationtech.geogig.api.RevFeatureType;
import org.locationtech.geogig.api.plumbing.diff.FeatureDiff;
import com.google.common.base.Optional;
import com.google.common.base.Supplier;
/**
* Compares two features in the repository and returns a {code FeatureDiff} object representing it.
* Checking is performed to ensure that the old and new features actually correspond to two versions
* of the same feature and not to two unrelated features, so the corresponding NodeRefs have to
* point to the same path.
*
*/
public class DiffFeature extends AbstractGeoGigOp<FeatureDiff> {
private NodeRef oldNodeRef;
private NodeRef newNodeRef;
/**
* @param oldNodeRef the ref that points to the "old" version of the feature to compare
* @return {@code this}
*/
public DiffFeature setOldVersion(Supplier<NodeRef> oldNodeRef) {
this.oldNodeRef = oldNodeRef.get();
return this;
}
/**
* @param oldNodeRef the ref that points to the "old" version of the feature to compare
* @return {@code this}
*/
public DiffFeature setNewVersion(Supplier<NodeRef> newNodeRef) {
this.newNodeRef = newNodeRef.get();
return this;
}
/**
* Finds differences between the two specified trees.
*
* @return a FeatureDiff object with the differences between the specified features
* @see FeatureDiff
*/
@Override
protected FeatureDiff _call() throws IllegalArgumentException {
checkNotNull(oldNodeRef, "old version not specified");
checkNotNull(newNodeRef, "new version not specified");
String oldPath = removeRef(oldNodeRef.path());
String newPath = removeRef(newNodeRef.path());
checkArgument(oldPath.equals(newPath),
"old and new versions do not corespond to the same feature");
Optional<RevFeature> oldFeature = command(RevObjectParse.class).setObjectId(
oldNodeRef.getNode().getObjectId()).call(RevFeature.class);
checkArgument(oldFeature.isPresent(), "Invalid reference: %s", oldNodeRef);
Optional<RevFeature> newFeature = command(RevObjectParse.class).setObjectId(
newNodeRef.getNode().getObjectId()).call(RevFeature.class);
checkArgument(newFeature.isPresent(), "Invalid reference: %s", newNodeRef);
Optional<RevFeatureType> oldFeatureType = command(RevObjectParse.class).setObjectId(
oldNodeRef.getMetadataId()).call(RevFeatureType.class);
checkArgument(oldFeatureType.isPresent(), "Invalid reference: %s", oldNodeRef);
Optional<RevFeatureType> newFeatureType = command(RevObjectParse.class).setObjectId(
newNodeRef.getMetadataId()).call(RevFeatureType.class);
checkArgument(newFeatureType.isPresent(), "Invalid reference: %s", newNodeRef);
return compare(oldFeature.get(), newFeature.get(), oldFeatureType.get(),
newFeatureType.get());
}
private String removeRef(String path) {
if (path.contains(":")) {
return path.substring(path.indexOf(":") + 1);
} else {
return path;
}
}
private FeatureDiff compare(RevFeature oldRevFeature, RevFeature newRevFeature,
RevFeatureType oldRevFeatureType, RevFeatureType newRevFeatureType) {
return new FeatureDiff(oldNodeRef.path(), newRevFeature, oldRevFeature, newRevFeatureType,
oldRevFeatureType, false);
}
}