use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class ResolveTreeish method call.
/**
* @param resolved an {@link Optional} with an ObjectId to resolve
* @return an {@link Optional} of the {@link ObjectId} that was resolved, or
* {@link Optional#absent()} if it did not resolve.
*/
private Optional<ObjectId> call(Optional<ObjectId> resolved) {
if (!resolved.isPresent()) {
return Optional.absent();
}
ObjectId objectId = resolved.get();
if (objectId.isNull()) {
// might be an empty commit ref
return Optional.of(RevTree.EMPTY_TREE_ID);
}
final TYPE objectType = command(ResolveObjectType.class).setObjectId(objectId).call();
switch(objectType) {
case TREE:
// ok
break;
case COMMIT:
{
Optional<RevCommit> commit = command(RevObjectParse.class).setObjectId(objectId).call(RevCommit.class);
if (commit.isPresent()) {
objectId = commit.get().getTreeId();
} else {
objectId = null;
}
break;
}
case TAG:
{
Optional<RevTag> tag = command(RevObjectParse.class).setObjectId(objectId).call(RevTag.class);
if (tag.isPresent()) {
ObjectId commitId = tag.get().getCommitId();
return call(Optional.of(commitId));
}
}
default:
throw new IllegalArgumentException(String.format("Provided ref spec ('%s') doesn't resolve to a tree-ish object: %s", treeishRefSpec, String.valueOf(objectType)));
}
return Optional.fromNullable(objectId);
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class WriteBack method writeBack.
private ObjectId writeBack(RevTreeBuilder ancestor, final String ancestorPath, final RevTree childTree, final String childPath, final ObjectDatabase targetDatabase, final ObjectId metadataId) {
final ObjectId treeId = childTree.getId();
targetDatabase.put(childTree);
final boolean isDirectChild = NodeRef.isDirectChild(ancestorPath, childPath);
if (isDirectChild) {
Envelope treeBounds = null;
if (!metadataId.isNull()) {
// only include bounds for trees with a default feature type
treeBounds = SpatialOps.boundsOf(childTree);
}
String childName = childPath;
Node treeNode = Node.create(childName, treeId, metadataId, TYPE.TREE, treeBounds);
ancestor.put(treeNode);
RevTree newAncestor = ancestor.build();
targetDatabase.put(newAncestor);
return newAncestor.getId();
}
final String parentPath = NodeRef.parentPath(childPath);
Optional<NodeRef> parentRef = getTreeChild(ancestor, parentPath);
RevTreeBuilder parentBuilder;
ObjectId parentMetadataId = ObjectId.NULL;
if (parentRef.isPresent()) {
ObjectId parentId = parentRef.get().objectId();
parentMetadataId = parentRef.get().getMetadataId();
parentBuilder = getTree(parentId, targetDatabase).builder(targetDatabase);
} else {
parentBuilder = RevTree.EMPTY.builder(targetDatabase);
}
String childName = NodeRef.nodeFromPath(childPath);
Envelope treeBounds = null;
if (!metadataId.isNull()) {
// only include bounds for trees with a default feature type
treeBounds = SpatialOps.boundsOf(childTree);
}
Node treeNode = Node.create(childName, treeId, metadataId, TYPE.TREE, treeBounds);
parentBuilder.put(treeNode);
RevTree parent = parentBuilder.build();
return writeBack(ancestor, ancestorPath, parent, parentPath, targetDatabase, parentMetadataId);
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class WriteTree method _call.
/**
* Executes the write tree operation.
*
* @return the new root tree id, the current HEAD tree id if there are no differences between
* the index and the HEAD, or {@code null} if the operation has been cancelled (as
* indicated by the {@link #getProgressListener() progress listener}.
*/
@Override
protected ObjectId _call() {
final ProgressListener progress = getProgressListener();
final RevTree oldRootTree = resolveRootTree();
final ObjectDatabase repositoryDatabase = objectDatabase();
Iterator<DiffEntry> diffs = null;
long numChanges = 0;
if (diffSupplier == null) {
diffs = index().getStaged(pathFilters);
numChanges = index().countStaged(pathFilters).count();
} else {
diffs = diffSupplier.get();
}
if (!diffs.hasNext()) {
return oldRootTree.getId();
}
if (progress.isCanceled()) {
return null;
}
Map<String, RevTreeBuilder> repositoryChangedTrees = Maps.newHashMap();
Map<String, NodeRef> indexChangedTrees = Maps.newHashMap();
Map<String, ObjectId> changedTreesMetadataId = Maps.newHashMap();
Set<String> deletedTrees = Sets.newHashSet();
final boolean moveObjects = this.moveObjects;
NodeRef ref;
int i = 0;
RevTree stageHead = index().getTree();
while (diffs.hasNext()) {
if (numChanges != 0) {
progress.setProgress((float) (++i * 100) / numChanges);
}
if (progress.isCanceled()) {
return null;
}
DiffEntry diff = diffs.next();
// ignore the root entry
if (NodeRef.ROOT.equals(diff.newName()) || NodeRef.ROOT.equals(diff.oldName())) {
continue;
}
ref = diff.getNewObject();
if (ref == null) {
ref = diff.getOldObject();
}
final String parentPath = ref.getParentPath();
final boolean isDelete = ChangeType.REMOVED.equals(diff.changeType());
final TYPE type = ref.getType();
if (isDelete && deletedTrees.contains(parentPath)) {
// tree delete entry was processed
continue;
}
RevTreeBuilder parentTree = resolveTargetTree(oldRootTree, parentPath, repositoryChangedTrees, changedTreesMetadataId, ObjectId.NULL, repositoryDatabase);
if (type == TYPE.TREE && !isDelete) {
// cache the tree
resolveTargetTree(oldRootTree, ref.name(), repositoryChangedTrees, changedTreesMetadataId, ref.getMetadataId(), repositoryDatabase);
}
resolveSourceTreeRef(parentPath, indexChangedTrees, changedTreesMetadataId, stageHead);
Preconditions.checkState(parentTree != null);
if (isDelete) {
String oldName = diff.getOldObject().getNode().getName();
parentTree.remove(oldName);
if (TYPE.TREE.equals(type)) {
deletedTrees.add(ref.path());
}
} else {
if (moveObjects && ref.getType().equals(TYPE.TREE)) {
RevTree tree = stagingDatabase().getTree(ref.objectId());
if (!ref.getMetadataId().isNull()) {
repositoryDatabase.put(stagingDatabase().getFeatureType(ref.getMetadataId()));
}
if (tree.isEmpty()) {
repositoryDatabase.put(tree);
} else {
continue;
}
} else if (moveObjects) {
deepMove(ref.getNode());
}
parentTree.put(ref.getNode());
}
}
if (progress.isCanceled()) {
return null;
}
// now write back all changed trees
ObjectId newTargetRootId = oldRootTree.getId();
RevTreeBuilder directRootEntries = repositoryChangedTrees.remove(NodeRef.ROOT);
if (directRootEntries != null) {
RevTree newRoot = directRootEntries.build();
repositoryDatabase.put(newRoot);
newTargetRootId = newRoot.getId();
}
for (Map.Entry<String, RevTreeBuilder> e : repositoryChangedTrees.entrySet()) {
String treePath = e.getKey();
ObjectId metadataId = changedTreesMetadataId.get(treePath);
RevTreeBuilder treeBuilder = e.getValue();
RevTree newRoot = getTree(newTargetRootId);
RevTree tree = treeBuilder.build();
newTargetRootId = writeBack(newRoot.builder(repositoryDatabase), tree, treePath, metadataId);
}
progress.complete();
return newTargetRootId;
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class RevParse method resolveObject.
/**
* @param objectName a ref name or object id
*/
private Optional<ObjectId> resolveObject(final String refSpec) {
ObjectId resolvedTo = null;
// is it a ref?
Optional<Ref> ref = command(RefParse.class).setName(refSpec).call();
if (ref.isPresent()) {
resolvedTo = ref.get().getObjectId();
} else {
// does it look like an object id hash?
boolean hexPatternMatches = HEX_PATTERN.matcher(refSpec).matches();
if (hexPatternMatches) {
try {
ObjectId parsed = ObjectId.valueOf(refSpec);
if (parsed.isNull()) {
return Optional.of(ObjectId.NULL);
}
if (parsed.equals(RevTree.EMPTY_TREE_ID)) {
return Optional.of(RevTree.EMPTY_TREE_ID);
}
if (stagingDatabase().exists(parsed)) {
return Optional.of(parsed);
}
} catch (IllegalArgumentException ignore) {
// its a partial id
}
List<ObjectId> hashMatches = stagingDatabase().lookUp(refSpec);
if (hashMatches.size() > 1) {
throw new IllegalArgumentException(String.format("Ref spec (%s) matches more than one object id: %s", refSpec, hashMatches.toString()));
}
if (hashMatches.size() == 1) {
resolvedTo = hashMatches.get(0);
} else if (ObjectId.NULL.toString().startsWith(refSpec)) {
resolvedTo = ObjectId.NULL;
} else if (RevTree.EMPTY_TREE_ID.toString().startsWith(refSpec)) {
resolvedTo = RevTree.EMPTY.getId();
}
}
}
return Optional.fromNullable(resolvedTo);
}
use of org.locationtech.geogig.api.ObjectId in project GeoGig by boundlessgeo.
the class RevParse method resolveCommit.
/**
* @param objectId
* @return
*/
private RevCommit resolveCommit(ObjectId objectId) {
final Optional<RevObject> object = command(RevObjectParse.class).setObjectId(objectId).call();
checkArgument(object.isPresent(), "No object named %s could be found", objectId);
final RevObject revObject = object.get();
RevCommit commit;
switch(revObject.getType()) {
case COMMIT:
commit = (RevCommit) revObject;
break;
case TAG:
ObjectId commitId = ((RevTag) revObject).getCommitId();
commit = command(RevObjectParse.class).setObjectId(commitId).call(RevCommit.class).get();
break;
default:
throw new IllegalArgumentException(String.format("%s did not resolve to a commit or tag: %s", objectId, revObject.getType()));
}
return commit;
}
Aggregations