/*******************************************************************************
* Copyright (c) 2011, 2017 Chris Aniszczyk <caniszczyk@gmail.com> and others.
* 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
*
* Contributors:
* Chris Aniszczyk <caniszczyk@gmail.com> - initial implementation
* EclipseSource - Filtered Viewer
* Thomas Wolf <thomas.wolf@paranor.ch> - deferred loading
*******************************************************************************/
package org.eclipse.egit.ui.internal.reflog;
import java.util.Collection;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.egit.ui.Activator;
import org.eclipse.egit.ui.internal.UIText;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.ReflogEntry;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.ui.model.WorkbenchAdapter;
import org.eclipse.ui.progress.DeferredTreeContentManager;
import org.eclipse.ui.progress.IDeferredWorkbenchAdapter;
import org.eclipse.ui.progress.IElementCollector;
/**
* A content provider for reflog entries given a repository and a ref.
*/
public class ReflogViewContentProvider implements ITreeContentProvider {
private DeferredTreeContentManager loader;
private Object currentInput;
/**
* Input class for this content provider
*/
public static class ReflogInput extends WorkbenchAdapter
implements IDeferredWorkbenchAdapter {
private final Repository repository;
private final String ref;
private Collection<ReflogEntry> refLog;
/**
* Create input with non-null repository and non-null ref
*
* @param repository
* @param ref
*/
public ReflogInput(Repository repository, String ref) {
Assert.isNotNull(repository, "Repository cannot be null"); //$NON-NLS-1$
Assert.isNotNull(ref, "Ref cannot be null"); //$NON-NLS-1$
this.repository = repository;
this.ref = ref;
}
/**
* Get repository
*
* @return repository
*/
public Repository getRepository() {
return repository;
}
@Override
public Object[] getChildren(Object o) {
if (refLog != null) {
return refLog.toArray();
}
return super.getChildren(o);
}
@Override
public void fetchDeferredChildren(Object object,
IElementCollector collector, IProgressMonitor monitor) {
try (Git git = new Git(repository)) {
refLog = git.reflog().setRef(ref).call();
collector.add(refLog.toArray(), monitor);
} catch (Exception e) {
Activator.logError("Error running reflog command", e); //$NON-NLS-1$
collector.add(new ErrorElement(), monitor);
}
}
@Override
public boolean isContainer() {
return true;
}
@Override
public ISchedulingRule getRule(Object object) {
return null;
}
}
private static class ErrorElement extends WorkbenchAdapter {
@Override
public String getLabel(Object object) {
return UIText.ReflogView_ErrorOnLoad;
}
}
@Override
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
@Override
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
if (oldInput != null && loader != null) {
loader.cancel(oldInput);
}
currentInput = newInput;
if (viewer instanceof AbstractTreeViewer && newInput != null) {
loader = new DeferredTreeContentManager(
(AbstractTreeViewer) viewer);
}
}
@Override
public void dispose() {
if (currentInput != null && loader != null) {
loader.cancel(currentInput);
}
currentInput = null;
loader = null;
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof ReflogInput && loader != null) {
return loader.getChildren(parentElement);
}
return new Object[0];
}
@Override
public Object getParent(Object element) {
return null;
}
@Override
public boolean hasChildren(Object element) {
return false;
}
}