/* Copyright (c) 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: * Gabriel Roldan (Boundless) - initial implementation */ package org.locationtech.geogig.api.plumbing.diff; import java.util.Stack; import javax.annotation.Nullable; import org.locationtech.geogig.api.Node; import org.locationtech.geogig.api.NodeRef; import org.locationtech.geogig.api.ObjectId; import com.google.common.base.Objects; import com.google.common.base.Optional; import com.google.common.base.Preconditions; public final class DiffPathTracker { private String currentPath; private Stack<Node> leftTrees = new Stack<>(), rightTrees = new Stack<>(); public String getCurrentPath() { return currentPath; } public boolean isEmpty() { return leftTrees.isEmpty(); } public Optional<Node> currentLeftTree() { return Optional.fromNullable(leftTrees.peek()); } public Optional<Node> currentRightTree() { return Optional.fromNullable(rightTrees.peek()); } public Optional<ObjectId> currentLeftMetadataId() { return metadataId(leftTrees.peek()); } public Optional<ObjectId> currentRightMetadataId() { return metadataId(rightTrees.peek()); } private Optional<ObjectId> metadataId(@Nullable Node treeNode) { if (treeNode == null) { return Optional.absent(); } return treeNode.getMetadataId(); } public String tree(@Nullable Node left, @Nullable Node right) { Preconditions.checkArgument(left != null || right != null); this.leftTrees.add(left); this.rightTrees.add(right); String name = name(left, right); if (currentPath == null) { currentPath = name; } else { currentPath = NodeRef.appendChild(currentPath, name); } return currentPath; } /** * @return the resulting parent path after removing left and right from the stack, or * {@code null} if left and/or right are a root tree. */ public String endTree(@Nullable Node left, @Nullable Node right) { final Node popLeft = this.leftTrees.pop(); final Node popRight = this.rightTrees.pop(); try { Preconditions.checkState(Objects.equal(popLeft, left)); Preconditions.checkState(Objects.equal(popRight, right)); } catch (IllegalStateException e) { throw e; } if (NodeRef.ROOT.equals(currentPath)) { currentPath = null; } else { String fullPath = currentPath; currentPath = NodeRef.parentPath(fullPath); } return currentPath; } public String name(Node left, Node right) { return left == null ? right.getName() : left.getName(); } }