// Copyright 2012 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.collide.shared.util; import com.google.collide.dto.WorkspaceInfo; import com.google.collide.json.shared.JsonArray; import com.google.collide.json.shared.JsonStringMap; import java.util.Comparator; /** * Utilities for managing workspaces. */ public class WorkspaceUtils { /** * A node in a hierarchical tree of workspaces. */ public static class WorkspaceNode { private final WorkspaceInfo workspace; private final JsonArray<WorkspaceNode> children; public WorkspaceNode(WorkspaceInfo workspace) { this.workspace = workspace; this.children = JsonCollections.createArray(); } public void addChild(WorkspaceNode child) { children.add(child); } public WorkspaceNode getChild(int index) { return children.get(index); } public int getChildCount() { return children.size(); } /** * Sort the direct children of this node. */ public void sortChildren(Comparator<? super WorkspaceNode> comparator) { sortChildren(comparator, false); } /** * Sort the children of this node and optionally sort the entire branch * recursively. */ public void sortChildren(Comparator<? super WorkspaceNode> comparator, boolean recursive) { // Sort the direct children. children.sort(comparator); // Recursively sort the branch children. if (recursive) { for (int i = 0; i < getChildCount(); i++) { getChild(i).sortChildren(comparator, true); } } } public WorkspaceInfo getWorkspace() { return workspace; } } /** * Take a flat list of workspaces and organize them into a hierarchy (or set * or hierarchies) based on workspace parent IDs. The children within each * node are not sorted. This method is O(n). * * @param workspaces the list of workspaces to organize * @return a array of root workspace nodes */ public static JsonArray<WorkspaceNode> getWorkspaceHierarchy( JsonArray<WorkspaceInfo> workspaces) { /* * Assume all workspaces are root nodes. Create a map of workspace IDs to * their associated tree nodes. */ final JsonStringMap<WorkspaceNode> idToNode = JsonCollections.createMap(); final JsonArray<WorkspaceNode> rootNodes = JsonCollections.createArray(); for (int i = 0; i < workspaces.size(); i++) { WorkspaceInfo value = workspaces.get(i); WorkspaceNode node = new WorkspaceNode(value); rootNodes.add(node); idToNode.put(value.getId(), node); } /* * Iterate over the list of workspaces and add each workspace as a child of * its parent. */ int count = rootNodes.size(); for (int i = 0; i < count; i++) { WorkspaceNode node = rootNodes.get(i); WorkspaceInfo workspace = node.getWorkspace(); WorkspaceNode parentNode = idToNode.get(workspace.getParentId()); if (parentNode != null) { parentNode.addChild(node); // This node has a parent, so it is not a root node. rootNodes.remove(i); i--; count--; } } return rootNodes; } /** * Take a flat list of workspaces and organize them into a hierarchy (or set * or hierarchies) based on workspace parent IDs, then sort children within * each node using the specified comparator. * * @param workspaces the list of workspaces to organize * @return a array of root workspace nodes */ public static JsonArray<WorkspaceNode> getWorkspaceHierarchy( JsonArray<WorkspaceInfo> workspaces, final Comparator<WorkspaceInfo> comparator) { JsonArray<WorkspaceNode> rootNodes = getWorkspaceHierarchy(workspaces); // Wrap the WorkspaceInfo comparator in a WorkspaceNode comparator. Comparator<WorkspaceNode> nodeComparator = new Comparator<WorkspaceUtils.WorkspaceNode>() { @Override public int compare(WorkspaceNode o1, WorkspaceNode o2) { return comparator.compare(o1.getWorkspace(), o2.getWorkspace()); } }; // Sort each root node. for (int i = 0; i < rootNodes.size(); i++) { rootNodes.get(i).sortChildren(nodeComparator, true); } // Sort the list of root nodes. rootNodes.sort(nodeComparator); return rootNodes; } /** * Returns the name of the trunk workspace given the name of the project. */ public static String createTrunkWorkspaceName(String projectName) { return projectName + " source"; } }