📄 reteviewer.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 + -