001package com.ganteater.ae.desktop.editor; 002 003import java.awt.BorderLayout; 004import java.awt.CardLayout; 005import java.awt.Color; 006import java.awt.Component; 007import java.awt.Desktop; 008import java.awt.Dimension; 009import java.awt.FileDialog; 010import java.awt.Font; 011import java.awt.Point; 012import java.awt.Toolkit; 013import java.awt.event.ActionEvent; 014import java.awt.event.ActionListener; 015import java.awt.event.KeyAdapter; 016import java.awt.event.KeyEvent; 017import java.awt.event.MouseAdapter; 018import java.awt.event.MouseEvent; 019import java.io.File; 020import java.io.FileOutputStream; 021import java.io.IOException; 022import java.lang.reflect.Constructor; 023import java.lang.reflect.InvocationTargetException; 024import java.util.ArrayList; 025import java.util.HashMap; 026import java.util.Map; 027import java.util.Properties; 028import java.util.Set; 029import java.util.Vector; 030 031import javax.swing.BorderFactory; 032import javax.swing.JButton; 033import javax.swing.JCheckBox; 034import javax.swing.JLabel; 035import javax.swing.JMenu; 036import javax.swing.JMenuBar; 037import javax.swing.JMenuItem; 038import javax.swing.JOptionPane; 039import javax.swing.JPanel; 040import javax.swing.JScrollPane; 041import javax.swing.JSeparator; 042import javax.swing.JSlider; 043import javax.swing.JSplitPane; 044import javax.swing.JTabbedPane; 045import javax.swing.JToolBar; 046import javax.swing.JTree; 047import javax.swing.JTree.DynamicUtilTreeNode; 048import javax.swing.KeyStroke; 049import javax.swing.SwingConstants; 050import javax.swing.SwingUtilities; 051import javax.swing.table.AbstractTableModel; 052import javax.swing.tree.DefaultMutableTreeNode; 053import javax.swing.tree.DefaultTreeModel; 054import javax.swing.tree.TreePath; 055import javax.swing.tree.TreeSelectionModel; 056 057import org.apache.commons.io.FilenameUtils; 058import org.apache.commons.lang.StringUtils; 059import org.apache.commons.lang.SystemUtils; 060import org.apache.commons.lang.exception.ExceptionUtils; 061 062import com.ganteater.ae.AEManager; 063import com.ganteater.ae.AEWorkspace; 064import com.ganteater.ae.CommandException; 065import com.ganteater.ae.ConfigurationException; 066import com.ganteater.ae.ILogger; 067import com.ganteater.ae.desktop.WorkPlace; 068import com.ganteater.ae.desktop.ui.AEFrame; 069import com.ganteater.ae.desktop.ui.AEPanel; 070import com.ganteater.ae.desktop.ui.DialogPopupMenu; 071import com.ganteater.ae.desktop.ui.TaskPanel; 072import com.ganteater.ae.desktop.view.ListLogPresenter; 073import com.ganteater.ae.desktop.view.LogPresenter; 074import com.ganteater.ae.desktop.view.PresentationPanel; 075import com.ganteater.ae.processor.BaseProcessor; 076import com.ganteater.ae.processor.Processor; 077import com.ganteater.ae.util.xml.easyparser.EasyParser; 078import com.ganteater.ae.util.xml.easyparser.EasyUtils; 079import com.ganteater.ae.util.xml.easyparser.Node; 080import com.ganteater.ae.util.xml.easyparser.Node.TreeVector; 081 082/** 083 * @author victort 084 * @version 1.0, 29-Jul-2005 085 */ 086public class TaskEditor extends WorkPlace implements AEPanel, AeEditPanel { 087 088 private static final String EDITOR_STD_PACKAGE = "com.ganteater.ae.desktop.editor."; 089 private static final String ABOUT = "About"; 090 private static final Color ACTIVE_COLOR = Color.GREEN.darker(); 091 private static final Font font = new Font("Monospaced", Font.PLAIN, 12); 092 093 private static final String TASK_EDITOR = "Editor"; 094 private static final String TASK_TREE = "Processing"; 095 096 private String fTaskFile; 097 private Vector<?> fTreeVector; 098 private Map<String, Object> fPresentationPanels = new HashMap<String, Object>(); 099 100 private AEFrame frame; 101 private JTree taskTree; 102 private TextEditor fTaskText = new TextEditor(); 103 private JTabbedPane fOutputTabbedPane; 104 private TaskPanel thePanel; 105 private JMenuItem fRunMenuItem = new JMenuItem("Run"); 106 private JMenuItem fContinueMenuItem = new JMenuItem("Continue"); 107 private JMenuItem fStopMenuItem = new JMenuItem("Stop"); 108 private JMenuItem fPauseMenuItem = new JMenuItem("Pause"); 109 private JButton fRunButton = new JButton("Run"); 110 private JCheckBox notifyMeCheckBox = new JCheckBox(); 111 private JMenuItem saveMenuItem; 112 private JSplitPane fOutputSplitPanel; 113 private JSlider speed = new JSlider(0, 100, 100); 114 private JTabbedPane createEditorPanel; 115 private JLabel changedLabel = new JLabel(""); 116 117 private JLabel lblTitle = new JLabel(); 118 private JTabbedPane tabbedPanel; 119 120 private boolean openIn; 121 122 private CodeHelper codeHelper = new CodeHelper(this, getLogger()); 123 124 public TaskEditor(AEFrame aFrame, Node aConfigNode, Map<String, Object> aSystemVariables) { 125 super(aFrame, aConfigNode, aSystemVariables); 126 this.frame = aFrame; 127 128 this.thePanel = new TaskPanel(this); 129 130 fOutputTabbedPane = new JTabbedPane(); 131 fOutputTabbedPane.setPreferredSize(new Dimension(200, 800)); 132 fOutputTabbedPane.addKeyListener(new KeyAdapter() { 133 @Override 134 public void keyReleased(KeyEvent e) { 135 if (e.getKeyCode() == KeyEvent.VK_F4 && e.isControlDown()) { 136 removeActivePresentationPanel(); 137 } 138 } 139 }); 140 141 fOutputTabbedPane.addMouseListener(new MouseAdapter() { 142 @Override 143 public void mouseClicked(MouseEvent e) { 144 JTabbedPane outputTabbedPane = (JTabbedPane) e.getSource(); 145 if (e.getButton() == MouseEvent.BUTTON2) { 146 if (outputTabbedPane.findComponentAt(e.getX(), e.getY()) == outputTabbedPane 147 && outputTabbedPane.indexAtLocation(e.getX(), e.getY()) != -1) { 148 149 Component selectedComponent = outputTabbedPane.getSelectedComponent(); 150 Object frameId = ((PresentationPanel) selectedComponent).getName(); 151 removeActivePresentationPanel(); 152 fPresentationPanels.remove(frameId); 153 } 154 } 155 if (e.getButton() == MouseEvent.BUTTON3) { 156 if (outputTabbedPane.findComponentAt(e.getX(), e.getY()) == outputTabbedPane 157 && outputTabbedPane.indexAtLocation(e.getX(), e.getY()) != -1) { 158 159 PresentationPanel selectedComponent = (PresentationPanel) outputTabbedPane 160 .getSelectedComponent(); 161 162 if (selectedComponent instanceof LogPresenter 163 && !((LogPresenter) selectedComponent).isEmpty()) { 164 if (fLoggers.contains(selectedComponent)) { 165 String frameId = selectedComponent.getName(); 166 LogPresenter findLogger = findLogger(frameId); 167 LogPresenter bakPresenter = findLogger.copyAndClean(); 168 outputTabbedPane.addTab(frameId, AEFrame.getIcon("copied.png"), bakPresenter); 169 } 170 } 171 } 172 } 173 } 174 }); 175 createEditorPanel = createEditorPanel(); 176 177 fOutputSplitPanel = new JSplitPane(JSplitPane.VERTICAL_SPLIT, createEditorPanel, fOutputTabbedPane); 178 fOutputSplitPanel.addPropertyChangeListener(JSplitPane.DIVIDER_LOCATION_PROPERTY, e -> { 179 int dividerLocation = fOutputSplitPanel.getDividerLocation(); 180 String divider = Integer.toString(dividerLocation); 181 int selectedIndex = createEditorPanel.getSelectedIndex(); 182 AEWorkspace.getInstance().setDefaultUserConfiguration("splitPanel.divider." + selectedIndex, divider); 183 }); 184 185 setSplitPanel(); 186 187 thePanel.add(fOutputSplitPanel, BorderLayout.CENTER); 188 JMenuBar menuBar = new JMenuBar(); 189 190 createFileMenu(menuBar); 191 createProcessMenu(menuBar); 192 193 Node taskNode = getTaskNode(); 194 if (taskNode != null && taskNode.findNode(ABOUT, null, null) != null) { 195 showAbout(); 196 } 197 198 JToolBar panel2 = new JToolBar(); 199 panel2.setBorderPainted(false); 200 panel2.setFloatable(false); 201 panel2.add(fRunButton); 202 notifyMeCheckBox.setIcon(AEFrame.getIcon("shout-off.png")); 203 notifyMeCheckBox.setSelectedIcon(AEFrame.getIcon("shout.png")); 204 panel2.add(notifyMeCheckBox); 205 206 notifyMeCheckBox.addActionListener(e -> { 207 if (getTaskName() != null) { 208 String aName = getTaskName() + ".notifyMe"; 209 String value = Boolean.toString(notifyMeCheckBox.isSelected()); 210 AEWorkspace.getInstance().setDefaultUserConfiguration(aName, value); 211 AEWorkspace.getInstance().setDefaultUserConfiguration("notifyMe", value); 212 } 213 }); 214 215 speed.setPreferredSize(new Dimension(30, 18)); 216 speed.setToolTipText("Action speed"); 217 218 speed.addChangeListener(e -> { 219 String text; 220 long traceDelay = getTraceDelay(); 221 if (traceDelay < 1000) { 222 text = traceDelay + "ms."; 223 } else { 224 text = String.format("%.2f", traceDelay / 1000.0) + "s"; 225 } 226 227 speed.setToolTipText("Delay: " + text); 228 fTitleTest.setText("Slow motion time: " + text); 229 }); 230 231 JPanel panel = new JPanel(new BorderLayout(4, 4)); 232 panel.setBorder(BorderFactory.createEtchedBorder()); 233 panel.add(menuBar, BorderLayout.WEST); 234 235 JButton closeBtn = new JButton(AEFrame.getIcon("close.png")); 236 closeBtn.addActionListener(e -> { 237 stopTest(); 238 closeTab(); 239 }); 240 panel.add(closeBtn, BorderLayout.EAST); 241 242 thePanel.add(panel, BorderLayout.NORTH); 243 244 JPanel aboutPanel = new JPanel(new BorderLayout(0, 0)); 245 aboutButtonPanel.setBorderPainted(false); 246 aboutButtonPanel.setFloatable(false); 247 aboutPanel.add(panel2, BorderLayout.WEST); 248 249 JPanel titlePanel = new JPanel(new BorderLayout(0, 0)); 250 titlePanel.add(aboutButtonPanel, BorderLayout.WEST); 251 titlePanel.add(fTitleTest, BorderLayout.CENTER); 252 aboutPanel.add(titlePanel, BorderLayout.CENTER); 253 panel.add(aboutPanel, BorderLayout.CENTER); 254 } 255 256 public void setSplitPanel() { 257 fOutputSplitPanel.setOneTouchExpandable(true); 258 } 259 260 private String getTaskName() { 261 String name = null; 262 if (getTaskNode() != null) { 263 name = getTaskNode().getAttribute("name"); 264 } 265 return name; 266 } 267 268 public TaskEditor(AEFrame aeFrame) { 269 this(aeFrame, aeFrame.getWorkspace().getConfigNode(), aeFrame.getWorkspace().getSystemVariables()); 270 setRunButtonAction(true); 271 } 272 273 private void createFileMenu(JMenuBar menuBar) { 274 JMenu menu = new JMenu("File"); 275 276 JMenuItem menuItem; 277 menuItem = new JMenuItem("Save"); 278 try { 279 menuItem.setAccelerator(KeyStroke.getKeyStroke('S', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 280 } catch (Exception e) { 281 } 282 283 this.saveMenuItem = menuItem; 284 menuItem.addActionListener(new ActionListener() { 285 public void actionPerformed(ActionEvent arg0) { 286 287 SwingUtilities.invokeLater(() -> { 288 try { 289 save(); 290 } catch (IOException e) { 291 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), 292 "Error: Unable to Save File: " + fTaskFile); 293 } 294 }); 295 } 296 }); 297 menu.add(menuItem); 298 299 menuItem = new JMenuItem("Reload"); 300 final JMenuItem reloadmenuItem = menuItem; 301 try { 302 menuItem.setAccelerator(KeyStroke.getKeyStroke('R', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 303 } catch (Exception e) { 304 } 305 menuItem.addActionListener(arg0 -> { 306 reload(); 307 }); 308 menu.add(menuItem); 309 310 menuItem = new JMenuItem("Format"); 311 try { 312 menuItem.setAccelerator(KeyStroke.getKeyStroke('F', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 313 } catch (Exception e) { 314 } 315 menuItem.addActionListener(arg0 -> { 316 format(); 317 }); 318 menu.add(menuItem); 319 320 menuItem = new JMenuItem("Open In"); 321 try { 322 menuItem.setAccelerator(KeyStroke.getKeyStroke('E', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 323 } catch (Exception e) { 324 } 325 menuItem.addActionListener(arg0 -> { 326 File file = new File(fTaskFile); 327 if (file.exists()) { 328 try { 329 Desktop.getDesktop().open(file); 330 openIn = true; 331 reloadmenuItem.setText("Reload [Before Run]"); 332 333 } catch (IOException e) { 334 getLogger().error(e.getMessage(), e); 335 } 336 } 337 }); 338 menu.add(menuItem); 339 340 menu.add(new JSeparator()); 341 menuItem = new JMenuItem("Close"); 342 try { 343 menuItem.setAccelerator(KeyStroke.getKeyStroke('X', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 344 } catch (Exception e) { 345 } 346 menuItem.addActionListener(e -> { 347 closeTab(); 348 }); 349 menu.add(menuItem); 350 menuBar.add(menu); 351 } 352 353 public void reload() { 354 openTaskFile(fTaskFile); 355 } 356 357 public void save() throws IOException { 358 changedLabel.setText(""); 359 format(); 360 saveTask(); 361 } 362 363 public void format() { 364 try { 365 compileTask(); 366 refreshTaskTree(); 367 368 Node taskNode = getTaskNode(); 369 applyText(taskNode); 370 371 if (taskNode != null && taskNode.findNode(ABOUT, null, null) != null) { 372 showAbout(); 373 } 374 375 } catch (Exception e) { 376 getLogger().error("Save action failed.", e); 377 } 378 } 379 380 private void createProcessMenu(JMenuBar menuBar) { 381 JMenu menu = new JMenu("Process"); 382 383 JMenuItem compileMenuItem = new JMenuItem("Compile"); 384 menu.add(compileMenuItem); 385 compileMenuItem.addActionListener(arg0 -> { 386 try { 387 compileTask(); 388 } catch (Exception e) { 389 getLogger().error("Compilation failed.", e); 390 } 391 }); 392 393 menu.add(fRunMenuItem); 394 395 try { 396 fRunMenuItem.setAccelerator( 397 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 398 } catch (Exception e) { 399 } 400 401 fRunMenuItem.addActionListener(e -> { 402 runTask(); 403 }); 404 menu.add(speed); 405 406 fRunButton.addActionListener(e -> { 407 boolean isCurrentRunAction = "Run".equals(e.getActionCommand()); 408 409 if (isCurrentRunAction) { 410 runTask(); 411 } else { 412 stopTest(); 413 if (getTaskProcessor().isStoppedTest()) { 414 setRunButtonAction(true); 415 } 416 } 417 }); 418 419 menu.add(fPauseMenuItem); 420 421 try { 422 fPauseMenuItem 423 .setAccelerator(KeyStroke.getKeyStroke('P', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 424 } catch (Exception e) { 425 } 426 427 fPauseMenuItem.addActionListener(e -> { 428 getTaskProcessor().pause(); 429 }); 430 431 menu.add(fContinueMenuItem); 432 433 try { 434 fContinueMenuItem 435 .setAccelerator(KeyStroke.getKeyStroke('P', Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 436 } catch (Exception e) { 437 } 438 439 fContinueMenuItem.addActionListener(arg0 -> getTaskProcessor().resume()); 440 441 try { 442 fStopMenuItem.setAccelerator( 443 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); 444 } catch (Exception e) { 445 } 446 447 fStopMenuItem.addActionListener(arg0 -> stopTask()); 448 menu.add(fStopMenuItem); 449 menuBar.add(menu); 450 } 451 452 @Override 453 public void setProgress(String message, long aMaxTags, long aCurrTags, boolean aErrorState) { 454 manager.progressValue((int) (((double) aCurrTags / aMaxTags) * 100), 100, true); 455 fTitleTest.setText(message); 456 } 457 458 public void stopTask() { 459 super.stopTest(); 460 } 461 462 private JTabbedPane createEditorPanel() { 463 JTabbedPane editorPanel = new JTabbedPane(); 464 editorPanel.setTabPlacement(SwingConstants.BOTTOM); 465 466 JScrollPane scrollPane = new JScrollPane(); 467 scrollPane.getViewport().add(fTaskText); 468 469 fTaskText.addKeyListener(codeHelper); 470 fTaskText.addMouseListener(codeHelper); 471 472 fTaskText.setEditable(true); 473 fTaskText.addKeyListener(new KeyAdapter() { 474 @Override 475 public void keyPressed(KeyEvent e) { 476 if (!(e.isControlDown() 477 && (e.getKeyCode() == 17 || e.getKeyChar() == 0 || e.getKeyCode() == KeyEvent.VK_C))) { 478 changedLabel.setText("*"); 479 } 480 } 481 }); 482 483 fTaskText.setFont(font); 484 485 JScrollPane theScroll = new JScrollPane(); 486 theScroll.getViewport().removeAll(); 487 taskTree = new JTree(); 488 taskTree.setRootVisible(false); 489 taskTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 490 491 taskTree.addMouseListener(new MouseAdapter() { 492 @Override 493 public void mousePressed(MouseEvent e) { 494 if (e.getClickCount() == 2) { 495 DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) taskTree 496 .getLastSelectedPathComponent(); 497 TreeVector userObject = (TreeVector) selectedNode.getUserObject(); 498 Node node = userObject.getNode(); 499 500 String tagName = node.getTag(); 501 if ("Task".equals(tagName)) { 502 String name = node.getAttribute("name"); 503 TaskEditor editTask = getAeFrame().editTask(name); 504 editTask.setRunButtonAction(true); 505 } 506 } 507 } 508 }); 509 510 theScroll.getViewport().add(taskTree); 511 512 editorPanel.addTab(TASK_TREE, theScroll); 513 editorPanel.addTab(TASK_EDITOR, scrollPane); 514 515 editorPanel.addChangeListener(e -> { 516 517 int selectedIndex = editorPanel.getSelectedIndex(); 518 String divider = AEWorkspace.getInstance() 519 .getDefaultUserConfiguration("splitPanel.divider." + selectedIndex, null); 520 if (divider != null) { 521 fOutputSplitPanel.setDividerLocation(Integer.parseInt(divider)); 522 } 523 524 Component selectedComponent = editorPanel.getSelectedComponent(); 525 if (selectedComponent instanceof VariableViewPanel) { 526 VariableViewPanel panel = (VariableViewPanel) selectedComponent; 527 panel.refreshData(); 528 } 529 }); 530 531 return editorPanel; 532 } 533 534 public void compileTask() { 535 try { 536 Node object = new EasyParser().getObject(fTaskText.getText()); 537 setTaskNode(object); 538 539 } catch (Exception e1) { 540 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), "Incorrect code!\nError: " + e1.getMessage()); 541 throw e1; 542 } 543 } 544 545 public void showPanel(JTabbedPane panel, String name) { 546 if (name == null) { 547 name = getPanelName(); 548 } 549 tabbedPanel = panel; 550 String tabNameId = Integer.toString(thePanel.hashCode()); 551 panel.addTab(tabNameId, thePanel); 552 panel.setSelectedComponent(thePanel); 553 554 JPanel pnlTab = new JPanel(new BorderLayout()); 555 pnlTab.setOpaque(false); 556 pnlTab.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0)); 557 558 setTitle(name); 559 lblTitle.addMouseListener(new MouseAdapter() { 560 @Override 561 public void mouseClicked(MouseEvent var1) { 562 int index = tabbedPanel.indexOfTab(tabNameId); 563 int button = var1.getButton(); 564 if (button == MouseEvent.BUTTON2) { 565 TaskEditor.this.frame.removeTab(TaskEditor.this); 566 } else { 567 tabbedPanel.setSelectedIndex(index); 568 } 569 } 570 }); 571 572 pnlTab.add(lblTitle, BorderLayout.CENTER); 573 pnlTab.add(changedLabel, BorderLayout.EAST); 574 575 int index = tabbedPanel.indexOfTab(tabNameId); 576 tabbedPanel.setTabComponentAt(index, pnlTab); 577 } 578 579 private void setTitle(String name) { 580 lblTitle.setText(StringUtils.abbreviate(name, 12)); 581 lblTitle.setToolTipText(name); 582 } 583 584 public JPanel getMainPanel() { 585 return thePanel; 586 } 587 588 @Override 589 public void endTask(boolean aErrorState) { 590 super.endTask(aErrorState); 591 fRunMenuItem.setEnabled(true); 592 setRunButtonAction(true); 593 } 594 595 private void openTaskFile(String filePath) { 596 fTaskFile = filePath; 597 if (new File(fTaskFile).exists() && !openIn) { 598 setEditable(true); 599 } 600 601 try { 602 Node node = new EasyParser().load(filePath); 603 applyText(node); 604 changedLabel.setText(""); 605 } catch (Exception e1) { 606 throw new ConfigurationException("Invalide recipe file.", e1); 607 } 608 609 } 610 611 private void applyText(Node node) { 612 setTaskNode(node); 613 int caretPosition = fTaskText.getCaretPosition(); 614 EasyUtils.removeTagId(node); 615 616 fTaskText.setOriginalText(node.getXMLText()); 617 if (caretPosition < fTaskText.getDocument().getLength()) { 618 fTaskText.setCaretPosition(caretPosition); 619 } 620 refreshTaskTree(); 621 } 622 623 private void addExternTabs() { 624 Node taskNode = getConfigNode(); 625 if (taskNode != null) { 626 Node[] editors = taskNode.getNodes(TASK_EDITOR); 627 createEditors(editors); 628 } 629 630 taskNode = getTaskNode(); 631 if (taskNode != null) { 632 Node[] editors = taskNode.getNodes(TASK_EDITOR); 633 createEditors(editors); 634 } 635 } 636 637 private void createEditors(Node[] editors) { 638 for (Node editorNode : editors) { 639 String className = editorNode.getAttribute("class"); 640 if (className != null) { 641 Class<?> filterClass; 642 try { 643 if (!className.startsWith(EDITOR_STD_PACKAGE)) { 644 className = EDITOR_STD_PACKAGE + className; 645 } 646 647 filterClass = Class.forName(className); 648 Constructor<?> constructor = filterClass.getConstructor(); 649 650 String name = editorNode.getAttribute("name"); 651 String tabName = StringUtils.defaultIfEmpty(name, StringUtils.substringAfterLast(className, ".")); 652 653 JPanel editor = (JPanel) constructor.newInstance(); 654 if (editor instanceof Editor) { 655 ((Editor) editor).init(this, editorNode); 656 } 657 createEditorPanel.addTab(tabName, editor); 658 659 } catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException 660 | IllegalAccessException | IllegalArgumentException | InvocationTargetException 661 | CommandException e) { 662 e.printStackTrace(); 663 JOptionPane.showMessageDialog(JOptionPane.getRootFrame(), 664 "The creation of the extended panel failed.\nError: " 665 + ExceptionUtils.getRootCauseMessage(e)); 666 } 667 } 668 } 669 } 670 671 private void setEditable(boolean editable) { 672 saveMenuItem.setEnabled(editable); 673 fTaskText.setEditable(editable); 674 } 675 676 protected void refreshTaskTree() { 677 if (getTaskNode() != null) { 678 fTreeVector = getTaskNode().getVector(true); 679 680 DefaultMutableTreeNode root = new DefaultMutableTreeNode("root"); 681 DynamicUtilTreeNode.createChildren(root, fTreeVector); 682 DefaultTreeModel model = new DefaultTreeModel(root, false); 683 taskTree.setModel(model); 684 685 taskTree.setEditable(false); 686 taskTree.setEnabled(true); 687 688 taskTree.setFont(font); 689 taskTree.setForeground(ACTIVE_COLOR); 690 for (int i = 0; i < taskTree.getRowCount(); i++) { 691 taskTree.expandRow(i); 692 } 693 } 694 } 695 696 @Override 697 public void changeVariable(String aAttribut, Object aValue) { 698 } 699 700 static class JBorderedPanel extends JPanel { 701 private static final long serialVersionUID = 1L; 702 703 public JBorderedPanel(Component aNorth, Component aWest, Component aCenter, Component aEast, Component aSouth) { 704 setLayout(new BorderLayout()); 705 if (aNorth != null) { 706 add(aNorth, BorderLayout.NORTH); 707 } 708 if (aWest != null) { 709 add(aWest, BorderLayout.WEST); 710 } 711 if (aCenter != null) { 712 add(aCenter, BorderLayout.CENTER); 713 } 714 if (aEast != null) { 715 add(aEast, BorderLayout.EAST); 716 } 717 if (aSouth != null) { 718 add(aSouth, BorderLayout.SOUTH); 719 } 720 } 721 } 722 723 @Override 724 public void startCommand(int aNumberCommand) { 725 setRunButtonAction(false); 726 try { 727 if (taskTree != null) { 728 taskTree.setSelectionRow(aNumberCommand); 729 long delay = getTraceDelay(); 730 if (delay > 0) { 731 try { 732 Thread.sleep(delay); 733 } catch (Exception e) { 734 Thread.currentThread().interrupt(); 735 } 736 } 737 } 738 } catch (Exception e) { 739 // 740 } 741 } 742 743 private long getTraceDelay() { 744 return (int) ((Math.pow(1.5, (double) (100 - speed.getValue()) / 4)) - 1); 745 } 746 747 @Override 748 public void aboutTest(String theTaskName, Node aCurrentAction) { 749 try { 750 setAbout(theTaskName, aCurrentAction); 751 aboutButtonPanel.setVisible(true); 752 } catch (Exception e) { 753 getLogger().error("Error", e); 754 } 755 } 756 757 @Override 758 public void runCommandFrame(Properties params) { 759 String theFrameId = params.getProperty("frameId"); 760 String title = params.getProperty("title"); 761 762 String reuse = params.getProperty("reuse"); 763 if ("true".equals(reuse)) { 764 PresentationPanel thePPanel = (PresentationPanel) fPresentationPanels.get(theFrameId); 765 if (thePPanel != null && thePPanel.isValid()) { 766 return; 767 } 768 } 769 770 createFrame(theFrameId, params, title); 771 } 772 773 private PresentationPanel createFrame(String theFrameId, Properties linkedMap, String title) { 774 775 if (title == null) { 776 title = theFrameId; 777 } 778 779 String className = linkedMap.getProperty("type", "TextPanel"); 780 781 if (className.indexOf('.') < 0) { 782 className = "com.ganteater.ae.desktop.view." + className; 783 } 784 785 Class<?> ppClass; 786 try { 787 ppClass = Class.forName(className); 788 Constructor<?> constructor = ppClass.getConstructor(Properties.class, AEManager.class); 789 PresentationPanel pPanel = (PresentationPanel) constructor.newInstance(linkedMap, manager); 790 791 fPresentationPanels.put(theFrameId, pPanel); 792 fOutputTabbedPane.add(title, pPanel); 793 794 fOutputTabbedPane.setSelectedComponent(pPanel); 795 return pPanel; 796 797 } catch (Exception e) { 798 throw new IllegalArgumentException(e); 799 } 800 } 801 802 @Override 803 public void outToFrame(Processor processor, Properties properties, Object value) { 804 String frameId = processor.replaceProperties((String) properties.get("frameId")); 805 if (frameId != null) { 806 PresentationPanel panel = (PresentationPanel) fPresentationPanels.get(frameId); 807 if (panel != null) { 808 Properties params = panel.getParams(); 809 810 if (fOutputTabbedPane.getComponentZOrder(panel) < 0) { 811 fPresentationPanels.remove(frameId); 812 panel = null; 813 } 814 815 if (panel == null) { 816 createFrame(frameId, params, null); 817 } else { 818 panel.out(value, properties); 819 } 820 } 821 } 822 } 823 824 public void removeActivePresentationPanel() { 825 int selectedIndex = fOutputTabbedPane.getSelectedIndex(); 826 827 Component theComp = fOutputTabbedPane.getComponent(selectedIndex); 828 if (theComp instanceof PresentationPanel) { 829 PresentationPanel thePPanel = (PresentationPanel) theComp; 830 fPresentationPanels.remove(thePPanel.getName()); 831 } 832 833 fOutputTabbedPane.remove(selectedIndex); 834 fLoggers.remove(findLogger(theComp)); 835 } 836 837 int fNumberLog = 1; 838 839 private ArrayList<LogPresenter> fLoggers = new ArrayList<LogPresenter>(); 840 private boolean isRunning; 841 842 public ILogger createLog(String aLogName, boolean mainLog) { 843 844 LogPresenter loggPanel = findLogger(aLogName); 845 846 if (loggPanel == null) { 847 if (aLogName == null || aLogName.length() == 0) 848 aLogName = "Log #" + String.valueOf(fNumberLog++); 849 loggPanel = new ListLogPresenter(this, aLogName, mainLog); 850 outputPaneAdd(loggPanel); 851 } 852 853 setLog(loggPanel); 854 return loggPanel; 855 } 856 857 public void setLog(ILogger log) { 858 super.setLog(log); 859 codeHelper.setLog(log); 860 } 861 862 private LogPresenter findLogger(String aLogName) { 863 if (aLogName == null && fLoggers.size() > 0) { 864 return fLoggers.get(0); 865 } 866 867 int tabCount = fLoggers.size(); 868 for (int i = 0; i < tabCount; i++) { 869 LogPresenter logger = (LogPresenter) fLoggers.get(i); 870 if (logger.getName().equals(aLogName)) { 871 return logger; 872 } 873 } 874 875 return null; 876 } 877 878 private LogPresenter findLogger(Component comp) { 879 int tabCount = fLoggers.size(); 880 for (int i = 0; i < tabCount; i++) { 881 LogPresenter logger = (LogPresenter) fLoggers.get(i); 882 if (logger == comp) { 883 return logger; 884 } 885 } 886 return null; 887 } 888 889 @Override 890 public void errorInformation(Processor processor, Throwable exception, Node command) throws CommandException { 891 try { 892 frame.errorInformation(processor, exception, command, notifyMeCheckBox.isSelected()); 893 } catch (CommandException e) { 894 throw e; 895 } catch (Throwable e) { 896 throw new CommandException(e, processor, command); 897 } 898 } 899 900 class VarTableModel extends AbstractTableModel { 901 private static final long serialVersionUID = 1L; 902 private String[][] fRows; 903 904 public VarTableModel() throws Exception { 905 Set<String> enumeration = getSystemVariables().keySet(); 906 fRows = new String[getSystemVariables().size()][2]; 907 int i = 0; 908 for (String theName : enumeration) { 909 String theValue = (String) getSystemVariables().get(theName); 910 fRows[i][0] = theName; 911 fRows[i][1] = theValue; 912 i++; 913 } 914 } 915 916 public int getColumnCount() { 917 return 2; 918 } 919 920 public int getRowCount() { 921 return getSystemVariables().size(); 922 } 923 924 public Class<String> getColumnClass(int columnIndex) { 925 return String.class; 926 } 927 928 public Object getValueAt(int row, int col) { 929 return fRows[row][col]; 930 } 931 932 public boolean isCellEditable(int rowIndex, int columnIndex) { 933 return columnIndex > 0; 934 } 935 936 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 937 if (columnIndex == 1) { 938 getSystemVariables().put(fRows[rowIndex][0], aValue); 939 fRows[rowIndex][1] = (String) aValue; 940 } 941 } 942 943 public String getColumnName(int column) { 944 if (column == 0) { 945 return "Name"; 946 } else { 947 return "Value"; 948 } 949 } 950 951 } 952 953 public void outputPaneAdd(LogPresenter logPanel) { 954 fLoggers.add(logPanel); 955 LogPresenter panel = logPanel; 956 fOutputTabbedPane.add(logPanel.getName(), panel); 957 fPresentationPanels.put(logPanel.getName(), logPanel); 958 fOutputTabbedPane.setSelectedComponent(panel); 959 } 960 961 @Override 962 public void setActiveTest(String theActiveTest) { 963 String fileName = manager.getTestPath(theActiveTest); 964 if (fileName == null) { 965 throw new IllegalArgumentException("Task file is not found. Recipe: " + theActiveTest); 966 } 967 968 setActiveTestFile(fileName); 969 970 addExternTabs(); 971 } 972 973 private void setActiveTestFile(String fileName) { 974 openTaskFile(fileName); 975 recipeFilePath = fileName; 976 977 boolean editable = new File(fTaskFile).exists(); 978 saveMenuItem.setEnabled(editable); 979 fTaskText.setEditable(editable); 980 981 Node taskNode = getTaskNode(); 982 boolean c = taskNode != null && taskNode.findNode(ABOUT, null, null) != null; 983 if (c) { 984 showAbout(); 985 } 986 } 987 988 public void runTaskNode() { 989 990 Thread thread = new Thread() { 991 public void run() { 992 try { 993 Processor processor; 994 995 File parentFile = SystemUtils.getUserDir(); 996 if (fTaskFile != null) { 997 parentFile = new File(fTaskFile).getParentFile(); 998 } 999 1000 String selectedText = fTaskText.getSelectedText(); 1001 1002 Node taskNode; 1003 Map<String, Object> hashtable; 1004 if (selectedText == null) { 1005 compileTask(); 1006 taskNode = getTaskNode(); 1007 processor = createProcessor(); 1008 hashtable = processor.startVariables; 1009 } else { 1010 String code = fTaskText.getText(0, fTaskText.getSelectionStart()); 1011 code = StringUtils.substringAfterLast(code, "<Extern "); 1012 if (!StringUtils.isEmpty(code)) { 1013 code = "<Extern " + code; 1014 selectedText = StringUtils.substringBefore(code, ">") + ">" + selectedText + "</Extern>"; 1015 } 1016 1017 code = "<Task>" + selectedText + "</Task>"; 1018 1019 taskNode = new EasyParser().getObject(code); 1020 setRunButtonAction(false); 1021 1022 processor = getTaskProcessor(); 1023 hashtable = processor.getVariables(); 1024 } 1025 taskNode.getVector(true); 1026 1027 processor.processTesting(taskNode, hashtable, parentFile); 1028 processor.getListener().endTask(false); 1029 endTask(false); 1030 setRunButtonAction(true); 1031 1032 } catch (Exception e) { 1033 e.printStackTrace(); 1034 } 1035 } 1036 1037 }; 1038 1039 thread.start(); 1040 } 1041 1042 private void runProcessTreeLine() { 1043 TreePath[] selectedPaths = taskTree.getSelectionPaths(); 1044 if (createEditorPanel.getSelectedIndex() == 0 && selectedPaths != null) { 1045 Processor processor = getTaskProcessor(); 1046 Node taskNode = new Node("Task"); 1047 setRunButtonAction(false); 1048 for (TreePath path : selectedPaths) { 1049 DefaultMutableTreeNode lastPathComponent = (DefaultMutableTreeNode) path.getLastPathComponent(); 1050 TreeVector userObject = (TreeVector) lastPathComponent.getUserObject(); 1051 Node node = userObject.getNode(); 1052 if ("Recipe".equals(node.getTag())) { 1053 taskNode = node; 1054 processor = createProcessor(); 1055 Map<String, Object> hashtable = processor.startVariables; 1056 } else { 1057 taskNode.add(node); 1058 processor = getTaskProcessor(); 1059 } 1060 } 1061 } 1062 } 1063 1064 private Processor createProcessor() { 1065 String attribute = getTaskNode().getAttribute("name"); 1066 if (attribute == null || attribute.isEmpty()) 1067 attribute = getTaskNode().getAttribute("description"); 1068 1069 ILogger createLog = createLog(attribute, true); 1070 setProcessor(null); 1071 Processor processor = new BaseProcessor(getManager(), createLog, getManager().getStartDir()); 1072 processor.init(fConfigNode, getSystemVariables(), this, getManager().getStartDir(), createLog); 1073 processor.setTestListener(this); 1074 1075 setProcessor(processor); 1076 return processor; 1077 } 1078 1079 public void start(String name) { 1080 if (StringUtils.isNotBlank(name)) { 1081 setActiveTest(name); 1082 runTaskNode(); 1083 } 1084 fRunMenuItem.setEnabled(false); 1085 } 1086 1087 public void setRunButtonAction(boolean runAction) { 1088 this.isRunning = !runAction; 1089 if (runAction) { 1090 try { 1091 fRunButton.setText("Run"); 1092 fRunButton.setToolTipText("Run"); 1093 fContinueMenuItem.setEnabled(false); 1094 fRunMenuItem.setEnabled(true); 1095 fStopMenuItem.setEnabled(false); 1096 fPauseMenuItem.setEnabled(false); 1097 lblTitle.setBorder(BorderFactory.createEmptyBorder()); 1098 } catch (Exception e) { 1099 e.printStackTrace(); 1100 } 1101 1102 } else { 1103 try { 1104 fRunButton.setText("Stop"); 1105 fRunButton.setToolTipText("Stop"); 1106 fContinueMenuItem.setEnabled(false); 1107 fRunMenuItem.setEnabled(false); 1108 fStopMenuItem.setEnabled(true); 1109 fPauseMenuItem.setEnabled(true); 1110 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, ACTIVE_COLOR)); 1111 } catch (Exception e) { 1112 e.printStackTrace(); 1113 } 1114 } 1115 } 1116 1117 public void edit(String name) { 1118 ListLogPresenter log = new ListLogPresenter(this, name); 1119 setLog(log); 1120 outputPaneAdd(log); 1121 fRunMenuItem.setEnabled(true); 1122 } 1123 1124 public void create(String name) { 1125 ListLogPresenter log = new ListLogPresenter(this, name); 1126 setLog(log); 1127 1128 fRunMenuItem.setEnabled(true); 1129 Node node = new EasyParser().getObject("<Recipe name=\"" + name + "\">\n<!-- your recipe code -->\n</Recipe>"); 1130 applyText(node); 1131 1132 runTest(new Node[] { node }); 1133 fContinueMenuItem.setEnabled(false); 1134 } 1135 1136 public String getPanelName() { 1137 Processor processor = getTaskProcessor(); 1138 return processor.getTestName(); 1139 } 1140 1141 public void saveTask() throws IOException { 1142 String recipeName = getTaskNode().getAttribute("name"); 1143 if (fTaskFile == null || !fTaskFile.startsWith("jar:")) { 1144 1145 if (fTaskFile == null) { 1146 FileDialog theFileDialog = new FileDialog(JOptionPane.getRootFrame(), "Save Recipe File", 1147 FileDialog.SAVE); 1148 if (getTaskNode() != null) { 1149 theFileDialog.setFile(recipeName + ".recipe"); 1150 } 1151 theFileDialog.setVisible(true); 1152 if (theFileDialog.getFile() == null) 1153 return; 1154 fTaskFile = new File(theFileDialog.getDirectory() + theFileDialog.getFile()).getAbsolutePath(); 1155 } 1156 1157 if (getTaskNode() != null) { 1158 File file = new File(fTaskFile); 1159 String name = FilenameUtils.getBaseName(file.getName()); 1160 String oldName = getTaskNode().getAttribute("name"); 1161 if (!StringUtils.equals(name, oldName)) { 1162 File newfile = new File(file.getParent(), oldName + ".recipe"); 1163 if (file.renameTo(newfile)) { 1164 file = newfile; 1165 fTaskFile = file.getAbsolutePath(); 1166 } 1167 } 1168 1169 Node theNode = (Node) getTaskNode().clone(); 1170 String newName = theNode.getAttribute("name"); 1171 1172 AEWorkspace workspace = frame.getWorkspace(); 1173 workspace.removeTestPath(oldName); 1174 workspace.setTestPath(newName, fTaskFile); 1175 1176 EasyUtils.removeTagId(theNode); 1177 1178 byte[] bytes = getTaskNode().getXMLText().getBytes("UTF-8"); 1179 1180 try (FileOutputStream theFileOutputStream = new FileOutputStream(fTaskFile)) { 1181 theFileOutputStream.write(bytes); 1182 } 1183 1184 setTitle(recipeName); 1185 } 1186 } 1187 } 1188 1189 public void runTask() { 1190 try { 1191 final String selectedText = fTaskText.getSelectedText(); 1192 1193 if (openIn && selectedText == null) { 1194 reload(); 1195 } 1196 1197 getManager().startTaskNotify(this); 1198 runTaskNode(); 1199 1200 } catch (Exception e) { 1201 getLogger().error("Running failed.", e); 1202 } 1203 } 1204 1205 @Override 1206 public void criticalError(final CommandException exception, final Processor processor) { 1207 frame.criticalError(TaskEditor.this); 1208 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.RED)); 1209 1210 if (isNotifyMe()) { 1211 getFrame().fireBuzzAction(() -> super.criticalError(exception, processor)); 1212 } else { 1213 super.criticalError(exception, processor); 1214 } 1215 } 1216 1217 @Override 1218 public void checkFailure(final CommandException exception, final Processor processor) { 1219 frame.checkFailure(TaskEditor.this); 1220 1221 if (isNotifyMe()) { 1222 getFrame().fireBuzzAction(() -> super.checkFailure(exception, processor)); 1223 } else { 1224 super.checkFailure(exception, processor); 1225 } 1226 } 1227 1228 public void closeTab() { 1229 frame.removeTab(TaskEditor.this); 1230 } 1231 1232 public void showAbout() { 1233 Node taskNode = getTaskNode(); 1234 aboutTest(taskNode.getAttribute("name"), taskNode.findNode(ABOUT, null, null)); 1235 } 1236 1237 public void showTaskTreePane() { 1238 CardLayout cl = (CardLayout) (createEditorPanel.getLayout()); 1239 cl.show(createEditorPanel, TASK_TREE); 1240 } 1241 1242 public int getCaretPosition() { 1243 return fTaskText.getCaretPosition(); 1244 } 1245 1246 public Point getMagicCaretPosition() { 1247 return fTaskText.getCaret().getMagicCaretPosition(); 1248 } 1249 1250 public String getText() { 1251 return fTaskText.getText(); 1252 } 1253 1254 public void replaceRange(String text, int i, int caretPosition2) { 1255 fTaskText.replaceRange(text, i, caretPosition2); 1256 } 1257 1258 public DialogPopupMenu contextHelp(DialogPopupMenu menu) { 1259 return menu; 1260 } 1261 1262 @Override 1263 public void runTest(Node testNode[]) { 1264 Node object = testNode[0]; 1265 object.getVector(true); 1266 setTaskNode(object); 1267 refreshTaskTree(); 1268 runTaskNode(); 1269 } 1270 1271 public AEFrame getFrame() { 1272 return frame; 1273 } 1274 1275 public void pause() { 1276 fRunMenuItem.setEnabled(false); 1277 fContinueMenuItem.setEnabled(true); 1278 fPauseMenuItem.setEnabled(false); 1279 1280 fTitleTest.setText(" Suspended execution ..."); 1281 fTitleTest.setForeground(Color.YELLOW.darker()); 1282 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.YELLOW)); 1283 } 1284 1285 @Override 1286 public void resume() { 1287 fRunMenuItem.setEnabled(false); 1288 fContinueMenuItem.setEnabled(false); 1289 fPauseMenuItem.setEnabled(true); 1290 1291 fTitleTest.setText(""); 1292 fTitleTest.setForeground(Color.GRAY.darker()); 1293 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, ACTIVE_COLOR)); 1294 } 1295 1296 public boolean isRunning() { 1297 return isRunning; 1298 } 1299 1300 public TextEditor getEditor() { 1301 return fTaskText; 1302 } 1303 1304 public void select() { 1305 getFrame().setSelectedComponent(getMainPanel()); 1306 } 1307 1308 @Override 1309 public void setTaskNode(Node taskNode) { 1310 super.setTaskNode(taskNode); 1311 String aName = getTaskName() + ".notifyMe"; 1312 String defaultNotify = AEWorkspace.getInstance().getDefaultUserConfiguration("notifyMe", "true"); 1313 boolean notify = Boolean 1314 .parseBoolean(AEWorkspace.getInstance().getDefaultUserConfiguration(aName, defaultNotify)); 1315 notifyMeCheckBox.setSelected(notify); 1316 } 1317 1318 public boolean isNotifyMe() { 1319 return notifyMeCheckBox.isSelected(); 1320 } 1321 1322}