/***** BEGIN LICENSE BLOCK ***** * Version: CPL 1.0/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Common Public * License Version 1.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.eclipse.org/legal/cpl-v10.html * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * Copyright (C) 2006 Mirko Stocker <me@misto.ch> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the CPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the CPL, the GPL or the LGPL. ***** END LICENSE BLOCK *****/ package org.rubypeople.rdt.astviewer.views; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.Viewer; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IFileEditorInput; import org.eclipse.ui.IStorageEditorInput; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.PlatformUI; import org.jruby.ast.CommentNode; import org.jruby.ast.NewlineNode; import org.jruby.ast.Node; import org.jruby.common.NullWarnings; import org.jruby.parser.DefaultRubyParser; import org.jruby.parser.RubyParserPool; import org.rubypeople.rdt.astviewer.Activator; import org.rubypeople.rdt.internal.core.parser.RubyParser; import org.rubypeople.rdt.internal.core.util.Util; import org.rubypeople.rdt.internal.ui.rubyeditor.RubyEditor; class ViewContentProvider implements IStructuredContentProvider, ITreeContentProvider { private TreeParent invisibleRoot; private IViewSite viewSite; private RubyEditor editor; private DefaultRubyParser parser; private boolean showNewline; public ViewContentProvider(IViewSite viewSite) { this.viewSite = viewSite; parser = RubyParserPool.getInstance().borrowParser(); parser.setWarnings(new NullWarnings()); } public void inputChanged(@SuppressWarnings("unused") Viewer v, @SuppressWarnings("unused") Object oldInput, @SuppressWarnings("unused") Object newInput) { } public void dispose() { RubyParserPool.getInstance().returnParser(parser); } protected IFile getFile() { IEditorInput input = editor.getEditorInput(); if (input instanceof IFileEditorInput) { return ((IFileEditorInput) input).getFile(); } return null; } public Object[] getElements(Object parent) { if (parent.equals(viewSite)) { if (invisibleRoot == null) initialize(); return getChildren(invisibleRoot); } return getChildren(parent); } public Object getParent(Object child) { if (child instanceof TreeObject) { return ((TreeObject) child).getParent(); } return null; } public Object[] getChildren(Object parent) { if (parent instanceof TreeParent) { return ((TreeParent) parent).getChildren(); } return new Object[0]; } public boolean hasChildren(Object parent) { if (parent instanceof TreeParent) return ((TreeParent) parent).hasChildren(); return false; } public Node getRootNode() { try { return new RubyParser().parse(getName(), new String(Util.getInputStreamAsCharArray(getContents(), -1, null))) .getAST(); } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } private String getName() throws CoreException { IFile file = getFile(); if (file != null) return file.getName(); IEditorInput input = editor.getEditorInput(); if (input instanceof IStorageEditorInput) { IStorageEditorInput storageInput = (IStorageEditorInput) input; return storageInput.getStorage().getName(); } return ""; } private InputStream getContents() throws CoreException { IFile file = getFile(); if (file != null) return file.getContents(); IEditorInput input = editor.getEditorInput(); if (input instanceof IStorageEditorInput) { IStorageEditorInput storageInput = (IStorageEditorInput) input; return storageInput.getStorage().getContents(); } return null; } private void initialize() { updateContent(); } private void buildTree(TreeParent parent, Node n) { if (n == null || n.isInvisible()) return; if (!showNewline && n instanceof NewlineNode) n = ((NewlineNode) n).getNextNode(); List<Node> children = new ArrayList<Node>(n.childNodes()); children.addAll(n.getComments()); if ((n instanceof CommentNode) || (children.size() <= 0)) { parent.addChild(new TreeObject(n)); } else { TreeParent newParent = new TreeParent(n); parent.addChild(newParent); for (Node childNode : children) { if (childNode.isInvisible()) continue; buildTree(newParent, childNode); } } } private IWorkbenchPage getActiveWorkbenchPage() { return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); } private boolean editorChanged() { if (getActiveWorkbenchPage() == null || !(getActiveWorkbenchPage().getActiveEditor() instanceof RubyEditor)) return false; return getEditor() != (RubyEditor) getActiveWorkbenchPage().getActiveEditor(); } public boolean forceUpdateContent() { if (getActiveWorkbenchPage() == null) return false; setEditor((RubyEditor) getActiveWorkbenchPage().getActiveEditor()); invisibleRoot = new TreeParent(null); showNewline = Activator.getDefault().getPreferenceStore().getBoolean("showNewline"); buildTree(invisibleRoot, getRootNode()); return true; } public boolean updateContent() { if (editorChanged()) return forceUpdateContent(); else return false; } private void setEditor(RubyEditor editor) { this.editor = editor; } private RubyEditor getEditor() { return editor; } }