⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reteviewer.java

📁 jboss规则引擎
💻 JAVA
字号:
package org.drools.ide.editors.rete;

/*
 * Copyright 2006 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.
 */
import java.io.Reader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.drools.PackageIntegrationException;
import org.drools.RuleBase;
import org.drools.compiler.DrlParser;
import org.drools.compiler.DroolsParserException;
import org.drools.compiler.PackageBuilder;
import org.drools.ide.DroolsIDEPlugin;
import org.drools.ide.builder.DroolsBuilder;
import org.drools.ide.editors.DSLAdapter;
import org.drools.ide.editors.rete.model.ReteGraph;
import org.drools.ide.editors.rete.part.VertexEditPartFactory;
import org.drools.ide.util.ProjectClassLoader;
import org.drools.lang.descr.PackageDescr;
import org.drools.reteoo.BaseVertex;
import org.drools.reteoo.ReteooRuleBase;
import org.drools.reteoo.ReteooVisitor;
import org.drools.rule.Package;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.ConnectionLayer;
import org.eclipse.draw2d.ConnectionRouter;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ShortestPathConnectionRouter;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.GraphicalViewer;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.MouseWheelHandler;
import org.eclipse.gef.MouseWheelZoomHandler;
import org.eclipse.gef.editparts.LayerManager;
import org.eclipse.gef.editparts.ScalableFreeformRootEditPart;
import org.eclipse.gef.editparts.ZoomManager;
import org.eclipse.gef.ui.parts.GraphicalEditor;
import org.eclipse.gef.ui.parts.GraphicalViewerKeyHandler;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IFileEditorInput;

/**
 * GEF-based RETE Viewer
 * 
 * @author Ahti Kitsik
 *
 */
public class ReteViewer extends GraphicalEditor {

    private static final String  MSG_PARSE_ERROR         = "Unable to parse rules to show RETE view!";

    private static final String  JAVA_NATURE             = "org.eclipse.jdt.core.javanature";

    private static final int     SIMPLE_ROUTER_MIN_NODES = 100;

    ScalableFreeformRootEditPart rootEditPart            = new ScalableFreeformRootEditPart();

    private ReteGraph            diagram                 = new ReteGraph();

    private boolean              relayoutRequired        = true;

    /**
     * Constructor.
     * 
     * @param documentProvider documentProvider must contain Document with rules.
     */
    public ReteViewer() {
        super();
        setEditDomain( new DefaultEditDomain( this ) );
    }

    /* (non-Javadoc)
     * @see org.eclipse.gef.ui.parts.GraphicalEditor#configureGraphicalViewer()
     */
    protected void configureGraphicalViewer() {
        super.configureGraphicalViewer();
        GraphicalViewer viewer = getGraphicalViewer();
        viewer.getControl().setBackground( ColorConstants.white );
        viewer.setEditPartFactory( new VertexEditPartFactory() );
        viewer.setRootEditPart( rootEditPart );
        viewer.setKeyHandler( new GraphicalViewerKeyHandler( viewer ) );
    }

    /* (non-Javadoc)
     * @see org.eclipse.gef.ui.parts.GraphicalEditor#getAdapter(java.lang.Class)
     */
    public Object getAdapter(Class type) {

        if ( type == ZoomManager.class ) return ((ScalableFreeformRootEditPart) getGraphicalViewer().getRootEditPart()).getZoomManager();
        if ( type == GraphicalViewer.class ) return getGraphicalViewer();
        if ( type == EditPart.class && getGraphicalViewer() != null ) return getGraphicalViewer().getRootEditPart();
        if ( type == IFigure.class && getGraphicalViewer() != null ) return ((GraphicalEditPart) getGraphicalViewer().getRootEditPart()).getFigure();
        return super.getAdapter( type );
    }

    private RuleBase getRuleBase(String contents) {
        if ( getEditorInput() instanceof IFileEditorInput ) {
            try {

                ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
                ClassLoader newLoader = DroolsBuilder.class.getClassLoader();
                IFile file = ((IFileEditorInput) getEditorInput()).getFile();
                if ( file.getProject().getNature( JAVA_NATURE ) != null ) {
                    IJavaProject project = JavaCore.create( file.getProject() );
                    newLoader = ProjectClassLoader.getProjectClassLoader( project );
                }

                Reader dslReader = DSLAdapter.getDSLContent( contents,
                                                             file );

                try {
                    Thread.currentThread().setContextClassLoader( newLoader );

                    return parseRuleBase( contents,
                                          dslReader );

                } catch ( Exception t ) {
                    throw t;
                } finally {
                    Thread.currentThread().setContextClassLoader( oldLoader );
                }
            } catch ( Throwable t ) {
                DroolsIDEPlugin.log( t );
            }
        }

        return null;

    }

    /**
     * 
     * 
     * @param contents
     * @param dslReader
     * @return
     * @throws DroolsParserException
     * @throws PackageIntegrationException
     */
    public static RuleBase parseRuleBase(String contents,
                                         Reader dslReader) throws DroolsParserException,
                                                          PackageIntegrationException {
        DrlParser parser = new DrlParser();

        PackageDescr packageDescr = null;
        if ( dslReader == null ) {
            packageDescr = parser.parse( contents );
        } else {
            packageDescr = parser.parse( contents,
                                         dslReader );
        }

        //pre build the package
        PackageBuilder builder = new PackageBuilder();
        builder.addPackage( packageDescr );
        Package pkg = builder.getPackage();

        //add the package to a rulebase
        ReteooRuleBase ruleBase = new ReteooRuleBase();
        ruleBase.addPackage( pkg );
        return ruleBase;
    }

