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

Source Code of org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob

/*******************************************************************************
* Copyright (C) 2010, Dariusz Luksza <dariusz@luksza.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 static org.eclipse.compare.structuremergeviewer.Differencer.RIGHT;
import static org.eclipse.egit.ui.internal.synchronize.compare.GitCompareInput.getFileRevisionLabel;
import static org.eclipse.jgit.lib.ObjectId.zeroId;

import java.io.IOException;

import org.eclipse.compare.CompareConfiguration;
import org.eclipse.compare.IResourceProvider;
import org.eclipse.compare.ITypedElement;
import org.eclipse.compare.structuremergeviewer.ICompareInput;
import org.eclipse.compare.structuremergeviewer.ICompareInputChangeListener;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.egit.core.Activator;
import org.eclipse.egit.core.synchronize.GitCommitsModelCache.Change;
import org.eclipse.egit.ui.internal.synchronize.compare.ComparisonDataSource;
import org.eclipse.egit.ui.internal.synchronize.compare.GitCompareInput;
import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.swt.graphics.Image;
import org.eclipse.team.ui.mapping.ISynchronizationCompareInput;
import org.eclipse.team.ui.mapping.SaveableComparison;

/**
* Git blob object representation in Git ChangeSet
*/
public class GitModelBlob extends GitModelObject implements
    ISynchronizationCompareInput, IResourceProvider {

  private static final GitModelObject[] empty = new GitModelObject[0];

  private final Change change;

  private ITypedElement ancestorElement;

  private ITypedElement leftElement;

  private ITypedElement rightElement;

  /**
   * Absolute path to changed object
   */
  protected final IPath path;

  /**
   * {@link Repository} associated with this object
   */
  protected final Repository repo;

  /**
   * @param parent
   *            parent object
   * @param repo
   *            repository associated with this object
   * @param change
   *            change associated with this object
   * @param path
   *            absolute path of change
   */
  public GitModelBlob(GitModelObjectContainer parent, Repository repo,
      Change change, IPath path) {
    super(parent);
    this.repo = repo;
    this.path = path;
    this.change = change;
  }

  @Override
  public GitModelObject[] getChildren() {
    return empty;
  }

  @Override
  public String getName() {
    return path.lastSegment();
  }

  @Override
  public IPath getLocation() {
    return path;
  }

  @Override
  public boolean isContainer() {
    return false;
  }

  @Override
  public int getKind() {
    return change.getKind();
  }

  /**
   * @return abbreviated object id of base commit
   */
  public AbbreviatedObjectId getBaseCommitId() {
    return change.getCommitId();
  }

  /**
   * @return abbreviated object id of remote commit
   */
  public AbbreviatedObjectId getRemoteCommitId() {
    return change.getRemoteCommitId();
  }

  @Override
  public int repositoryHashCode() {
    return repo.getWorkTree().hashCode();
  }

  @Override
  public void dispose() {
    // there is nothing to dispose
  }

  @Override
  public String toString() {
    return "ModelBlob[objectId=" + change.getObjectId() + ", location=" + getLocation() + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
  }

  public Image getImage() {
    // not used
    return null;
  }

  public ITypedElement getAncestor() {
    prepareTypedElements();
    return ancestorElement;
  }

  public ITypedElement getLeft() {
    prepareTypedElements();
    return leftElement;
  }

  public ITypedElement getRight() {
    prepareTypedElements();
    return rightElement;
  }

  public void addCompareInputChangeListener(
      ICompareInputChangeListener listener) {
    // data in commit will never change, therefore change listeners are
    // useless
  }

  public void removeCompareInputChangeListener(
      ICompareInputChangeListener listener) {
    // data in commit will never change, therefore change listeners are
    // useless
  }

  public void copy(boolean leftToRight) {
    // do nothing, we should disallow coping content between commits
  }

  public SaveableComparison getSaveable() {
    // unused
    return null;
  }

  public void prepareInput(CompareConfiguration configuration,
      IProgressMonitor monitor) throws CoreException {
    configuration.setLeftLabel(getFileRevisionLabel(getLeft()));
    configuration.setRightLabel(getFileRevisionLabel(getRight()));
  }

  public String getFullPath() {
    return path.toOSString();
  }

  public boolean isCompareInputFor(Object object) {
    // not used
    return false;
  }

  @Override
  public int hashCode() {
    int baseHash = 1;
    if (change != null)
      baseHash = change.getObjectId() != null ? change.getObjectId()
        .hashCode() : 31;
    int remoteHash = 11;
    if (change != null)
      remoteHash = change.getRemoteObjectId() != null ? change
        .getRemoteObjectId().hashCode() : 41;

    return baseHash ^ remoteHash ^ path.hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    GitModelBlob other = (GitModelBlob) obj;
    if (change == null) {
      if (other.change != null)
        return false;
    } else if (!change.equals(other.change))
      return false;
    if (path == null) {
      if (other.path != null)
        return false;
    } else if (!path.equals(other.path))
      return false;

    return true;
  }

  private void prepareTypedElements() {
    if (ancestorElement != null) // other elements should also not be null
      return;

    ComparisonDataSource baseData;
    ComparisonDataSource remoteData;

    RevWalk rw = new RevWalk(repo);
    rw.setRetainBody(true);
    RevCommit baseCommit = null;
    RevCommit remoteCommit = null;
    try {
      if (change.getCommitId() != null)
        baseCommit = rw.parseCommit(change.getCommitId().toObjectId());
      if (change.getRemoteCommitId() != null)
        remoteCommit = rw.parseCommit(change.getRemoteCommitId()
            .toObjectId());
    } catch (IOException e) {
      Activator.logError(e.getMessage(), e);
    } finally {
      rw.dispose();
    }
    if (baseCommit == null && remoteCommit != null)
      baseCommit = remoteCommit; // prevent from NPE for deleted files

    ObjectId localId = extractObjectId(change.getObjectId());
    ObjectId remoteId = extractObjectId(change.getRemoteObjectId());

    if ((getKind() & RIGHT) == RIGHT) {
      baseData = new ComparisonDataSource(baseCommit, localId);
      remoteData = new ComparisonDataSource(remoteCommit, remoteId);
    } else /* getKind() == LEFT */{
      baseData = new ComparisonDataSource(remoteCommit, remoteId);
      remoteData = new ComparisonDataSource(baseCommit, localId);
    }

    GitCompareInput compareInput = getCompareInput(baseData, remoteData, remoteData);

    ancestorElement = compareInput.getAncestor();
    leftElement = compareInput.getLeft();
    rightElement = compareInput.getRight();
  }

  public IResource getResource() {
    IFile file = ResourcesPlugin.getWorkspace().getRoot()
        .getFileForLocation(path);

    return file;
  }

  /**
   * Returns specific instance of {@link GitCompareInput} for particular
   * compare input.
   *
   * @param baseData
   * @param remoteData
   * @param ancestorData
   * @return Git specific {@link ICompareInput}
   */
  protected GitCompareInput getCompareInput(ComparisonDataSource baseData,
      ComparisonDataSource remoteData, ComparisonDataSource ancestorData) {
    String gitPath = Repository.stripWorkDir(repo.getWorkTree(), path.toFile());

    return new GitCompareInput(repo, ancestorData, baseData, remoteData,
        gitPath);
  }

  private ObjectId extractObjectId(AbbreviatedObjectId objectId) {
    if (objectId != null)
      return objectId.toObjectId();
    else
      return zeroId();
  }

}
TOP

Related Classes of org.eclipse.egit.ui.internal.synchronize.model.GitModelBlob

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.