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 }