    /**
     * Loads model from rule base,
     * calculates rete view and initializes diagram model.
     * @param monitor 
     * @param contents 
     * @return
     */
    public ReteGraph loadReteModel(IProgressMonitor monitor,
                                   String contents) throws Throwable {
        if ( relayoutRequired == false ) {
            return diagram;
        }

        ReteGraph newDiagram = new ReteGraph();

        try {

            monitor.beginTask( "Loading RETE Tree",
                               100 );

            monitor.subTask( "Loading Rule Base" );
            RuleBase ruleBase = getRuleBase( contents );
            if ( ruleBase == null ) {
                final Exception error = new Exception( MSG_PARSE_ERROR );
                throw error;
            }
            monitor.worked( 50 );
            if ( monitor.isCanceled() ) {
                throw new InterruptedException();
            }

            monitor.subTask( "Building RETE Tree" );
            final ReteooVisitor visitor = new ReteooVisitor( newDiagram );
            visitor.visit( ruleBase );
            monitor.worked( 30 );
            if ( monitor.isCanceled() ) {
                throw new InterruptedException();
            }

            monitor.subTask( "Calculating RETE Tree Layout" );
            BaseVertex rootVertex = visitor.getRootVertex();
            RowList rowList = ReteooLayoutFactory.calculateReteRows( rootVertex );
            ReteooLayoutFactory.layoutRowList( newDiagram,
                                               rowList );
            zeroBaseDiagram( newDiagram );
            monitor.worked( 20 );
            if ( monitor.isCanceled() ) {
                throw new InterruptedException();
            }
            monitor.done();

        } catch ( Throwable t ) {
            if ( !(t instanceof InterruptedException) ) {
                DroolsIDEPlugin.log( t );
            }
            throw t;
        }
        relayoutRequired = false;
        return newDiagram;
    }

    private ReteGraph getModel() {
        return diagram;
    }

    /**
     * Loads Rete model and initializes zoom manager.
     * 
     */
    protected void initializeGraphicalViewer() {
        ZoomManager zoomManager = rootEditPart.getZoomManager();

        //List<String>
        List zoomLevels = new ArrayList( 3 );

        zoomLevels.add( ZoomManager.FIT_ALL );
        zoomLevels.add( ZoomManager.FIT_HEIGHT );
        zoomLevels.add( ZoomManager.FIT_WIDTH );

        zoomManager.setZoomLevelContributions( zoomLevels );

        // Zoom mousewheel - Ctrl+Mousewheel for zoom in/out
        getGraphicalViewer().setProperty( MouseWheelHandler.KeyGenerator.getKey( SWT.MOD1 ),
                                          MouseWheelZoomHandler.SINGLETON );

    }

    /**
     * Moves all <code>diagram</code> nodes to upper left corner
     * and shifting to right if neccessary to get rid of negative XY coordinates.
     * 
     */
    private void zeroBaseDiagram(ReteGraph graph) {

        Dimension dim = rootEditPart.getContentPane().getSize();

        int minx = 0, miny = 0, maxx = 0, x = dim.width;

        final Iterator nodeIter = graph.getChildren().iterator();
        while ( nodeIter.hasNext() ) {
            Point loc = ((BaseVertex) (nodeIter.next())).getLocation();
            minx = Math.min( loc.x,
                             minx );
            maxx = Math.max( loc.x,
                             maxx );
            miny = Math.min( loc.y,
                             miny );
        }

        int delta = (x - (maxx - minx + 20)) / 2;
        minx = minx - (delta);

        final Iterator nodeIter2 = graph.getChildren().iterator();
        while ( nodeIter2.hasNext() ) {
            final BaseVertex vertex = (BaseVertex) (nodeIter2.next());
            Point loc = vertex.getLocation();
            vertex.setLocation( new Point( loc.x - minx,
                                           loc.y - miny ) );
        }
    }

    /**
     * No save operation in ReteViewer
     */
    public void doSave(IProgressMonitor monitor) {

    }

    /**
     * ReteViewer is never dirty.
     * This prevents editor close mechanism to ask file save confirmation
     * even after one of the vertices is moved.
     */
    public boolean isDirty() {
        return false;
    }

    /**
     * Fired when underlying source is modified.
     * Marks graph viewer to be relayouted when activated.
     */
    public void fireDocumentChanged() {
        relayoutRequired = true;
    }

    /**
     * Draws graph.
     * 
     * @param newGraph used to replace existing graph. if null then existing graph is simply redrawn.
     */
    public void drawGraph(ReteGraph newGraph) {

        LayerManager manager = (LayerManager) getGraphicalViewer().getEditPartRegistry().get( LayerManager.ID );
        ConnectionLayer connLayer = (ConnectionLayer) manager.getLayer( LayerConstants.CONNECTION_LAYER );

        // Lazy-init model initialization
        if ( getGraphicalViewer().getContents() == null ) {
            getGraphicalViewer().setContents( getModel() );
        }

        final boolean isNewDiagram = newGraph != null && newGraph != diagram;

        if ( isNewDiagram ) {
            diagram.removeAll();
        }

        // Update connection router according to new model size
        ConnectionRouter router;
        if ( (isNewDiagram && newGraph.getChildren().size() < SIMPLE_ROUTER_MIN_NODES) || (!isNewDiagram && getModel().getChildren().size() < SIMPLE_ROUTER_MIN_NODES) ) {
            router = new ShortestPathConnectionRouter( (IFigure) rootEditPart.getContentPane().getChildren().get( 0 ) );
        } else {
            router = ConnectionRouter.NULL;
        }
        connLayer.setConnectionRouter( router );

        if ( newGraph != null && newGraph != diagram ) {
            diagram.addAll( newGraph.getChildren() );
        }

    }

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -