package com.aptana.rdt.internal.rake;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.IBaseLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.swt.graphics.Image;
import org.jruby.ast.RootNode;
import org.rubypeople.rdt.core.IImportContainer;
import org.rubypeople.rdt.core.ILocalVariable;
import org.rubypeople.rdt.core.IParent;
import org.rubypeople.rdt.core.IRubyElement;
import org.rubypeople.rdt.core.IRubyScript;
import org.rubypeople.rdt.core.RubyModelException;
import org.rubypeople.rdt.internal.core.RubyBlock;
import org.rubypeople.rdt.internal.ui.RubyPlugin;
import org.rubypeople.rdt.internal.ui.rubyeditor.ASTProvider;
import org.rubypeople.rdt.internal.ui.rubyeditor.RubyOutlinePage;
import org.rubypeople.rdt.internal.ui.viewsupport.RubyElementImageProvider;
import org.rubypeople.rdt.ui.RubyElementLabels;
import org.rubypeople.rdt.ui.rubyeditor.ICustomRubyOutlinePage;
import org.rubypeople.rdt.ui.viewsupport.ImageDescriptorRegistry;
import com.aptana.rdt.rake.RakePlugin;
public class RakeOutlinePage extends RubyOutlinePage implements ICustomRubyOutlinePage
{
protected ITreeContentProvider getContentProvider()
{
return new RakeChildrenProvider();
}
@Override
protected IBaseLabelProvider getLabelProvider()
{
return new LabelProvider()
{
public String getText(Object element)
{
if (element instanceof Task)
{
return ((Task) element).getName();
}
if (element instanceof Namespace)
{
return ((Namespace) element).toString();
}
if (element instanceof IRubyElement)
{
return RubyElementLabels.getTextLabel(element, 0);
}
return super.getText(element);
}
public Image getImage(Object element)
{
ImageDescriptorRegistry registry = RubyPlugin.getImageDescriptorRegistry();
ImageDescriptor descriptor = null;
if (element instanceof Task)
{
descriptor = RakePlugin.imageDescriptorFromPlugin(RakePlugin.PLUGIN_ID,
"icons/targetpublic_obj.gif");
}
else if (element instanceof Namespace)
{
descriptor = RakePlugin.imageDescriptorFromPlugin(RakePlugin.PLUGIN_ID, "icons/task_obj.gif");
}
else if (element instanceof IRubyElement)
{
descriptor = new RubyElementImageProvider().getRubyImageDescriptor((IRubyElement) element, 0);
}
if (descriptor != null)
{
return registry.get(descriptor);
}
return super.getImage(element);
}
};
}
class RakeChildrenProvider extends ChildrenProvider
{
public Object[] getElements(Object inputElement)
{
IRubyScript script = (IRubyScript) inputElement;
RootNode root = ASTProvider.getASTProvider()
.getAST(script, ASTProvider.WAIT_YES, new NullProgressMonitor());
RakeStructureCreator rakeCreator = new RakeStructureCreator();
rakeCreator.acceptNode(root);
try
{
Object[] tasks = rakeCreator.getTasks();
Object[] scriptChildren = filter(script.getChildren());
Object[] all = new Object[tasks.length + scriptChildren.length];
System.arraycopy(scriptChildren, 0, all, 0, scriptChildren.length);
System.arraycopy(tasks, 0, all, scriptChildren.length, tasks.length);
return all;
}
catch (RubyModelException e)
{
RakePlugin.log(e);
}
return rakeCreator.getTasks();
}
public boolean hasChildren(Object element)
{
if (element instanceof IRubyScript)
return true;
if (element instanceof Namespace)
return true;
if (element instanceof Task)
return false;
if (element instanceof IImportContainer)
return true;
return false;
}
public Object getParent(Object element)
{
if (element instanceof IRubyScript)
return null;
return null;
}
/**
* Remove local variables and blocks.
*
* @param original
* @return
*/
private Object[] filter(Object[] original)
{
List<Object> filtered = new ArrayList<Object>();
for (int i = 0; i < original.length; i++)
{
if ((original[i] instanceof ILocalVariable) || (original[i] instanceof RubyBlock))
{
continue;
}
filtered.add(original[i]);
}
return filtered.toArray(new Object[filtered.size()]);
}
public Object[] getChildren(Object parentElement)
{
if (parentElement instanceof Namespace)
{
return ((Namespace) parentElement).getChildren();
}
try
{
if (parentElement instanceof IParent)
return filter(((IParent) parentElement).getChildren());
}
catch (RubyModelException e)
{
RakePlugin.log(e);
}
return new Object[0];
}
}
public boolean isEnabled(IRubyElement inputElement)
{
if (inputElement == null)
return false;
IPath path = inputElement.getPath();
if (path == null)
return false;
String name = path.lastSegment();
return name.endsWith(".rake") || name.equals("Rakefile");
}
}