/*******************************************************************************
* Copyright (C) 2006, Robin Rosenberg <robin.rosenberg@dewire.com>
* Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org>
* Copyright (C) 2010, Mathias Kinzler <mathias.kinzler@sap.com>
* Copyright (C) 2015, Thomas Wolf <thomas.wolf@paranor.ch>
*
* 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.history;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.osgi.util.NLS;
/**
* Input for the {@link GitHistoryPage}
**/
public class HistoryPageInput {
private final List<IResource> list;
private final List<File> files;
private final Repository repo;
private final Object singleFile;
private final Object singleItem;
/**
* @param repository
* the {@link Repository}
* @param resourceItems
* the resources
*/
public HistoryPageInput(final Repository repository,
final IResource[] resourceItems) {
this.repo = repository;
list = Arrays.asList(resourceItems);
if (resourceItems.length == 1) {
singleItem = resourceItems[0];
if (resourceItems[0].getType() == IResource.FILE)
singleFile = resourceItems[0];
else
singleFile = null;
} else {
singleItem = null;
singleFile = null;
}
files = null;
}
/**
* @param repository
* the {@link Repository}
* @param fileItems
* the files
*/
public HistoryPageInput(final Repository repository, final File[] fileItems) {
this.repo = repository;
list = null;
if (fileItems.length == 1 && fileItems[0].isFile()
&& !inGitDir(repository, fileItems[0])) {
singleItem = fileItems[0];
singleFile = fileItems[0];
files = Arrays.asList(fileItems);
} else {
singleItem = null;
singleFile = null;
files = filterFilesInGitDir(repository, fileItems);
}
}
/**
* @param repository
* the {@link Repository}
*/
public HistoryPageInput(final Repository repository) {
this.repo = repository;
list = null;
singleFile = null;
singleItem = null;
files = null;
}
/**
* @return the {@link Repository} provided to the constructor
*/
public Repository getRepository() {
return repo;
}
/**
* @return the list provided to our constructor
*/
public IResource[] getItems() {
return list == null ? null : list.toArray(new IResource[list.size()]);
}
/**
* @return the list provided to our constructor
*/
public File[] getFileList() {
return files == null ? null : files.toArray(new File[files.size()]);
}
/**
* @return the single File, either a {@link IResource} or {@link File}, or
* <code>null</code>
*/
public Object getSingleFile() {
return singleFile;
}
/**
* @return the single Item, either a {@link IResource} or {@link File}, or
* <code>null</code>
*/
public Object getSingleItem() {
return singleItem;
}
/**
* @return <code>true</code> if this represents a single file (either as
* {@link IResource} or as {@link File})
*/
public boolean isSingleFile() {
return singleFile != null;
}
/**
* @return the HEAD Ref
*/
public Ref getHead() {
try {
Ref h = repo.exactRef(Constants.HEAD);
if (h != null && h.isSymbolic())
return h;
return null;
} catch (IOException e) {
throw new IllegalStateException(NLS.bind(
UIText.GitHistoryPage_errorParsingHead, Activator
.getDefault().getRepositoryUtil()
.getRepositoryName(repo)), e);
}
}
/**
* Tests whether a file is in a repository's .git directory (or is that
* directory itself).
*
* @param repository
* to test against
* @param file
* to test
* @return {@code true} if the file is in the .git directory of the
* repository, or is that directory itself.
*/
private boolean inGitDir(Repository repository, File file) {
return file.getAbsoluteFile().toPath().startsWith(
repository.getDirectory().getAbsoluteFile().toPath());
}
/**
* Filters all files that are inside a repository's .git directory from the
* given files.
*
* @param repository
* to test against
* @param fileItems
* to test
* @return a list of all files from {@code files} that are <em>not</em> in
* the .git directory of the repository, or {@code null} if there
* are none.
*/
private List<File> filterFilesInGitDir(Repository repository,
File[] fileItems) {
List<File> result = new ArrayList<>(fileItems.length);
Path gitDirPath = repository.getDirectory().getAbsoluteFile().toPath();
for (File f : fileItems) {
if (!f.getAbsoluteFile().toPath().startsWith(gitDirPath)) {
result.add(f);
}
}
if (result.isEmpty()) {
return null;
}
return result;
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof HistoryPageInput)) {
return false;
}
HistoryPageInput other = (HistoryPageInput) obj;
return repo == other.repo && singleFile == other.singleFile
&& singleItem == other.singleItem
&& listEquals(files, other.files)
&& listEquals(list, other.list);
}
private <T> boolean listEquals(List<? extends T> a, List<? extends T> b) {
if (a == b) {
return true;
}
if (a == null || b == null) {
return false;
}
return Arrays.equals(a.toArray(), b.toArray());
}
@Override
public int hashCode() {
return (repo == null ? 0 : repo.hashCode())
^ (singleFile == null ? 0 : singleFile.hashCode())
^ (singleItem == null ? 0 : singleItem.hashCode())
^ (files == null ? 0 : Arrays.hashCode(files.toArray()))
^ (list == null ? 0 : Arrays.hashCode(list.toArray()));
}
}