blob: 5ad6544688d64fe027684627beaccebec14df446 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 1C-Soft LLC.
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Vladimir Piskarev (1C) - initial API and implementation
*******************************************************************************/
package org.eclipse.handly.ui.viewer;
import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT;
import java.util.Collection;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.handly.internal.ui.Activator;
import org.eclipse.handly.model.Elements;
import org.eclipse.handly.model.IElement;
import org.eclipse.handly.model.ISourceFile;
import org.eclipse.handly.util.ICollector;
import org.eclipse.jface.viewers.AbstractTreeViewer;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.progress.IElementCollector;
/**
* A deferred content provider for {@link IElement}s.
* Uses the existing structure of the elements.
*
* @since 1.5
*/
public class DeferredElementTreeContentProvider
extends DeferredTreeContentProvider
{
/**
* A zero-length array of the runtime type <code>Object[]</code>.
*/
protected static final Object[] NO_CHILDREN = new Object[0];
/**
* Creates a new instance of the content provider.
*
* @param viewer the tree viewer that will use this content provider
* (not <code>null</code>)
* @param site the site of the containing workbench part
* (may be <code>null</code>)
*/
public DeferredElementTreeContentProvider(AbstractTreeViewer viewer,
IWorkbenchPartSite site)
{
super(viewer, site);
}
@Override
public Object[] getElements(Object inputElement)
{
return getChildren(inputElement);
}
@Override
public Object[] getChildren(Object parentElement)
{
if (shouldDefer(parentElement))
return getDeferredTreeContentManager().getChildren(parentElement);
return getImmediateChildren(parentElement);
}
@Override
public Object getParent(Object element)
{
if (element instanceof IElement)
return Elements.getParent((IElement)element);
return null;
}
@Override
public boolean hasChildren(Object element)
{
if (shouldDefer(element))
return getDeferredTreeContentManager().mayHaveChildren(element);
return getImmediateChildren(element).length > 0;
}
/**
* Returns whether the given element should be processed
* via deferred tree content manager.
*
* @param element an element
* @return <code>true</code> if the given element should be processed
* via deferred tree content manager, and <code>false</code> otherwise
*/
protected boolean shouldDefer(Object element)
{
return element instanceof ISourceFile && !Elements.isWorkingCopy(
(ISourceFile)element);
}
/**
* Returns the child elements of the given parent element.
* <p>
* Default implementation invokes <code>Elements.getChildren((IElement)parentElement)</code>
* if the parent element is an IElement. Subclasses may override or extend.
* </p>
*
* @param parentElement the parent element
* @return an array of child elements (not <code>null</code>)
*/
protected Object[] getImmediateChildren(Object parentElement)
{
if (parentElement instanceof IElement)
{
try
{
return Elements.getChildren((IElement)parentElement);
}
catch (CoreException e)
{
Activator.logError(e);
}
}
return NO_CHILDREN;
}
@Override
protected void fetchDeferredChildren(Object parentElement,
IElementCollector collector, IProgressMonitor monitor)
{
try
{
if (parentElement instanceof IElement)
{
try
{
Elements.fetchChildren((IElement)parentElement,
EMPTY_CONTEXT, new ICollector<Object>()
{
@Override
public void add(Object e)
{
collector.add(e, null);
}
@Override
public void addAll(Collection<? extends Object> c)
{
collector.add(c.toArray(), null);
}
}, monitor);
}
catch (CoreException e)
{
Activator.logError(e);
}
}
}
finally
{
collector.done();
}
}
/**
* Returns the rule used to schedule the deferred fetching of children
* for the given parent element.
* <p>
* {@link DeferredElementTreeContentProvider}'s implementation
* of this method always returns <code>null</code>.
* </p>
*/
@Override
protected ISchedulingRule getRule(Object parentElement)
{
return null;
}
}