001 /****************************************************************************** 002 * Copyright (C) MActor Developers. All rights reserved. * 003 * ---------------------------------------------------------------------------* 004 * This file is part of MActor. * 005 * * 006 * MActor is free software; you can redistribute it and/or modify * 007 * it under the terms of the GNU General Public License as published by * 008 * the Free Software Foundation; either version 2 of the License, or * 009 * (at your option) any later version. * 010 * * 011 * MActor is distributed in the hope that it will be useful, * 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 014 * GNU General Public License for more details. * 015 * * 016 * You should have received a copy of the GNU General Public License * 017 * along with MActor; if not, write to the Free Software * 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * 019 ******************************************************************************/ 020 package org.mactor.ui.gui.project.editors; 021 022 import java.awt.event.ActionEvent; 023 import java.awt.event.ActionListener; 024 import java.awt.event.ItemListener; 025 import java.io.File; 026 import java.io.IOException; 027 import java.util.Collections; 028 import java.util.Iterator; 029 import java.util.LinkedList; 030 import java.util.List; 031 032 import javax.swing.AbstractAction; 033 import javax.swing.JButton; 034 import javax.swing.JFileChooser; 035 import javax.swing.JLabel; 036 import javax.swing.JOptionPane; 037 import javax.swing.JTextField; 038 import javax.swing.filechooser.FileFilter; 039 040 import org.dom4j.Element; 041 import org.mactor.framework.MactorException; 042 import org.mactor.framework.spec.ProjectContext; 043 import org.mactor.ui.gui.GuiUtil; 044 import org.mactor.ui.gui.project.editors.CommandPrototypeComboBox.ProtoListener; 045 046 public class CommandEditor extends SimpleFormPanel { 047 CommandPrototypeComboBox protoCb = new CommandPrototypeComboBox(); 048 CommandTypeComboBox typeCb = new CommandTypeComboBox(); 049 GlobalConfigDBGroupComboBox gcDbGroup = new GlobalConfigDBGroupComboBox(); 050 ParamsPanel parameterPanel = new ParamsPanel(); 051 Element data; 052 String commandAttributeName; 053 SimpleRowPanel dbPanel = new SimpleRowPanel(); 054 BshPanel bshPanel = new BshPanel(); 055 JButton test = new JButton(new AbstractAction("Test...") { 056 public void actionPerformed(ActionEvent e) { 057 try { 058 applyListener.onApply(); 059 new CommandTestDlg(JOptionPane.getFrameForComponent(CommandEditor.this), data).setVisible(true); 060 } catch (MactorException me) { 061 GuiUtil.showGuiError(CommandEditor.this, me); 062 } 063 } 064 }); 065 ItemListener typeCbListener = new ItemListener() { 066 public void itemStateChanged(java.awt.event.ItemEvent e) { 067 NodeEditorConfig.CommandType type = (NodeEditorConfig.CommandType) typeCb.getSelectedItem(); 068 String proto = protoCb.getSelectedPrototype(); 069 if (type != null) { 070 protoCb.setConfig(type.getPrototypes()); 071 boolean showDbPanel = "sql".equalsIgnoreCase(type.getName()); 072 dbPanel.setVisible(showDbPanel); 073 if (showDbPanel) 074 gcDbGroup.load(); 075 parameterPanel.setVisible(type.isAcceptParameters()); 076 bshPanel.setVisible("bsh".equalsIgnoreCase(type.getName())); 077 } else { 078 protoCb.setConfig(null); 079 dbPanel.setVisible(false); 080 bshPanel.setVisible(false); 081 } 082 protoCb.setSelectedPrototype(proto); 083 }; 084 }; 085 ProtoListener pl = new ProtoListener() { 086 public void protoSelected(org.mactor.ui.gui.project.editors.NodeEditorConfig.CommandPrototype proto) { 087 parameterPanel.setExampleParamters(proto == null ? null : proto.getParams()); 088 }; 089 }; 090 public void setTipListener(TipListener tipListener) { 091 protoCb.setTipListener(tipListener); 092 typeCb.setTipListener(tipListener); 093 } 094 ApplyListener applyListener; 095 public CommandEditor(String commandCaption, ApplyListener applyListener) { 096 this.commandAttributeName = "command"; 097 this.applyListener = applyListener; 098 add(new JLabel(commandCaption)); 099 SimpleRowPanel panel = new SimpleRowPanel(); 100 panel.add(typeCb); 101 dbPanel.add(new JLabel(":")); 102 dbPanel.add(gcDbGroup); 103 panel.add(dbPanel); 104 panel.add(new JLabel(":")); 105 panel.add(protoCb); 106 panel.add(bshPanel); 107 panel.add(test); 108 add(panel); 109 add(parameterPanel); 110 typeCb.addItemListener(typeCbListener); 111 protoCb.setProtoListener(pl); 112 } 113 public void applyChanges() { 114 if (data.attribute(commandAttributeName) == null) 115 data.addAttribute(commandAttributeName, ""); 116 if (dbPanel.isVisible()) 117 data.attribute(commandAttributeName).setValue(typeCb.getSelectedType() + ":" + gcDbGroup.getSelectedGroup() + ":" + protoCb.getSelectedPrototype()); 118 else 119 data.attribute(commandAttributeName).setValue(typeCb.getSelectedType() + ":" + protoCb.getSelectedPrototype()); 120 parameterPanel.applyChanges(); 121 } 122 public void setData(Object data) throws MactorException { 123 this.data = (Element) data; 124 parameterPanel.setData(data); 125 String command = this.data.attributeValue(commandAttributeName); 126 String[] parts = null; 127 if (command != null) 128 parts = command.split(":"); 129 String type = null; 130 String group = null; 131 String proto = null; 132 if (parts != null) { 133 if (parts.length >= 1) 134 type = parts[0]; 135 if (parts.length > 2) { 136 proto = parts[2]; 137 group = parts[1]; 138 } else if (parts.length == 2) 139 proto = parts[1]; 140 } 141 typeCb.setSelectedType(type); 142 gcDbGroup.setSelectedGroup(group); 143 protoCb.setSelectedPrototype(proto); 144 if (!"sql".equalsIgnoreCase(type)) 145 dbPanel.setVisible(false); 146 } 147 public void setConfig(NodeEditorConfig config) { 148 typeCb.setConfig(config.getCommandTypes()); 149 } 150 private class ParamsPanel extends SimpleFormPanel { 151 List<RowPanel> rows = new LinkedList<RowPanel>(); 152 JButton addRowButton = new JButton("Add Parameter"); 153 JButton exampleParametersButton = new JButton("Load Example Parameters"); 154 Element rowsParentElement; 155 public ParamsPanel() { 156 add(new JLabel("Parameters:")); 157 addRowButton.addActionListener(new ActionListener() { 158 public void actionPerformed(ActionEvent arg0) { 159 applyChanges(); 160 rowsParentElement.addElement("param"); 161 setData(rowsParentElement); 162 applyListener.onApply(); 163 } 164 }); 165 exampleParametersButton.addActionListener(new ActionListener() { 166 public void actionPerformed(ActionEvent arg0) { 167 loadExampleParameters(); 168 } 169 }); 170 } 171 public void applyChanges() { 172 for (RowPanel row : rows) 173 row.applyChanges(); 174 } 175 public void removeRow(RowPanel row) { 176 remove(row); 177 rows.remove(row); 178 rowsParentElement.remove(row.rowElement); 179 applyChanges(); 180 revalidate(); 181 repaint(); 182 } 183 public void setConfig(NodeEditorConfig config) { 184 } 185 public void setData(Object data) { 186 rowsParentElement = (Element) data; 187 rows.clear(); 188 removeAll(); 189 add(new JLabel("Command Parameters:")); 190 Iterator it = rowsParentElement.elementIterator(); 191 while (it.hasNext()) { 192 RowPanel panel = new RowPanel((Element) it.next()); 193 rows.add(panel); 194 add(panel); 195 } 196 add(addRowButton); 197 add(exampleParametersButton); 198 revalidate(); 199 repaint(); 200 } 201 List<String> examleParameters; 202 public void setExampleParamters(List<String> examleParameters) { 203 this.examleParameters = examleParameters; 204 // exampleParametersButton.setEnabled(examleParameters!=null && 205 // examleParameters.size()>0); 206 } 207 private void loadExampleParameters() { 208 if (examleParameters == null) 209 examleParameters = Collections.emptyList(); 210 if (rowsParentElement != null) { 211 Iterator<Element> it = rowsParentElement.elementIterator("param"); 212 while (it.hasNext()) { 213 it.next().detach(); 214 } 215 for (String p : examleParameters) { 216 rowsParentElement.addElement("param").setText(p); 217 } 218 setData(rowsParentElement); 219 applyChanges(); 220 } 221 } 222 private class RowPanel extends SimpleRowPanel { 223 JTextField valueField = new JTextField(20); 224 JButton removeButton = new JButton("X"); 225 Element rowElement; 226 public RowPanel(Element rowElement) { 227 add(valueField); 228 add(removeButton); 229 this.rowElement = rowElement; 230 valueField.setText(rowElement.getText()); 231 removeButton.addActionListener(new ActionListener() { 232 public void actionPerformed(ActionEvent e) { 233 ParamsPanel.this.removeRow(RowPanel.this); 234 } 235 }); 236 } 237 public void applyChanges() { 238 rowElement.setText(valueField.getText()); 239 } 240 } 241 } 242 private class BshPanel extends SimpleRowPanel { 243 JButton bshEdit = new JButton(new AbstractAction("Edit...") { 244 public void actionPerformed(ActionEvent e) { 245 applyListener.onApply(); 246 String name = protoCb.getSelectedPrototype(); 247 if (name != null && name.length() > 0) { 248 File path = ProjectContext.getGlobalInstance().getAbsolutePath(name); 249 if (!path.exists()) { 250 if (JOptionPane.OK_OPTION != JOptionPane 251 .showConfirmDialog(BshPanel.this, "The script '" + name + "' does not exist. Create it?", "Create script", JOptionPane.OK_CANCEL_OPTION)) { 252 return; 253 } 254 } 255 new TextFileEditor( 256 name, 257 "Edit BeanShell Script", 258 "Tip: BeanShell is an object scripting language for Java. Read more at: http://www.beanshell.org\n\n Note that the TestContext (containing the local variables and the received messages etc.) is made available as a variable named 'context'") 259 .setVisible(true); 260 } 261 } 262 }); 263 JFileChooser fc = new JFileChooser(ProjectContext.getGlobalInstance().getProjectDir()); 264 JButton selectButton = new JButton(new AbstractAction("Select..") { 265 public void actionPerformed(ActionEvent e) { 266 applyListener.onApply(); 267 try { 268 if (protoCb.getSelectedPrototype() != null && protoCb.getSelectedPrototype().toLowerCase().endsWith(".bsh")) 269 fc.setSelectedFile(ProjectContext.getGlobalInstance().getAbsolutePath(protoCb.getSelectedPrototype())); 270 fc.setFileFilter(new FileFilter() { 271 @Override 272 public String getDescription() { 273 return "*.bsh"; 274 } 275 public boolean accept(File f) { 276 return !f.isDirectory() && f.getName().endsWith(".bsh"); 277 } 278 }); 279 int returnVal = fc.showOpenDialog(CommandEditor.this); 280 if (returnVal == JFileChooser.APPROVE_OPTION) { 281 File f = fc.getSelectedFile(); 282 if (!f.getName().toLowerCase().endsWith(".bsh")) 283 f = new File(f.getAbsolutePath() + ".bsh"); 284 f.createNewFile(); 285 protoCb.setSelectedPrototype(ProjectContext.getGlobalInstance().getRelativePath(f)); 286 } 287 } catch (IOException ioe) { 288 GuiUtil.showGuiError(CommandEditor.this, ioe); 289 } 290 } 291 }); 292 public BshPanel() { 293 add(selectButton); 294 add(bshEdit); 295 } 296 } 297 }