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 (StringUtils.isBlank(selectedText)) { 1005 compileTask(); 1006 taskNode = getTaskNode(); 1007 processor = createProcessor(); 1008 hashtable = processor.startVariables; 1009 1010 } else { 1011 String code = fTaskText.getText(0, fTaskText.getSelectionStart()); 1012 code = StringUtils.substringAfterLast(code, "<Extern "); 1013 if (!StringUtils.isEmpty(code)) { 1014 code = "<Extern " + code; 1015 selectedText = StringUtils.substringBefore(code, ">") + ">" + selectedText + "</Extern>"; 1016 } 1017 1018 code = "<Task>" + selectedText + "</Task>"; 1019 1020 taskNode = new EasyParser().getObject(code); 1021 setRunButtonAction(false); 1022 1023 processor = getTaskProcessor(); 1024 hashtable = processor.getVariables(); 1025 } 1026 taskNode.getVector(true); 1027 1028 processor.processTesting(taskNode, hashtable, parentFile); 1029 processor.getListener().endTask(false); 1030 endTask(false); 1031 setRunButtonAction(true); 1032 1033 } catch (Exception e) { 1034 e.printStackTrace(); 1035 } 1036 } 1037 1038 }; 1039 1040 thread.start(); 1041 } 1042 1043 private void runProcessTreeLine() { 1044 TreePath[] selectedPaths = taskTree.getSelectionPaths(); 1045 if (createEditorPanel.getSelectedIndex() == 0 && selectedPaths != null) { 1046 Processor processor = getTaskProcessor(); 1047 Node taskNode = new Node("Task"); 1048 setRunButtonAction(false); 1049 for (TreePath path : selectedPaths) { 1050 DefaultMutableTreeNode lastPathComponent = (DefaultMutableTreeNode) path.getLastPathComponent(); 1051 TreeVector userObject = (TreeVector) lastPathComponent.getUserObject(); 1052 Node node = userObject.getNode(); 1053 if ("Recipe".equals(node.getTag())) { 1054 taskNode = node; 1055 processor = createProcessor(); 1056 Map<String, Object> hashtable = processor.startVariables; 1057 } else { 1058 taskNode.add(node); 1059 processor = getTaskProcessor(); 1060 } 1061 } 1062 } 1063 } 1064 1065 private Processor createProcessor() { 1066 String attribute = getTaskNode().getAttribute("name"); 1067 if (attribute == null || attribute.isEmpty()) 1068 attribute = getTaskNode().getAttribute("description"); 1069 1070 ILogger createLog = createLog(attribute, true); 1071 setProcessor(null); 1072 Processor processor = new BaseProcessor(getManager(), createLog, getManager().getStartDir()); 1073 processor.init(fConfigNode, getSystemVariables(), this, getManager().getStartDir(), createLog); 1074 processor.setTestListener(this); 1075 1076 setProcessor(processor); 1077 return processor; 1078 } 1079 1080 public void start(String name) { 1081 if (StringUtils.isNotBlank(name)) { 1082 setActiveTest(name); 1083 runTaskNode(); 1084 } 1085 fRunMenuItem.setEnabled(false); 1086 } 1087 1088 public void setRunButtonAction(boolean runAction) { 1089 this.isRunning = !runAction; 1090 if (runAction) { 1091 try { 1092 fRunButton.setText("Run"); 1093 fRunButton.setToolTipText("Run"); 1094 fContinueMenuItem.setEnabled(false); 1095 fRunMenuItem.setEnabled(true); 1096 fStopMenuItem.setEnabled(false); 1097 fPauseMenuItem.setEnabled(false); 1098 lblTitle.setBorder(BorderFactory.createEmptyBorder()); 1099 } catch (Exception e) { 1100 e.printStackTrace(); 1101 } 1102 1103 } else { 1104 try { 1105 fRunButton.setText("Stop"); 1106 fRunButton.setToolTipText("Stop"); 1107 fContinueMenuItem.setEnabled(false); 1108 fRunMenuItem.setEnabled(false); 1109 fStopMenuItem.setEnabled(true); 1110 fPauseMenuItem.setEnabled(true); 1111 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, ACTIVE_COLOR)); 1112 } catch (Exception e) { 1113 e.printStackTrace(); 1114 } 1115 } 1116 } 1117 1118 public void edit(String name) { 1119 ListLogPresenter log = new ListLogPresenter(this, name); 1120 setLog(log); 1121 outputPaneAdd(log); 1122 fRunMenuItem.setEnabled(true); 1123 } 1124 1125 public void create(String name) { 1126 ListLogPresenter log = new ListLogPresenter(this, name); 1127 setLog(log); 1128 1129 fRunMenuItem.setEnabled(true); 1130 Node node = new EasyParser().getObject("<Recipe name=\"" + name + "\">\n<!-- your recipe code -->\n</Recipe>"); 1131 applyText(node); 1132 1133 runTest(new Node[] { node }); 1134 fContinueMenuItem.setEnabled(false); 1135 } 1136 1137 public String getPanelName() { 1138 Processor processor = getTaskProcessor(); 1139 return processor.getTestName(); 1140 } 1141 1142 public void saveTask() throws IOException { 1143 String recipeName = getTaskNode().getAttribute("name"); 1144 if (fTaskFile == null || !fTaskFile.startsWith("jar:")) { 1145 1146 if (fTaskFile == null) { 1147 FileDialog theFileDialog = new FileDialog(JOptionPane.getRootFrame(), "Save Recipe File", 1148 FileDialog.SAVE); 1149 if (getTaskNode() != null) { 1150 theFileDialog.setFile(recipeName + ".recipe"); 1151 } 1152 theFileDialog.setVisible(true); 1153 if (theFileDialog.getFile() == null) 1154 return; 1155 fTaskFile = new File(theFileDialog.getDirectory() + theFileDialog.getFile()).getAbsolutePath(); 1156 } 1157 1158 if (getTaskNode() != null) { 1159 File file = new File(fTaskFile); 1160 String name = FilenameUtils.getBaseName(file.getName()); 1161 String oldName = getTaskNode().getAttribute("name"); 1162 if (!StringUtils.equals(name, oldName)) { 1163 File newfile = new File(file.getParent(), oldName + ".recipe"); 1164 if (file.renameTo(newfile)) { 1165 file = newfile; 1166 fTaskFile = file.getAbsolutePath(); 1167 } 1168 } 1169 1170 Node theNode = (Node) getTaskNode().clone(); 1171 String newName = theNode.getAttribute("name"); 1172 1173 AEWorkspace workspace = frame.getWorkspace(); 1174 workspace.removeTestPath(oldName); 1175 workspace.setTestPath(newName, fTaskFile); 1176 1177 EasyUtils.removeTagId(theNode); 1178 1179 byte[] bytes = getTaskNode().getXMLText().getBytes("UTF-8"); 1180 1181 try (FileOutputStream theFileOutputStream = new FileOutputStream(fTaskFile)) { 1182 theFileOutputStream.write(bytes); 1183 } 1184 1185 setTitle(recipeName); 1186 } 1187 } 1188 } 1189 1190 public void runTask() { 1191 try { 1192 final String selectedText = fTaskText.getSelectedText(); 1193 1194 if (openIn && StringUtils.isBlank(selectedText)) { 1195 reload(); 1196 } 1197 1198 getManager().startTaskNotify(this); 1199 runTaskNode(); 1200 1201 } catch (Exception e) { 1202 getLogger().error("Running failed.", e); 1203 } 1204 } 1205 1206 @Override 1207 public void criticalError(final CommandException exception, final Processor processor) { 1208 frame.criticalError(TaskEditor.this); 1209 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.RED)); 1210 1211 if (isNotifyMe()) { 1212 getFrame().fireBuzzAction(() -> super.criticalError(exception, processor)); 1213 } else { 1214 super.criticalError(exception, processor); 1215 } 1216 } 1217 1218 @Override 1219 public void checkFailure(final CommandException exception, final Processor processor) { 1220 frame.checkFailure(TaskEditor.this); 1221 1222 if (isNotifyMe()) { 1223 getFrame().fireBuzzAction(() -> super.checkFailure(exception, processor)); 1224 } else { 1225 super.checkFailure(exception, processor); 1226 } 1227 } 1228 1229 public void closeTab() { 1230 frame.removeTab(TaskEditor.this); 1231 } 1232 1233 public void showAbout() { 1234 Node taskNode = getTaskNode(); 1235 aboutTest(taskNode.getAttribute("name"), taskNode.findNode(ABOUT, null, null)); 1236 } 1237 1238 public void showTaskTreePane() { 1239 CardLayout cl = (CardLayout) (createEditorPanel.getLayout()); 1240 cl.show(createEditorPanel, TASK_TREE); 1241 } 1242 1243 public int getCaretPosition() { 1244 return fTaskText.getCaretPosition(); 1245 } 1246 1247 public Point getMagicCaretPosition() { 1248 return fTaskText.getCaret().getMagicCaretPosition(); 1249 } 1250 1251 public String getText() { 1252 return fTaskText.getText(); 1253 } 1254 1255 public void replaceRange(String text, int i, int caretPosition2) { 1256 fTaskText.replaceRange(text, i, caretPosition2); 1257 } 1258 1259 public DialogPopupMenu contextHelp(DialogPopupMenu menu) { 1260 return menu; 1261 } 1262 1263 @Override 1264 public void runTest(Node testNode[]) { 1265 Node object = testNode[0]; 1266 object.getVector(true); 1267 setTaskNode(object); 1268 refreshTaskTree(); 1269 runTaskNode(); 1270 } 1271 1272 public AEFrame getFrame() { 1273 return frame; 1274 } 1275 1276 public void pause() { 1277 fRunMenuItem.setEnabled(false); 1278 fContinueMenuItem.setEnabled(true); 1279 fPauseMenuItem.setEnabled(false); 1280 1281 fTitleTest.setText(" Suspended execution ..."); 1282 fTitleTest.setForeground(Color.YELLOW.darker()); 1283 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, Color.YELLOW)); 1284 } 1285 1286 @Override 1287 public void resume() { 1288 fRunMenuItem.setEnabled(false); 1289 fContinueMenuItem.setEnabled(false); 1290 fPauseMenuItem.setEnabled(true); 1291 1292 fTitleTest.setText(""); 1293 fTitleTest.setForeground(Color.GRAY.darker()); 1294 lblTitle.setBorder(BorderFactory.createMatteBorder(0, 0, 2, 0, ACTIVE_COLOR)); 1295 } 1296 1297 public boolean isRunning() { 1298 return isRunning; 1299 } 1300 1301 public TextEditor getEditor() { 1302 return fTaskText; 1303 } 1304 1305 public void select() { 1306 getFrame().setSelectedComponent(getMainPanel()); 1307 } 1308 1309 @Override 1310 public void setTaskNode(Node taskNode) { 1311 super.setTaskNode(taskNode); 1312 String aName = getTaskName() + ".notifyMe"; 1313 String defaultNotify = AEWorkspace.getInstance().getDefaultUserConfiguration("notifyMe", "true"); 1314 boolean notify = Boolean 1315 .parseBoolean(AEWorkspace.getInstance().getDefaultUserConfiguration(aName, defaultNotify)); 1316 notifyMeCheckBox.setSelected(notify); 1317 } 1318 1319 public boolean isNotifyMe() { 1320 return notifyMeCheckBox.isSelected(); 1321 } 1322 1323}