
org.pentaho.dm.kf.GroovyComponentCustomizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kfGroovy Show documentation
Show all versions of kfGroovy Show documentation
Knowledge Flow plugin that provides a Knowledge Flow step that wraps around a Groovy script. The plugin generates a fully compilable template Groovy script that implements various Knowledge Flow interfaces. The user can fill in the methods that are necessary to accomplish the desired logic. The script is compiled at runtime and the Groovy component passes incoming events to the script and collects and passes on generated events.
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* GroovyComponentCustomizer.java
* Copyright (C) 2009 Pentaho Corporation
*
*/
package org.pentaho.dm.kf;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.Customizer;
import java.util.Properties;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import java.awt.Window;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import weka.core.Utils;
import weka.gui.beans.BeanCustomizer;
import weka.gui.beans.CustomizerCloseRequester;
import weka.gui.scripting.GroovyScript;
import weka.gui.scripting.SyntaxDocument;
import weka.gui.visualize.VisualizeUtils;
/**
* Customizer class for the GroovyComponent.
*
* @author Mark Hall (mhall{[at]}pentaho{[dot]}com)
* @version $Revision $
*/
public class GroovyComponentCustomizer extends JPanel
implements BeanCustomizer, CustomizerCloseRequester {
/** The object to edit */
protected GroovyComponent m_groovyP;
/** The script from the GroovyComponent */
protected GroovyScript m_script;
protected JTextPane m_textPane = new JTextPane();
protected Window m_parentWindow;
/** Holds the template text of a new script */
protected String m_newScript;
protected JMenuBar m_menuBar;
protected ModifyListener m_modifyListener;
/** the Groovy setup. */
public final static String PROPERTIES_FILE = "weka/gui/scripting/Groovy.props";
/* (non-Javadoc)
* @see java.beans.Customizer#setObject(java.lang.Object)
*/
public void setObject(Object object) {
m_groovyP = (GroovyComponent)object;
m_script = new GroovyScript(m_textPane.getDocument());
String script = m_groovyP.getScript();
if (script != null && script.length() > 0) {
m_script.setContent(script);
}
}
public GroovyComponentCustomizer() {
Properties props;
try {
props = Utils.readProperties(PROPERTIES_FILE);
} catch (Exception ex) {
ex.printStackTrace();
props = new Properties();
}
if (props.getProperty("Syntax", "false").equals("true")) {
SyntaxDocument doc = new SyntaxDocument(props);
m_textPane.setDocument(doc);
m_textPane.setBackground(doc.getBackgroundColor());
} else {
m_textPane.setForeground(VisualizeUtils.processColour(
props.getProperty("ForegroundColor", "black"), Color.BLACK));
m_textPane.setBackground(VisualizeUtils.processColour(
props.getProperty("BackgroundColor", "white"), Color.WHITE));
m_textPane.setFont(new Font(props.getProperty("FontName", "monospaced"),
Font.PLAIN, Integer.parseInt(props.getProperty("FontSize", "12"))));
}
final JFileChooser fileChooser = new JFileChooser();
fileChooser.setAcceptAllFileFilterUsed(true);
fileChooser.setMultiSelectionEnabled(false);
setUpNewScript();
setLayout(new BorderLayout());
add(new JScrollPane(m_textPane), BorderLayout.CENTER);
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new BorderLayout());
JPanel newCompile = new JPanel();
newCompile.setLayout(new BorderLayout());
JButton newBut = new JButton("New");
JButton compileBut = new JButton("Compile");
JButton okBut = new JButton("OK");
JButton cancelBut = new JButton("Cancel");
newCompile.add(newBut, BorderLayout.WEST);
newCompile.add(compileBut, BorderLayout.EAST);
buttonPanel.add(newCompile, BorderLayout.WEST);
buttonPanel.add(okBut, BorderLayout.CENTER);
buttonPanel.add(cancelBut, BorderLayout.EAST);
add(buttonPanel, BorderLayout.SOUTH);
newBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newScript(fileChooser);
}
});
compileBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doCompile();
}
});
okBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (m_groovyP != null) {
m_groovyP.setScript(m_script.getContent());
if (m_modifyListener != null) {
m_modifyListener.setModifiedStatus(GroovyComponentCustomizer.this, true);
}
// close the dialog
m_parentWindow.dispose();
}
}
});
cancelBut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// just close the dialog
//TODO if their are mods, ask the user (same if the frame is closed
// from the close widget)
if (m_modifyListener != null) {
m_modifyListener.setModifiedStatus(GroovyComponentCustomizer.this, false);
}
m_parentWindow.dispose();
}
});
m_menuBar = new JMenuBar();
JMenu fileM = new JMenu();
m_menuBar.add(fileM);
fileM.setText("File");
fileM.setMnemonic('F');
JMenuItem newItem = new JMenuItem();
fileM.add(newItem);
newItem.setText("New");
newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
KeyEvent.CTRL_MASK));
newItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
newScript(fileChooser);
}
});
JMenuItem loadItem = new JMenuItem();
fileM.add(loadItem);
loadItem.setText("Open File...");
loadItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,
KeyEvent.CTRL_MASK));
loadItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int retVal = fileChooser.showOpenDialog(GroovyComponentCustomizer.this);
if (retVal == JFileChooser.APPROVE_OPTION) {
boolean ok = m_script.open(fileChooser.getSelectedFile());
if (!ok) {
JOptionPane.showMessageDialog(GroovyComponentCustomizer.this,
"Couldn't open file '" + fileChooser.getSelectedFile() + "'!");
}
}
}
});
JMenuItem saveItem = new JMenuItem();
fileM.add(saveItem);
saveItem.setText("Save");
saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,
KeyEvent.CTRL_MASK));
saveItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (m_script.getFilename() != null) {
save(null);
} else {
save(fileChooser);
}
}
});
JMenuItem saveAsItem = new JMenuItem();
fileM.add(saveAsItem);
saveAsItem.setText("Save As...");
saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,
KeyEvent.CTRL_MASK));
saveAsItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
save(fileChooser);
}
});
JMenu scriptM = new JMenu();
m_menuBar.add(scriptM);
scriptM.setText("Script");
scriptM.setMnemonic('S');
JMenuItem compileItem = new JMenuItem();
scriptM.add(compileItem);
compileItem.setText("Compile");
compileItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,
KeyEvent.CTRL_MASK));
compileItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doCompile();
}
});
Dimension d = new Dimension(600,800);
m_textPane.setMinimumSize(d);
m_textPane.setPreferredSize(d);
}
private void save(JFileChooser fileChooser) {
boolean ok = false;
int retVal;
if (m_script.getFilename() == null || fileChooser != null) {
retVal = fileChooser.showSaveDialog(GroovyComponentCustomizer.this);
if (retVal == JFileChooser.APPROVE_OPTION) {
ok = m_script.saveAs(fileChooser.getSelectedFile());
}
} else {
ok = m_script.save();
}
if (!ok) {
if (m_script.getFilename() != null) {
JOptionPane.showMessageDialog(GroovyComponentCustomizer.this,
"Failed to save file '" + fileChooser.getSelectedFile() + "'!");
} else {
JOptionPane.showMessageDialog(GroovyComponentCustomizer.this,
"Failed to save file!");
}
}
}
private void doCompile() {
if (m_groovyP != null) {
String script = m_script.getContent();
if (script != null && script.length() > 0) {
try {
m_groovyP.compileScript(script);
JOptionPane.showMessageDialog(GroovyComponentCustomizer.this,
"Script compiled OK.",
"Script Status",
JOptionPane.INFORMATION_MESSAGE);
} catch (Exception ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(GroovyComponentCustomizer.this,
"Problem compiling script:\n" + ex.getMessage(),
"Script Status",
JOptionPane.INFORMATION_MESSAGE);
}
}
}
}
private void newScript(JFileChooser fileChooser) {
if (m_groovyP != null) {
if (m_script.isModified()) {
// prompt for are you sure?
int retVal = JOptionPane.showConfirmDialog(GroovyComponentCustomizer.this,
"Save changes" +
((m_script.getFilename() != null)
? (" to " + m_script.getFilename() + "?")
: " first?"));
if (retVal == JOptionPane.OK_OPTION) {
if (m_script.getFilename() != null) {
save(null);
} else {
save(fileChooser);
}
}
}
m_script.setContent(m_newScript);
}
}
public void setParentWindow(Window parent) {
m_parentWindow = parent;
if (parent instanceof javax.swing.JDialog) {
((javax.swing.JDialog)m_parentWindow).setJMenuBar(m_menuBar);
((javax.swing.JDialog)m_parentWindow).setTitle("Groovy Script Editor");
}
}
protected void setUpNewScript() {
StringBuffer temp = new StringBuffer();
temp.append("import java.beans.*\n");
temp.append("import java.io.Serializable\n");
temp.append("import java.util.Vector\n");
temp.append("import java.util.Enumeration\n");
temp.append("import org.pentaho.dm.kf.KFGroovyScript\n");
temp.append("import org.pentaho.dm.kf.GroovyHelper\n");
temp.append("import weka.core.*\n");
temp.append("import weka.gui.Logger\n");
temp.append("import weka.gui.beans.*\n");
temp.append("// add further imports here if necessary\n\n");
temp.append("class MyScript\n");
temp.append("\timplements\n");
temp.append("\t\tKFGroovyScript,\n");
temp.append("\t\tEnvironmentHandler,\n");
temp.append("\t\tBeanCommon,\n");
temp.append("\t\tEventConstraints,\n");
temp.append("\t\tUserRequestAcceptor,\n");
temp.append("\t\tTrainingSetListener,\n");
temp.append("\t\tTestSetListener,\n");
temp.append("\t\tDataSourceListener,\n");
temp.append("\t\tInstanceListener,\n");
temp.append("\t\tTextListener,\n");
temp.append("\t\tBatchClassifierListener,\n");
temp.append("\t\tIncrementalClassifierListener,\n");
temp.append("\t\tBatchClustererListener,\n");
temp.append("\t\tGraphListener,\n");
temp.append("\t\tChartListener,\n");
temp.append("\t\tThresholdDataListener,\n");
temp.append("\t\tVisualizableErrorListener,\n");
temp.append("\t\tSerializable {\n\n");
temp.append("\t/** Don't delete!!\n");
temp.append("\t * GroovyHelper has the following useful methods:\n");
temp.append("\t *\n");
temp.append("\t * notifyListenerType(Object event) - GroovyHelper will pass on event\n");
temp.append("\t * appropriate listener type for you\n");
temp.append("\t * ArrayList getTrainingSetListeners() - get\n");
temp.append("\t * a list of any directly connected components that are listening\n");
temp.append("\t * for TrainingSetEvents from us\n");
temp.append("\t * ArrayList getTestSetListeners()\n");
temp.append("\t * ArrayList getInstanceListeners()\n");
temp.append("\t * ArrayList getTextListeners()\n");
temp.append("\t * ArrayList getDataSourceListeners()\n");
temp.append("\t * ArrayList getBatchClassifierListeners()\n");
temp.append("\t * ArrayList getIncrementalClassifierListeners()\n");
temp.append("\t * ArrayList getBatchClustererListeners()\n");
temp.append("\t * ArrayList getGraphListeners()\n");
temp.append("\t * ArrayList getChartListeners()\n");
temp.append("\t * ArrayList getThresholdDataListeners()\n");
temp.append("\t * ArrayList getVisualizableErrorListeners()\n");
temp.append("\t */\n");
temp.append("\tGroovyHelper m_helper\n\n");
temp.append("\t/** Don't delete!! */\n");
temp.append("\tvoid setManager(GroovyHelper manager) { "
+ "m_helper = manager }\n\n");
// BeanCommon
temp.append("\t/** Alter or add to in order to tell the KnowlegeFlow\n");
temp.append("\t * environment whether a certain incoming connection type is allowed\n");
temp.append("\t */\n");
temp.append("\tboolean connectionAllowed(String eventName) {\n");
temp.append("\t\tif (eventName.equals(\"trainingSet\")) { return false }\n");
temp.append("\t\treturn false\n");
temp.append("\t}\n\n");
temp.append("\t/** Alter or add to in order to tell the KnowlegeFlow\n");
temp.append("\t * environment whether a certain incoming connection type is allowed\n");
temp.append("\t */\n");
temp.append("\tboolean connectionAllowed(EventSetDescriptor esd) {\n");
temp.append("\t\treturn connectionAllowed(esd.getName())\n");
temp.append("\t}\n\n");
temp.append("\t/** Add (optional) code to do something when you have been\n");
temp.append("\t * registered as a listener with a source for the named event\n");
temp.append("\t */\n");
temp.append("\tvoid connectionNotification(String eventName, Object source) { }\n\n");
temp.append("\t/** Add (optional) code to do something when you have been\n");
temp.append("\t * deregistered as a listener with a source for the named event\n");
temp.append("\t */\n");
temp.append("\tvoid disconnectionNotification(String eventName, Object source) { }\n\n");
temp.append("\t/** Custom name of this component. Do something with it if you\n");
temp.append("\t * like. GroovyHelper already stores it and alters the icon text\n");
temp.append("\t * for you");
temp.append("\t */\n");
temp.append("\tvoid setCustomName(String name) { }\n\n");
temp.append("\t/** Custom name of this component. No need to return anything\n");
temp.append("\t * GroovyHelper already stores it and alters the icon text\n");
temp.append("\t * for you");
temp.append("\t */\n");
temp.append("\tString getCustomName() { return null }\n\n");
temp.append("\t/** Add code to return true when you are busy doing something\n");
temp.append("\t */\n");
temp.append("\tboolean isBusy() { return false }\n\n");
temp.append("\t/** Store and use this logging object in order to post messages\n" +
"\t * to the log\n");
temp.append("\t */\n");
temp.append("\tvoid setLog(Logger logger) { }\n\n");
temp.append("\t/** Store and use this Environment object in order to lookup and\n" +
"\t * use the values of environment variables\n");
temp.append("\t */\n");
temp.append("\tvoid setEnvironment(Environment env) { }\n\n");
temp.append("\t/** Stop any processing (if possible)\n");
temp.append("\t */\n");
temp.append("\tvoid stop() { }\n\n");
temp.append("\t/** Alter or add to in order to tell the KnowlegeFlow\n");
temp.append("\t * whether, at the current time, the named event could\n");
temp.append("\t * be generated.\n");
temp.append("\t */\n");
temp.append("\tboolean eventGeneratable(String eventName) {\n");
temp.append("\t\tif (eventName.equals(\"trainingSet\")) { return false }\n");
temp.append("\t\treturn false\n");
temp.append("\t}\n\n");
temp.append("\t/** Implement this to tell KnowledgeFlow about any methods\n");
temp.append("\t * that the user could invoke (i.e. to show a popup visualization\n");
temp.append("\t * or something).\n");
temp.append("\t */\n");
temp.append("\tEnumeration enumerateRequests() { return (new Vector(0)).elements()}\n\n");
temp.append("\t/** Make the user-requested action happen here.\n");
temp.append("\t */\n");
temp.append("\tvoid performRequest(String requestName) { }\n\n");
temp.append("\t//--------------- Incoming events ------------------\n");
temp.append("\t//--------------- Implement as necessary -----------\n\n");
temp.append("\tvoid acceptTrainingSet(TrainingSetEvent e) { }\n\n");
temp.append("\tvoid acceptTestSet(TestSetEvent e) { }\n\n");
temp.append("\tvoid acceptDataSet(DataSetEvent e) { }\n\n");
temp.append("\tvoid acceptInstance(InstanceEvent e) { }\n\n");
temp.append("\tvoid acceptText(TextEvent e) { }\n\n");
temp.append("\tvoid acceptClassifier(BatchClassifierEvent e) { }\n\n");
temp.append("\tvoid acceptClassifier(IncrementalClassifierEvent e) { }\n\n");
temp.append("\tvoid acceptClusterer(BatchClustererEvent e) { }\n\n");
temp.append("\tvoid acceptGraph(GraphEvent e) { }\n\n");
temp.append("\tvoid acceptDataPoint(ChartEvent e) { }\n\n");
temp.append("\tvoid acceptDataSet(ThresholdDataEvent e) { }\n\n");
temp.append("\tvoid acceptDataSet(VisualizableErrorEvent e) { }\n\n");
temp.append("}\n");
m_newScript = temp.toString();
}
public void setModifiedListener(ModifyListener l) {
m_modifyListener = l;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy