/** * 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.flow.ruleflow.view.property.constraint; /* * Copyright 2005 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.util.List; import java.util.Map; import org.drools.core.util.ArrayUtils; import org.drools.eclipse.editors.DRLSourceViewerConfig; import org.drools.eclipse.editors.scanners.DRLPartionScanner; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.text.Document; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.IDocumentPartitioner; import org.eclipse.jface.text.contentassist.ContentAssistant; import org.eclipse.jface.text.contentassist.IContentAssistant; import org.eclipse.jface.text.reconciler.IReconciler; import org.eclipse.jface.text.rules.FastPartitioner; import org.eclipse.jface.text.source.ISourceViewer; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.events.KeyListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.TabFolder; import org.eclipse.swt.widgets.TabItem; import org.eclipse.swt.widgets.Text; import org.jbpm.workflow.core.Constraint; import org.jbpm.workflow.core.WorkflowProcess; import org.jbpm.workflow.core.impl.ConstraintImpl; /** * Dialog for editing constraints. * * @author <a href="mailto:kris_verlaenen@hotmail.com">Kris Verlaenen</a> */ public class RuleFlowConstraintDialog extends Dialog { private static final String[] DIALECTS = new String[] { "mvel", "java" }; private static final String[] TYPES = new String[] { "rule", "code" }; private Constraint constraint; private WorkflowProcess process; private boolean success; private Button alwaysTrue; private Text nameText; private Text priorityText; private Combo typeCombo; private Combo dialectCombo; private TabFolder tabFolder; private SourceViewer constraintViewer; private ConstraintCompletionProcessor completionProcessor; public RuleFlowConstraintDialog(Shell parentShell, WorkflowProcess process) { super(parentShell); this.process = process; setShellStyle(getShellStyle() | SWT.RESIZE); } protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Constraint editor"); } protected Point getInitialSize() { return new Point(600, 450); } private Control createTextualEditor(Composite parent) { constraintViewer = new SourceViewer(parent, null, SWT.BORDER); constraintViewer.configure(new DRLSourceViewerConfig(null) { public IReconciler getReconciler(ISourceViewer sourceViewer) { return null; } public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) { ContentAssistant assistant = new ContentAssistant(); completionProcessor = new ConstraintCompletionProcessor(process); assistant.setContentAssistProcessor( completionProcessor, IDocument.DEFAULT_CONTENT_TYPE); assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY); return assistant; } }); IDocument document = new Document(); constraintViewer.setDocument(document); IDocumentPartitioner partitioner = new FastPartitioner( new DRLPartionScanner(), DRLPartionScanner.LEGAL_CONTENT_TYPES); partitioner.connect(document); document.setDocumentPartitioner(partitioner); constraintViewer.getControl().addKeyListener(new KeyListener() { public void keyPressed(KeyEvent e) { if (e.character == ' ' && e.stateMask == SWT.CTRL) { constraintViewer.doOperation(ISourceViewer.CONTENTASSIST_PROPOSALS); } } public void keyReleased(KeyEvent e) { } }); return constraintViewer.getControl(); } private String getConstraintText() { return constraintViewer.getDocument().get(); } private void setConstraintText(String text) { constraintViewer.getDocument().set(text); } public Control createDialogArea(Composite parent) { GridLayout layout = new GridLayout(); parent.setLayout(layout); layout.numColumns = 2; Composite top = new Composite(parent, SWT.NONE); GridData gd = new GridData(); gd.horizontalSpan = 2; gd.grabExcessHorizontalSpace = true; top.setLayoutData(gd); layout = new GridLayout(); layout.numColumns = 4; top.setLayout(layout); Label l1 = new Label(top, SWT.None); l1.setText("Name:"); gd = new GridData(); l1.setLayoutData(gd); nameText = new Text(top, SWT.BORDER); gd = new GridData(); gd.horizontalAlignment = GridData.FILL; gd.widthHint = 200; gd.horizontalSpan = 3; nameText.setLayoutData(gd); Label l2 = new Label(top, SWT.NONE); gd = new GridData(); l2.setLayoutData(gd); l2.setText("Priority:"); priorityText = new Text(top, SWT.BORDER); gd = new GridData(); gd.widthHint = 200; gd.horizontalSpan = 3; priorityText.setLayoutData(gd); alwaysTrue = new Button(top, SWT.CHECK); alwaysTrue.setText("Always true"); gd = new GridData(); gd.horizontalSpan = 2; alwaysTrue.setLayoutData(gd); Button importButton = new Button(top, SWT.PUSH); importButton.setText("Imports ..."); importButton.setFont(JFaceResources.getDialogFont()); importButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { importButtonPressed(); } }); gd = new GridData(); gd.grabExcessHorizontalSpace = true; gd.horizontalAlignment = GridData.END; importButton.setLayoutData(gd); Button globalButton = new Button(top, SWT.PUSH); globalButton.setText("Globals ..."); globalButton.setFont(JFaceResources.getDialogFont()); globalButton.addSelectionListener(new SelectionAdapter() { public void widgetSelected(SelectionEvent event) { globalButtonPressed(); } }); gd = new GridData(); gd.horizontalAlignment = GridData.END; globalButton.setLayoutData(gd); Label l3 = new Label(top, SWT.NONE); gd = new GridData(); l3.setLayoutData(gd); l3.setText("Type:"); typeCombo = new Combo(top, SWT.DROP_DOWN | SWT.READ_ONLY); typeCombo.setItems(TYPES); gd = new GridData(); typeCombo.setLayoutData(gd); typeCombo.addSelectionListener(new SelectionListener() { public void widgetDefaultSelected(SelectionEvent e) { } public void widgetSelected(SelectionEvent e) { if (completionProcessor != null) { completionProcessor.setType(typeCombo.getText()); } } }); typeCombo.select(0); Label l4 = new Label(top, SWT.NONE); gd = new GridData(); l4.setLayoutData(gd); l4.setText("Dialect:"); dialectCombo = new Combo(top, SWT.DROP_DOWN | SWT.READ_ONLY); dialectCombo.setItems(DIALECTS); dialectCombo.select(0); gd = new GridData(); dialectCombo.setLayoutData(gd); tabFolder = new TabFolder(parent, SWT.NONE); gd = new GridData(); gd.horizontalSpan = 4; gd.grabExcessHorizontalSpace = true; gd.grabExcessVerticalSpace = true; gd.verticalAlignment = GridData.FILL; gd.horizontalAlignment = GridData.FILL; tabFolder.setLayoutData(gd); TabItem textEditorTab = new TabItem(tabFolder, SWT.NONE); textEditorTab.setText("Textual Editor"); textEditorTab.setControl(createTextualEditor(tabFolder)); alwaysTrue.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { tabFolder.setVisible(!alwaysTrue.getSelection()); } public void widgetDefaultSelected(SelectionEvent e) { widgetSelected(e); } }); return tabFolder; } private void importButtonPressed() { final Runnable r = new Runnable() { public void run() { RuleFlowImportsDialog dialog = new RuleFlowImportsDialog(getShell(), process); dialog.create(); int code = dialog.open(); if (code != CANCEL) { List imports = dialog.getImports(); ((org.jbpm.process.core.Process) process).setImports(imports); completionProcessor.reset(); } } }; r.run(); } private void globalButtonPressed() { final Runnable r = new Runnable() { public void run() { RuleFlowGlobalsDialog dialog = new RuleFlowGlobalsDialog(getShell(), process); dialog.create(); int code = dialog.open(); if (code != CANCEL) { Map globals = dialog.getGlobals(); ((org.jbpm.process.core.Process) process).setGlobals(globals); completionProcessor.reset(); } } }; r.run(); } public void fixType(int index) { typeCombo.select(index); typeCombo.setEnabled(false); } public void fixDialect(int index) { typeCombo.select(index); typeCombo.setEnabled(false); } protected void okPressed() { int selectionIndex = tabFolder.getSelectionIndex(); if (selectionIndex == 1) { updateTranslation(); } else { updateConstraint(); } super.okPressed(); } private void updateTranslation() { // TODO add custom token model checker success = true; constraint = new ConstraintImpl(); constraint.setConstraint(null); constraint.setConstraint(getConstraintText()); constraint.setName(nameText.getText()); try { constraint.setPriority(Integer.parseInt(priorityText.getText())); } catch (NumberFormatException exc) { constraint.setPriority(1); } } public boolean isSuccess() { return success; } public void updateConstraint() { constraint = new ConstraintImpl(); if (!alwaysTrue.getSelection()) { constraint.setConstraint(getConstraintText()); } else { if (typeCombo.getSelectionIndex() == 0) { constraint.setConstraint("eval(true)"); } else { constraint.setConstraint("return true;"); } } constraint.setName(nameText.getText()); try { constraint.setPriority(Integer.parseInt(priorityText.getText())); } catch (NumberFormatException exc) { constraint.setPriority(1); } constraint.setType(typeCombo.getItem(typeCombo.getSelectionIndex())); constraint.setDialect(dialectCombo.getItem(dialectCombo.getSelectionIndex())); } public Constraint getConstraint() { return constraint; } public void setConstraint(Constraint constraint) { this.constraint = constraint; if (constraint != null) { if ("eval(true)".equals(constraint.getConstraint()) || "return true;".equals(constraint.getConstraint())) { alwaysTrue.setSelection(true); } else { setConstraintText(constraint.getConstraint() == null ? "" : constraint.getConstraint()); } tabFolder.setVisible(!alwaysTrue.getSelection()); nameText.setText(constraint.getName() == null ? "" : constraint .getName()); priorityText.setText(constraint.getPriority() + ""); int index = 0; String type = constraint.getType(); int found = ArrayUtils.indexOf(TYPES, type); if (found >= 0) { index = found; } typeCombo.select(index); index = 0; String dialect = constraint.getDialect(); found = ArrayUtils.indexOf(DIALECTS, dialect); if (found >= 0) { index = found; } dialectCombo.select(index); completionProcessor.setType(typeCombo.getText()); setConstraintText(constraint.getConstraint()); } else { priorityText.setText("1"); nameText.setText("constraint"); } } }