/* 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.porcelain;
import java.util.Iterator;
import java.util.Map;
import org.locationtech.geogig.api.AbstractGeoGigOp;
import org.locationtech.geogig.api.FeatureBuilder;
import org.locationtech.geogig.api.NodeRef;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.RevFeature;
import org.locationtech.geogig.api.RevFeatureType;
import org.locationtech.geogig.api.RevObject;
import org.locationtech.geogig.api.RevTree;
import org.locationtech.geogig.api.plumbing.DiffFeature;
import org.locationtech.geogig.api.plumbing.RevObjectParse;
import org.locationtech.geogig.api.plumbing.diff.DiffEntry;
import org.locationtech.geogig.api.plumbing.diff.DiffEntry.ChangeType;
import org.locationtech.geogig.api.plumbing.diff.FeatureDiff;
import org.locationtech.geogig.api.plumbing.diff.Patch;
import org.opengis.feature.Feature;
import com.google.common.base.Suppliers;
import com.google.common.collect.Maps;
/**
* Creates a patch that represents the differences between to version of the repository *
*
*/
public class CreatePatchOp extends AbstractGeoGigOp<Patch> {
/**
* The differences between the two version of the repository that are to be stored in a patch
* object
*/
private Iterator<DiffEntry> diffs;
public CreatePatchOp setDiffs(Iterator<DiffEntry> diffs) {
this.diffs = diffs;
return this;
}
@Override
protected Patch _call() {
Patch patch = new Patch();
Map<ObjectId, RevFeatureType> featureTypes = Maps.newHashMap();
while (diffs.hasNext()) {
DiffEntry diffEntry = diffs.next();
final NodeRef newObject = diffEntry.getNewObject();
final NodeRef oldObject = diffEntry.getOldObject();
if (diffEntry.changeType() == ChangeType.MODIFIED) {
RevObject revObject = command(RevObjectParse.class)
.setObjectId(diffEntry.newObjectId()).call().get();
if (revObject instanceof RevFeature) {
FeatureDiff diff = command(DiffFeature.class)
.setNewVersion(Suppliers.ofInstance(diffEntry.getNewObject()))
.setOldVersion(Suppliers.ofInstance(diffEntry.getOldObject())).call();
patch.addModifiedFeature(diff);
} else if (revObject instanceof RevTree) {
RevFeatureType oldFeatureType = command(RevObjectParse.class)
.setObjectId(diffEntry.getOldObject().getMetadataId())
.call(RevFeatureType.class).get();
RevFeatureType newFeatureType = command(RevObjectParse.class)
.setObjectId(diffEntry.getNewObject().getMetadataId())
.call(RevFeatureType.class).get();
patch.addFeatureType(oldFeatureType);
patch.addFeatureType(newFeatureType);
patch.addAlteredTree(diffEntry);
}
} else if (diffEntry.changeType() == ChangeType.ADDED) {
RevObject revObject = command(RevObjectParse.class)
.setObjectId(diffEntry.newObjectId()).call().get();
if (revObject instanceof RevFeature) {
RevFeatureType featureType;
if (featureTypes.containsKey(newObject.getMetadataId())) {
featureType = featureTypes.get(newObject.getMetadataId());
} else {
featureType = command(RevObjectParse.class)
.setObjectId(newObject.getMetadataId()).call(RevFeatureType.class)
.get();
featureTypes.put(newObject.getMetadataId(), featureType);
}
FeatureBuilder featureBuilder = new FeatureBuilder(featureType);
Feature feature = featureBuilder.build(diffEntry.newObjectId().toString(),
(RevFeature) revObject);
String name = diffEntry.newPath();
patch.addAddedFeature(name, feature, featureType);
} else if (revObject instanceof RevTree) {
ObjectId metadataId = diffEntry.getNewObject().getMetadataId();
if (!metadataId.isNull()) {
RevFeatureType featureType = command(RevObjectParse.class)
.setObjectId(metadataId).call(RevFeatureType.class).get();
patch.addAlteredTree(diffEntry);
patch.addFeatureType(featureType);
}
}
} else if (diffEntry.changeType() == ChangeType.REMOVED) {
RevObject revObject = command(RevObjectParse.class)
.setObjectId(diffEntry.oldObjectId()).call().get();
if (revObject instanceof RevFeature) {
RevFeatureType featureType;
if (featureTypes.containsKey(oldObject.getMetadataId())) {
featureType = featureTypes.get(oldObject.getMetadataId());
} else {
featureType = command(RevObjectParse.class)
.setObjectId(oldObject.getMetadataId()).call(RevFeatureType.class)
.get();
featureTypes.put(oldObject.getMetadataId(), featureType);
}
FeatureBuilder featureBuilder = new FeatureBuilder(featureType);
Feature feature = featureBuilder.build(diffEntry.oldObjectId().toString(),
(RevFeature) revObject);
String name = diffEntry.oldPath();
patch.addRemovedFeature(name, feature, featureType);
} else if (revObject instanceof RevTree) {
ObjectId metadataId = diffEntry.getOldObject().getMetadataId();
if (!metadataId.isNull()) {
RevFeatureType featureType = command(RevObjectParse.class)
.setObjectId(metadataId).call(RevFeatureType.class).get();
patch.addAlteredTree(diffEntry);
patch.addFeatureType(featureType);
}
}
}
}
return patch;
}
}