/** * Copyright 2010 JBoss Inc * * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.drools.eclipse.view.rules; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.drools.eclipse.DRLInfo; import org.drools.eclipse.DroolsEclipsePlugin; import org.drools.eclipse.ProcessInfo; import org.drools.eclipse.core.DroolsElement; import org.drools.eclipse.core.DroolsModelBuilder; import org.drools.eclipse.core.Function; import org.drools.eclipse.core.Global; import org.drools.eclipse.core.Package; import org.drools.eclipse.core.Process; import org.drools.eclipse.core.Query; import org.drools.eclipse.core.Rule; import org.drools.eclipse.core.RuleSet; import org.drools.eclipse.core.Template; import org.drools.eclipse.core.ui.DroolsContentProvider; import org.drools.eclipse.core.ui.DroolsLabelProvider; import org.drools.eclipse.core.ui.DroolsTreeSorter; import org.drools.eclipse.core.ui.FilterActionGroup; import org.drools.lang.descr.FactTemplateDescr; import org.drools.lang.descr.FunctionDescr; import org.drools.lang.descr.GlobalDescr; import org.drools.lang.descr.QueryDescr; import org.drools.lang.descr.RuleDescr; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceChangeEvent; import org.eclipse.core.resources.IResourceChangeListener; import org.eclipse.core.resources.IResourceDelta; import org.eclipse.core.resources.IResourceDeltaVisitor; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IMemento; import org.eclipse.ui.IViewSite; import org.eclipse.ui.PartInitException; import org.eclipse.ui.forms.editor.FormEditor; import org.eclipse.ui.ide.IDE; import org.eclipse.ui.part.ViewPart; import org.eclipse.ui.texteditor.ITextEditor; public class RulesView extends ViewPart implements IDoubleClickListener, IResourceVisitor, IResourceChangeListener { private final RuleSet ruleSet = DroolsModelBuilder.createRuleSet(); private Map resourcesMap = new HashMap(); private TreeViewer treeViewer; public void createPartControl(Composite parent) { treeViewer = new TreeViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); treeViewer.setContentProvider(new DroolsContentProvider()); treeViewer.setLabelProvider(new DroolsLabelProvider()); treeViewer.setSorter(new DroolsTreeSorter()); treeViewer.addDoubleClickListener(this); treeViewer.setUseHashlookup(true); treeViewer.setInput(ruleSet); FilterActionGroup filterActionGroup = new FilterActionGroup( treeViewer, "org.drools.eclipse.view.rules.RulesView"); filterActionGroup.fillActionBars(getViewSite().getActionBars()); } public void init(IViewSite site, IMemento memento) throws PartInitException { super.init(site, memento); try { ResourcesPlugin.getWorkspace().getRoot().accept(this); } catch (CoreException e) { DroolsEclipsePlugin.log(e); } ResourcesPlugin.getWorkspace().addResourceChangeListener(this); } public void dispose() { ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); } public void setFocus() { treeViewer.getControl().setFocus(); } public boolean visit(IResource resource) throws CoreException { return updateResource(resource); } private boolean updateResource(IResource resource) { IProject project = resource.getProject(); if (project != null) { IJavaProject javaProject = JavaCore.create(project); if (!javaProject.exists()) { return false; } if (resource instanceof IFile && javaProject.isOnClasspath(resource)) { IFile file = (IFile) resource; if ("drl".equals(resource.getFileExtension()) || "dslr".equals(resource.getFileExtension())) { try { DRLInfo drlInfo = DroolsEclipsePlugin.getDefault().parseResource(resource, false); String packageName = drlInfo.getPackageName(); Package pkg = ruleSet.getPackage(packageName); if (pkg == null) { pkg = DroolsModelBuilder.addPackage(ruleSet, packageName, 0, 0); } if (drlInfo.getBuilderErrors().length > 0 || drlInfo.getPackageDescr() == null) { return false; } // add rules List rules = drlInfo.getPackageDescr().getRules(); for (Iterator iterator = rules.iterator(); iterator.hasNext();) { RuleDescr ruleDescr = (RuleDescr) iterator.next(); boolean isQuery = ruleDescr instanceof QueryDescr; String ruleName = ruleDescr.getName(); if (!isQuery) { Rule rule = DroolsModelBuilder.addRule( pkg, ruleName, file, ruleDescr.getStartCharacter(), ruleDescr.getEndCharacter() - ruleDescr.getStartCharacter() + 1, null); // create link between resource and created rule nodes List droolsElements = (List) resourcesMap.get(file); if (droolsElements == null) { droolsElements = new ArrayList(); resourcesMap.put(file, droolsElements); } droolsElements.add(rule); } else { Query query = DroolsModelBuilder.addQuery( pkg, ruleName, file, ruleDescr.getStartCharacter(), ruleDescr.getEndCharacter() - ruleDescr.getStartCharacter() + 1); // create link between resource and created rule nodes List droolsElements = (List) resourcesMap.get(file); if (droolsElements == null) { droolsElements = new ArrayList(); resourcesMap.put(file, droolsElements); } droolsElements.add(query); } } // add templates List templates = drlInfo.getPackageDescr().getFactTemplates(); for (Iterator iterator = templates.iterator(); iterator.hasNext();) { FactTemplateDescr templateDescr = (FactTemplateDescr) iterator.next(); Template template = DroolsModelBuilder.addTemplate( pkg, templateDescr.getName(), file, templateDescr.getStartCharacter(), templateDescr.getEndCharacter() - templateDescr.getStartCharacter() + 1); // create link between resource and created rule nodes List droolsElements = (List) resourcesMap.get(file); if (droolsElements == null) { droolsElements = new ArrayList(); resourcesMap.put(file, droolsElements); } droolsElements.add(template); } // add globals List globals = drlInfo.getPackageDescr().getGlobals(); for (Iterator iterator = globals.iterator(); iterator.hasNext();) { GlobalDescr globalDescr = (GlobalDescr) iterator.next(); Global global = DroolsModelBuilder.addGlobal( pkg, globalDescr.getIdentifier(), file, globalDescr.getStartCharacter(), globalDescr.getEndCharacter() - globalDescr.getStartCharacter() + 1); // create link between resource and created rule nodes List droolsElements = (List) resourcesMap.get(file); if (droolsElements == null) { droolsElements = new ArrayList(); resourcesMap.put(file, droolsElements); } droolsElements.add(global); } // add functions List functions = drlInfo.getPackageDescr().getFunctions(); for (Iterator iterator = functions.iterator(); iterator.hasNext();) { FunctionDescr functionDescr = (FunctionDescr) iterator.next(); String functionName = functionDescr.getName(); Function function = DroolsModelBuilder.addFunction( pkg, functionName, file, functionDescr.getStartCharacter(), functionDescr.getEndCharacter() - functionDescr.getStartCharacter() + 1); // create link between resource and created rule nodes List droolsElements = (List) resourcesMap.get(file); if (droolsElements == null) { droolsElements = new ArrayList(); resourcesMap.put(file, droolsElements); } droolsElements.add(function); } } catch (Throwable t) { DroolsEclipsePlugin.log(t); } return false; } else if ("rf".equals(resource.getFileExtension())) { try { String processString = convertToString(file.getContents()); ProcessInfo processInfo = DroolsEclipsePlugin.getDefault().parseProcess(processString, resource); if (processInfo != null && processInfo.getProcess() != null) { String packageName = processInfo.getProcess().getPackageName(); Package pkg = ruleSet.getPackage(packageName); if (pkg == null) { pkg = DroolsModelBuilder.addPackage(ruleSet, packageName, 0, 0); } Process process = DroolsModelBuilder.addProcess(pkg, processInfo.getProcess().getId(), file); List droolsElements = (List) resourcesMap.get(file); if (droolsElements == null) { droolsElements = new ArrayList(); resourcesMap.put(file, droolsElements); } droolsElements.add(process); } } catch (Throwable t) { DroolsEclipsePlugin.log(t); } return false; } } } return true; } public void resourceChanged(final IResourceChangeEvent event) { try { if (event.getType() == IResourceChangeEvent.POST_CHANGE) { IResourceDelta delta = event.getDelta(); if (delta != null) { delta.accept(new IResourceDeltaVisitor() { public boolean visit(IResourceDelta delta) throws CoreException { IResource resource = delta.getResource(); removeElementsFromResource(resource); boolean result = true; if (delta.getKind() != IResourceDelta.REMOVED) { result = updateResource(resource); } treeViewer.getControl().getDisplay().asyncExec( new Runnable() { public void run() { if (!treeViewer.getControl().isDisposed()) { treeViewer.refresh(); } } } ); return result; } }); } } else if (event.getType() == IResourceChangeEvent.PRE_DELETE) { IResource resource = event.getResource(); if (resource != null) { resource.accept(new IResourceVisitor() { public boolean visit(IResource resource) throws CoreException { removeElementsFromResource(resource); return true; } }); } } else if (event.getType() == IResourceChangeEvent.PRE_CLOSE) { IResource resource = event.getResource(); if (resource != null) { resource.accept(new IResourceVisitor() { public boolean visit(IResource resource) throws CoreException { removeElementsFromResource(resource); return true; } }); } } } catch (Throwable t) { DroolsEclipsePlugin.log(t); } } private void removeElementsFromResource(IResource resource) { List droolsElements = (List) resourcesMap.get(resource); if (droolsElements != null) { for (Iterator iterator = droolsElements.iterator(); iterator.hasNext();) { DroolsModelBuilder.removeElement((DroolsElement) iterator.next()); } resourcesMap.remove(resource); } } public void doubleClick(DoubleClickEvent event) { ISelection selection = event.getSelection(); if (selection instanceof IStructuredSelection) { Object selected = ((StructuredSelection) selection).getFirstElement(); if (selected != null && selected instanceof DroolsElement) { DroolsElement droolsSelected = (DroolsElement) selected; IFile file = droolsSelected.getFile(); if (file != null) { try { IEditorPart editor = IDE.openEditor(getSite().getPage(), file); if (editor instanceof FormEditor) { editor = ((FormEditor) editor).getActiveEditor(); } if (editor instanceof ITextEditor) { ((ITextEditor)editor).selectAndReveal( droolsSelected.getOffset(), droolsSelected.getLength()); } } catch (Throwable t) { DroolsEclipsePlugin.log(t); } } } } } private static String convertToString(final InputStream inputStream) throws IOException { Reader reader = new InputStreamReader(inputStream); final StringBuffer text = new StringBuffer(); final char[] buf = new char[1024]; int len = 0; while ((len = reader.read(buf)) >= 0) { text.append(buf, 0, len); } return text.toString(); } }