use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class ShpExportDiff method getFeatureType.
private SimpleFeatureType getFeatureType(String path, GeogigCLI cli) {
checkParameter(path != null, "No path specified.");
String refspec;
if (path.contains(":")) {
refspec = path;
} else {
refspec = "WORK_HEAD:" + path;
}
checkParameter(!refspec.endsWith(":"), "No path specified.");
final GeoGIG geogig = cli.getGeogig();
Optional<ObjectId> rootTreeId = geogig.command(ResolveTreeish.class).setTreeish(refspec.split(":")[0]).call();
checkParameter(rootTreeId.isPresent(), "Couldn't resolve '" + refspec + "' to a treeish object");
RevTree rootTree = geogig.getRepository().getTree(rootTreeId.get());
Optional<NodeRef> featureTypeTree = geogig.command(FindTreeChild.class).setChildPath(refspec.split(":")[1]).setParent(rootTree).setIndex(true).call();
checkParameter(featureTypeTree.isPresent(), "pathspec '" + refspec.split(":")[1] + "' did not match any valid path");
Optional<RevObject> revObject = cli.getGeogig().command(RevObjectParse.class).setObjectId(featureTypeTree.get().getMetadataId()).call();
if (revObject.isPresent() && revObject.get() instanceof RevFeatureType) {
RevFeatureType revFeatureType = (RevFeatureType) revObject.get();
if (revFeatureType.type() instanceof SimpleFeatureType) {
return (SimpleFeatureType) revFeatureType.type();
} else {
throw new InvalidParameterException("Cannot find feature type for the specified path");
}
} else {
throw new InvalidParameterException("Cannot find feature type for the specified path");
}
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class ExportDiffOp method _call.
/**
* Executes the export operation using the parameters that have been specified.
*
* @return a FeatureCollection with the specified features
*/
@Override
protected SimpleFeatureStore _call() {
final SimpleFeatureStore targetStore = getTargetStore();
final String refspec = old ? oldRef : newRef;
final RevTree rootTree = resolveRootTree(refspec);
final NodeRef typeTreeRef = resolTypeTreeRef(refspec, path, rootTree);
final ObjectId defaultMetadataId = typeTreeRef.getMetadataId();
final ProgressListener progressListener = getProgressListener();
progressListener.started();
progressListener.setDescription("Exporting diffs for path '" + path + "'... ");
FeatureCollection<SimpleFeatureType, SimpleFeature> asFeatureCollection = new BaseFeatureCollection<SimpleFeatureType, SimpleFeature>() {
@Override
public FeatureIterator<SimpleFeature> features() {
Iterator<DiffEntry> diffs = command(DiffOp.class).setOldVersion(oldRef).setNewVersion(newRef).setFilter(path).call();
final Iterator<SimpleFeature> plainFeatures = getFeatures(diffs, old, stagingDatabase(), defaultMetadataId, progressListener);
Iterator<Optional<Feature>> transformed = Iterators.transform(plainFeatures, ExportDiffOp.this.function);
Iterator<SimpleFeature> filtered = Iterators.filter(Iterators.transform(transformed, new Function<Optional<Feature>, SimpleFeature>() {
@Override
public SimpleFeature apply(Optional<Feature> input) {
return (SimpleFeature) (input.isPresent() ? input.get() : null);
}
}), Predicates.notNull());
return new DelegateFeatureIterator<SimpleFeature>(filtered);
}
};
// add the feature collection to the feature store
final Transaction transaction;
if (transactional) {
transaction = new DefaultTransaction("create");
} else {
transaction = Transaction.AUTO_COMMIT;
}
try {
targetStore.setTransaction(transaction);
try {
targetStore.addFeatures(asFeatureCollection);
transaction.commit();
} catch (final Exception e) {
if (transactional) {
transaction.rollback();
}
Throwables.propagateIfInstanceOf(e, GeoToolsOpException.class);
throw new GeoToolsOpException(e, StatusCode.UNABLE_TO_ADD);
} finally {
transaction.close();
}
} catch (IOException e) {
throw new GeoToolsOpException(e, StatusCode.UNABLE_TO_ADD);
}
progressListener.complete();
return targetStore;
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class ExportOp method getFeatures.
private static Iterator<SimpleFeature> getFeatures(final RevTree typeTree, final ObjectDatabase database, final ObjectId defaultMetadataId, final ProgressListener progressListener) {
Iterator<NodeRef> nodes = new DepthTreeIterator("", defaultMetadataId, typeTree, database, Strategy.FEATURES_ONLY);
// progress reporting
nodes = Iterators.transform(nodes, new Function<NodeRef, NodeRef>() {
private AtomicInteger count = new AtomicInteger();
@Override
public NodeRef apply(NodeRef input) {
progressListener.setProgress((count.incrementAndGet() * 100.f) / typeTree.size());
return input;
}
});
Function<NodeRef, SimpleFeature> asFeature = new Function<NodeRef, SimpleFeature>() {
private Map<ObjectId, FeatureBuilder> ftCache = Maps.newHashMap();
@Override
@Nullable
public SimpleFeature apply(final NodeRef input) {
final ObjectId metadataId = input.getMetadataId();
final RevFeature revFeature = database.getFeature(input.objectId());
FeatureBuilder featureBuilder = getBuilderFor(metadataId);
Feature feature = featureBuilder.build(input.name(), revFeature);
feature.getUserData().put(Hints.USE_PROVIDED_FID, true);
feature.getUserData().put(RevFeature.class, revFeature);
feature.getUserData().put(RevFeatureType.class, featureBuilder.getType());
if (feature instanceof SimpleFeature) {
return (SimpleFeature) feature;
}
return null;
}
private FeatureBuilder getBuilderFor(final ObjectId metadataId) {
FeatureBuilder featureBuilder = ftCache.get(metadataId);
if (featureBuilder == null) {
RevFeatureType revFtype = database.getFeatureType(metadataId);
featureBuilder = new FeatureBuilder(revFtype);
ftCache.put(metadataId, featureBuilder);
}
return featureBuilder;
}
};
Iterator<SimpleFeature> asFeatures = Iterators.transform(nodes, asFeature);
UnmodifiableIterator<SimpleFeature> filterNulls = Iterators.filter(asFeatures, Predicates.notNull());
return filterNulls;
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class RemoveWebOp method run.
/**
* Runs the command and builds the appropriate response.
*
* @param context - the context to use for this command
*
* @throws CommandSpecException
*/
@Override
public void run(CommandContext context) {
if (this.getTransactionId() == null) {
throw new CommandSpecException("No transaction was specified, remove requires a transaction to preserve the stability of the repository.");
}
if (this.path == null) {
throw new CommandSpecException("No path was specified for removal.");
}
final Context geogig = this.getCommandLocator(context);
RemoveOp command = geogig.command(RemoveOp.class);
NodeRef.checkValidPath(path);
Optional<NodeRef> node = geogig.command(FindTreeChild.class).setParent(geogig.workingTree().getTree()).setIndex(true).setChildPath(path).call();
if (node.isPresent()) {
NodeRef nodeRef = node.get();
if (nodeRef.getType() == TYPE.TREE) {
if (!recursive) {
throw new CommandSpecException("Recursive option must be used to remove a tree.");
}
}
}
command.addPathToRemove(path).call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeElement("Deleted", path);
out.finish();
}
});
}
use of org.locationtech.geogig.api.NodeRef in project GeoGig by boundlessgeo.
the class RevertFeatureWebOp method run.
/**
* Runs the command and builds the appropriate response
*
* @param context - the context to use for this command
*
* @throws CommandSpecException
*/
@Override
public void run(CommandContext context) {
if (this.getTransactionId() == null) {
throw new CommandSpecException("No transaction was specified, revert feature requires a transaction to preserve the stability of the repository.");
}
final Context geogig = this.getCommandLocator(context);
Optional<RevTree> newTree = Optional.absent();
Optional<RevTree> oldTree = Optional.absent();
// get tree from new commit
Optional<ObjectId> treeId = geogig.command(ResolveTreeish.class).setTreeish(newCommitId).call();
Preconditions.checkState(treeId.isPresent(), "New commit id did not resolve to a valid tree.");
newTree = geogig.command(RevObjectParse.class).setRefSpec(treeId.get().toString()).call(RevTree.class);
Preconditions.checkState(newTree.isPresent(), "Unable to read the new commit tree.");
// get tree from old commit
treeId = geogig.command(ResolveTreeish.class).setTreeish(oldCommitId).call();
Preconditions.checkState(treeId.isPresent(), "Old commit id did not resolve to a valid tree.");
oldTree = geogig.command(RevObjectParse.class).setRefSpec(treeId.get().toString()).call(RevTree.class);
Preconditions.checkState(newTree.isPresent(), "Unable to read the old commit tree.");
// get feature from old tree
Optional<NodeRef> node = geogig.command(FindTreeChild.class).setParent(oldTree.get()).setIndex(true).setChildPath(featurePath).call();
boolean delete = false;
if (!node.isPresent()) {
delete = true;
node = geogig.command(FindTreeChild.class).setParent(newTree.get()).setIndex(true).setChildPath(featurePath).call();
Preconditions.checkState(node.isPresent(), "The feature was not found in either commit tree.");
}
// get the new parent tree
ObjectId metadataId = ObjectId.NULL;
Optional<NodeRef> parentNode = geogig.command(FindTreeChild.class).setParent(newTree.get()).setChildPath(node.get().getParentPath()).setIndex(true).call();
RevTreeBuilder treeBuilder = null;
if (parentNode.isPresent()) {
metadataId = parentNode.get().getMetadataId();
Optional<RevTree> parsed = geogig.command(RevObjectParse.class).setObjectId(parentNode.get().getNode().getObjectId()).call(RevTree.class);
checkState(parsed.isPresent(), "Parent tree couldn't be found in the repository.");
treeBuilder = new RevTreeBuilder(geogig.stagingDatabase(), parsed.get());
treeBuilder.remove(node.get().getNode().getName());
} else {
treeBuilder = new RevTreeBuilder(geogig.stagingDatabase());
}
// put the old feature into the new tree
if (!delete) {
treeBuilder.put(node.get().getNode());
}
ObjectId newTreeId = geogig.command(WriteBack.class).setAncestor(newTree.get().builder(geogig.stagingDatabase())).setChildPath(node.get().getParentPath()).setToIndex(true).setTree(treeBuilder.build()).setMetadataId(metadataId).call();
// build new commit with parent of new commit and the newly built tree
CommitBuilder builder = new CommitBuilder();
builder.setParentIds(Lists.newArrayList(newCommitId));
builder.setTreeId(newTreeId);
builder.setAuthor(authorName.orNull());
builder.setAuthorEmail(authorEmail.orNull());
builder.setMessage(commitMessage.or("Reverted changes made to " + featurePath + " at " + newCommitId.toString()));
RevCommit mapped = builder.build();
context.getGeoGIG().getRepository().objectDatabase().put(mapped);
// merge commit into current branch
final Optional<Ref> currHead = geogig.command(RefParse.class).setName(Ref.HEAD).call();
if (!currHead.isPresent()) {
throw new CommandSpecException("Repository has no HEAD, can't merge.");
}
MergeOp merge = geogig.command(MergeOp.class);
merge.setAuthor(authorName.orNull(), authorEmail.orNull());
merge.addCommit(Suppliers.ofInstance(mapped.getId()));
merge.setMessage(mergeMessage.or("Merged revert of " + featurePath));
try {
final MergeReport report = merge.call();
context.setResponseContent(new CommandResponse() {
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
out.writeMergeResponse(Optional.fromNullable(report.getMergeCommit()), report.getReport().get(), geogig, report.getOurs(), report.getPairs().get(0).getTheirs(), report.getPairs().get(0).getAncestor());
out.finish();
}
});
} catch (Exception e) {
final RevCommit ours = context.getGeoGIG().getRepository().getCommit(currHead.get().getObjectId());
final RevCommit theirs = context.getGeoGIG().getRepository().getCommit(mapped.getId());
final Optional<ObjectId> ancestor = geogig.command(FindCommonAncestor.class).setLeft(ours).setRight(theirs).call();
context.setResponseContent(new CommandResponse() {
final MergeScenarioReport report = geogig.command(ReportMergeScenarioOp.class).setMergeIntoCommit(ours).setToMergeCommit(theirs).call();
@Override
public void write(ResponseWriter out) throws Exception {
out.start();
Optional<RevCommit> mergeCommit = Optional.absent();
out.writeMergeResponse(mergeCommit, report, geogig, ours.getId(), theirs.getId(), ancestor.get());
out.finish();
}
});
}
}
Aggregations