Package org.eclipse.egit.ui.internal.synchronize.model

Source Code of org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder$FileModelFactory

/*******************************************************************************
* Copyright (C) 2013 Robin Stocker <robin@nibor.org>
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.egit.ui.internal.synchronize.model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
import org.eclipse.jgit.lib.Repository;

/**
* For building trees of directory and file nodes out of a flat list of changes.
*/
class TreeBuilder {

  /**
   * This interface enables creating the right instances of
   * {@link GitModelBlob} for files.
   */
  interface FileModelFactory {
    /**
     * Creates proper instance of {@link GitModelBlob} for file nodes
     *
     * @param parent
     *            parent object
     * @param repo
     *            repository associated with file that will be created
     * @param change
     *            change associated with file that will be created
     * @param fullPath
     *            absolute path
     * @return instance of {@link GitModelBlob}
     */
    GitModelBlob createFileModel(GitModelObjectContainer parent,
        Repository repo, Change change, IPath fullPath);

    /**
     * Distinguish working tree from changed/staged tree
     *
     * @return {@code true} when this tree is working tree, {@code false}
     *         when it is a cached tree
     */
    boolean isWorkingTree();
  }

  /**
   * Interface for creating the desired instances of {@link GitModelTree}.
   */
  interface TreeModelFactory {
    GitModelTree createTreeModel(GitModelObjectContainer parent,
        IPath fullPath, int kind);
  }

  /**
   *
   * @param root
   *            the root node of the tree to build, which will become the
   *            parent of the first level of children
   * @param repo
   * @param changes
   * @param fileFactory
   * @param treeFactory
   * @return the children of the root nodes
   */
  public static GitModelObject[] build(final GitModelObjectContainer root,
      final Repository repo, final Map<String, Change> changes,
      final FileModelFactory fileFactory,
      final TreeModelFactory treeFactory) {

    if (changes == null || changes.isEmpty())
      return new GitModelObject[] {};

    final IPath rootPath = new Path(repo.getWorkTree()
        .getAbsolutePath());
    final List<GitModelObject> rootChildren = new ArrayList<GitModelObject>();

    final Map<IPath, Node> nodes = new HashMap<IPath, Node>();

    for (Map.Entry<String, Change> entry : changes.entrySet()) {
      String repoRelativePath = entry.getKey();
      Change change = entry.getValue();

      GitModelObjectContainer parent = root;
      List<GitModelObject> children = rootChildren;
      IPath path = rootPath;

      String[] segments = repoRelativePath.split("/"); //$NON-NLS-1$

      for (int i = 0; i < segments.length; i++) {
        path = path.append(segments[i]);

        // Changes represent files, so the last segment is the file name
        boolean fileNode = (i == segments.length - 1);
        if (!fileNode) {
          Node node = nodes.get(path);
          if (node == null) {
            GitModelTree tree = treeFactory.createTreeModel(parent,
                path, change.getKind());
            node = new Node(tree);
            nodes.put(path, node);
            children.add(tree);
          }
          parent = node.tree;
          children = node.children;
        } else {
          GitModelBlob file = fileFactory.createFileModel(parent,
              repo, change, path);
          children.add(file);
        }
      }
    }

    for (Node object : nodes.values()) {
      GitModelTree tree = object.tree;
      tree.setChildren(object.children);
    }

    return rootChildren.toArray(new GitModelObject[rootChildren.size()]);
  }

  private static class Node {
    private final GitModelTree tree;

    private final List<GitModelObject> children = new ArrayList<GitModelObject>();

    public Node(GitModelTree tree) {
      this.tree = tree;
    }
  }
}
TOP

Related Classes of org.eclipse.egit.ui.internal.synchronize.model.TreeBuilder$FileModelFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.