/*
* Created on Nov 25, 2005
*
* Copyright 2005-2010 Ignis Software Tools Ltd. All rights reserved.
*/
package jsystem.treeui.tree;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import jsystem.extensions.report.html.HtmlCodeWriter;
import jsystem.framework.FrameworkOptions;
import jsystem.framework.JSystemProperties;
import jsystem.framework.report.ListenerstManager;
import jsystem.framework.scenario.JTest;
import jsystem.framework.scenario.RunnerTest;
import jsystem.framework.scenario.RunningProperties;
import jsystem.framework.scenario.ScenarioHelpers;
import jsystem.framework.scenario.ScenariosManager;
import jsystem.guiMapping.JsystemMapping;
import jsystem.treeui.HTMLJavaDocView;
import jsystem.treeui.ProgressController;
import jsystem.treeui.TestFilterManager;
import jsystem.treeui.TestTreeModel;
import jsystem.treeui.WaitDialog;
import jsystem.treeui.actionItems.RefreshAction;
import jsystem.treeui.images.ImageCenter;
import jsystem.utils.StringUtils;
import jsystem.utils.SwingUtils;
import junit.framework.SystemTest;
/**
* Control the tests tree tab.
*
* @author guy.arieli
*
*/
public class TestsTreeController implements TreeSelectionListener, MouseListener, ActionListener, KeyListener {
private static Logger log = Logger.getLogger(TestsTreeController.class.getName());
private TestTreePanel testBrowser;
private TestsTreeListener listener;
private AssetNode currentNode = null;
private JMenuItem popupCheckItem;
private JMenuItem popupUncheckItem;
private JPopupMenu popupMenu;
private JPopupMenu rootPopupMenu;
private JMenuItem popupCheckItem2;
private JMenuItem popupUncheckItem2;
private JMenuItem popupCollapseTree;
private JMenuItem popupExpandTree;
private JMenuItem popupCollapseTree2;
private JMenuItem popupExpandTree2;
private JButton addButton;
private JSpinner testsNumSpinner;
private int testsCounter;
private JSplitPane main;
private JComboBox filter;
private JToggleButton sutFilter;
private JToggleButton sort;
private HTMLJavaDocView nodeInformation;
public TestsTreeController(TestsTreeListener listener) {
this.listener = listener;
testBrowser = new TestTreePanel();
testBrowser.showLoadFailIfExists();
testBrowser.getTree().addMouseListener(this);
testBrowser.getTree().addTreeSelectionListener(this);
createPopup();
main = new JSplitPane();
main.setOrientation(JSplitPane.VERTICAL_SPLIT);
main.setDividerLocation(30);
main.setOneTouchExpandable(false);
main.setDividerSize(0);
JSplitPane treeAndTestInfo = new JSplitPane();
treeAndTestInfo.setOrientation(JSplitPane.VERTICAL_SPLIT);
treeAndTestInfo.setDividerSize(10);
treeAndTestInfo.setDividerLocation(700);
treeAndTestInfo.setOneTouchExpandable(true);
treeAndTestInfo.setBackground(new Color(0xf6, 0xf6, 0xf6));
treeAndTestInfo.setTopComponent(new JScrollPane(testBrowser));
treeAndTestInfo.setResizeWeight(0.85);
//This will make sure that the test/scenario info pane is expandable.
BasicSplitPaneUI ui = (BasicSplitPaneUI) treeAndTestInfo.getUI();
BasicSplitPaneDivider divider = ui.getDivider();
divider.setLocation(0, 700);
JButton button = (JButton) divider.getComponent(1);
button.doClick();
// Add scenario/test information view
nodeInformation = new HTMLJavaDocView(new Color(0xf6, 0xf6, 0xf6));
nodeInformation.setToolTipText(JsystemMapping.getInstance().getBuildingBlockInformationToolTip());
nodeInformation.setOpaque(true);
nodeInformation.setEditable(false);
JScrollPane nodeInformationPane = SwingUtils.getJScrollPaneWithWaterMark(
ImageCenter.getInstance().getAwtImage(ImageCenter.ICON_TEST_TREE_BG), nodeInformation);
nodeInformationPane.setOpaque(true);
treeAndTestInfo.setBottomComponent(nodeInformationPane);
main.setBottomComponent(treeAndTestInfo);
main.setTopComponent(createToolBar());
addButton.setEnabled(false);
testsNumSpinner.setEnabled(false);
TestFilterManager.getInstance().init(this);
}
public JSplitPane getTreePanel() {
return main;
}
/**
* Reloads the view by updating the tree and clears the report view
*/
public void refreshView() {
// reload tree
testBrowser.refreshTree();
testBrowser.getTree().repaint();
testBrowser.getTree().removeTreeSelectionListener(this);
testBrowser.getTree().clearSelection();
testBrowser.getTree().addTreeSelectionListener(this);
}
public void repaintTree() {
testBrowser.getTree().repaint();
}
public TestTreeModel getTreeModel() {
return testBrowser.getTreeModel();
}
/*
* (non-Javadoc)
*
* @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
*/
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
*/
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
*/
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
*/
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
/**
* Impelemnts the mause pressed action
*
* @param e
* MouseEvent
*/
@Override
public void mousePressed(MouseEvent e) {
showPopup(e);
}
/**
* Handles the changes on the tree
*
* @param e
* TreeSelectionEvent
*/
@Override
public void valueChanged(TreeSelectionEvent e) {
// save the selected node
currentNode = (AssetNode) testBrowser.getTree().getLastSelectedPathComponent();
if (nodeInformation.getParent().getHeight() <= 0) {
nodeInformation.setContent("");
return;
}
nodeInformation.setContent(getCurrentNodeInformation());
}
/**
* Collects the current node information according to the node type and
* returns the information as HTML formatted string
*
* @return HTML string that represents the current node information
*/
private String getCurrentNodeInformation() {
if (null == currentNode){
return "";
}
final StringBuilder info = new StringBuilder();
info.append("<b>").append(currentNode.toString()).append("</b><br>");
if (currentNode instanceof TestNode) {
RunnerTest test = ((TestNode) currentNode).getTest();
final String className = test.getClassName();
final String methodName = test.getMethodName();
info.append("<b>Class:</b> ").append(className).append("<br>");
info.append("<b>Method:</b> ").append(methodName).append("<br>");
final long lastRunTime = ProgressController.getTestTime(className, methodName);
if (lastRunTime > 0) {
info.append("<b>Last run time:</b> ").append(lastRunTime / 1000).append(" seconds<br>");
}
String[] retParams = test.getReturnParameters();
if (retParams != null && retParams.length > 0) {
info.append("<b>Return params: </b>")
.append(StringUtils.objectArrayToString(",", (Object[]) retParams)).append("<br>");
}
if (test.getTest() instanceof SystemTest) {
SystemTest sTest = (SystemTest) test.getTest();
info.append("<b>Fixture: </b>").append(sTest.getFixture().getName()).append("<br>");
Class<?> ff = sTest.getTearDownFixture();
if (ff != null) {
info.append("<b>Fail to fixture: </b>").append(ff.getName()).append("<br>");
}
}
try {
String doc = HtmlCodeWriter.getInstance().getMethodJavaDoc(className, methodName);
if (!StringUtils.isEmpty(doc)) {
info.append("<b>Documentation:</b><br>").append(doc.replaceAll("\n", "<br>"));
}
} catch (Exception e) {
log.log(Level.WARNING, "Failed to get test documentation", e);
}
} else if (currentNode instanceof ScenarioNode) {
String doc = ScenarioHelpers.getTestProperty(null, ((ScenarioNode) currentNode).getScenarioName(),
RunningProperties.DOCUMENTATION_TAG);
if (!StringUtils.isEmpty(doc)) {
info.append("<b>User Documentation:</b><br>").append(doc);
}
}
return info.toString();
}
/**
* Shows the tree popup menu
*
* @param e
* MouseEvent
*/
private void showPopup(MouseEvent e) {
int x = e.getX();
int y = e.getY();
// save the path for future use
TreePath clickedPath = testBrowser.getTree().getPathForLocation(x, y);
if (clickedPath == null)
return;
// save the selected node
currentNode = (AssetNode) clickedPath.getLastPathComponent();
// if this is the right button
if (e.getButton() == MouseEvent.BUTTON3) {
// get position
testBrowser.getTree().setSelectionPath(clickedPath);
testBrowser.getTree().scrollPathToVisible(clickedPath);
// show the popup menu
if (currentNode instanceof TestNode || currentNode instanceof ScenarioNode
|| currentNode instanceof FixtureNode || currentNode instanceof TestNode) {
popupCollapseTree.setVisible(false);
popupExpandTree.setVisible(false);
} else {
popupCollapseTree.setVisible(true);
popupExpandTree.setVisible(true);
}
if (currentNode.isClassPath()) {
rootPopupMenu.show(testBrowser.getTree(), x, y);
} else {
popupMenu.show(testBrowser.getTree(), x, y);
}
} else if (e.getButton() == MouseEvent.BUTTON1) {
if (currentNode instanceof FixtureNode) {
AssetNode n = currentNode;
n.setSelected(!n.isSelected);
testBrowser.getTree().repaint();
}
if (currentNode instanceof ScriptNode) {
AssetNode n = currentNode;
n.setSelected(!n.isSelected);
testBrowser.getTree().repaint();
}
if (currentNode instanceof TestNode) {
TestNode n = (TestNode) currentNode;
n.setSelected(!n.isSelected());
testBrowser.getTree().repaint();
} else if (currentNode instanceof ScenarioNode) {
ScenarioNode n = (ScenarioNode) currentNode;
n.setSelected(!n.isSelected());
testBrowser.getTree().repaint();
}
boolean enable = TestTreePanel.currentSelectedTests > 0;
addButton.setEnabled(enable);
testsNumSpinner.setEnabled(enable);
}
}
/**
* Creates the popup menu
*/
private void createPopup() {
popupMenu = new JPopupMenu();
rootPopupMenu = new JPopupMenu();
popupCheckItem = new JMenuItem("Check Selection");
popupCheckItem.addActionListener(this);
popupUncheckItem = new JMenuItem("Uncheck Selection");
popupUncheckItem.addActionListener(this);
popupCollapseTree = new JMenuItem("Collapse tree");
popupCollapseTree.addActionListener(this);
popupExpandTree = new JMenuItem("Expand tree");
popupExpandTree.addActionListener(this);
popupMenu.add(popupCollapseTree);
popupMenu.add(popupExpandTree);
popupMenu.add(popupCheckItem);
popupMenu.add(popupUncheckItem);
popupCheckItem2 = new JMenuItem("Check Selection");
popupCheckItem2.addActionListener(this);
popupUncheckItem2 = new JMenuItem("Uncheck Selection");
popupUncheckItem2.addActionListener(this);
popupCollapseTree2 = new JMenuItem("Collapse tree");
popupCollapseTree2.addActionListener(this);
popupExpandTree2 = new JMenuItem("Expand tree");
popupExpandTree2.addActionListener(this);
rootPopupMenu.add(popupCollapseTree2);
rootPopupMenu.add(popupExpandTree2);
rootPopupMenu.add(popupCheckItem2);
rootPopupMenu.add(popupUncheckItem2);
}
private void expandAll(JTree tree, TreePath parent, boolean expand) {
// Traverse children
TreeNode node = (TreeNode) parent.getLastPathComponent();
if (node.getChildCount() >= 0) {
for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
TreeNode n = (TreeNode) e.nextElement();
TreePath path = parent.pathByAddingChild(n);
expandAll(tree, path, expand);
}
}
// Expansion or collapse must be done bottom-up
if (expand) {
tree.expandPath(parent);
} else {
tree.collapsePath(parent);
}
}
/**
* Expands the tree
*/
public void expandTree() {
JTree tree = testBrowser.getTree();
if (tree == null) {
return;
}
int row = 0;
while (row < tree.getRowCount()) {
tree.expandRow(row);
row++;
}
}
public void expandTree(int row) {
JTree tree = testBrowser.getTree();
if (tree == null) {
return;
}
tree.expandRow(row);
}
/*
* (non-Javadoc)
*
* @see
* java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(popupCheckItem) || e.getSource().equals(popupCheckItem2)) {
currentNode.setSelected(true);
testBrowser.getTree().repaint();
} else if (e.getSource().equals(popupUncheckItem) || e.getSource().equals(popupUncheckItem2)) {
currentNode.setSelected(false);
testBrowser.getTree().repaint();
} else if (e.getSource().equals(popupCollapseTree) || e.getSource().equals(popupCollapseTree2)) {
expandAll(testBrowser.getTree(), testBrowser.getTree().getSelectionPath(), false);
} else if (e.getSource().equals(popupExpandTree) || e.getSource().equals(popupExpandTree2)) {
expandAll(testBrowser.getTree(), testBrowser.getTree().getSelectionPath(), true);
testBrowser.getTree().repaint();
} else if (e.getSource().equals(addButton)) {
WaitDialog.launchWaitDialog(JsystemMapping.getInstance().getAddTestsDialog(), null);
(new Thread() {
@Override
public void run() {
try {
Vector<JTest> v = new Vector<JTest>();
Vector<JTest> all = new Vector<JTest>();
boolean success = true;
testBrowser.collectSelectedTests(v, null);
Collections.reverse(v); // add Tests in reverse order to
// get tests in the same order
// they appear in the tree
for (int i = 0; i < Integer.valueOf(testsNumSpinner.getValue().toString()) && success; i++) {
all.addAll(v);
}
testsCounter = ScenariosManager.getInstance().getCurrentScenario().getTests().size();
testsCounter += all.size();
int max = Integer.parseInt(JSystemProperties.getInstance().getPreference(
FrameworkOptions.MAX_BUILDING_BLOCKS_NUMBER));
if (testsCounter <= max)
success = listener.addTests(all);
else {
success = false;
WaitDialog.endWaitDialog();
ListenerstManager
.getInstance()
.showConfirmDialog(
"Error",
"Exceeded max building blocks number, couldn't add the selected tests to the scenario",
JOptionPane.CLOSED_OPTION, JOptionPane.ERROR_MESSAGE);
}
if (success) {
testBrowser.unselectAll();
testsNumSpinner.setValue(Integer.valueOf(1));
addButton.setEnabled(false);
testsNumSpinner.setEnabled(false);
TestTreePanel.currentSelectedTests = 0;
}
testBrowser.getTree().repaint();
} finally {
WaitDialog.endWaitDialog();
}
}
}).start();
} else if (e.getSource().equals(filter)) {
keyReleased(null);
} else if (e.getSource().equals(sutFilter)) {
JSystemProperties.getInstance().setPreference(FrameworkOptions.FILTER_SUT_IN_ASSETS_TREE,
Boolean.toString(sutFilter.isSelected()));
RefreshAction.getInstance().actionPerformed(null);
} else if (e.getSource().equals(sort)) {
JSystemProperties.getInstance().setPreference(FrameworkOptions.SORT_ASSETS_TREE,
Boolean.toString(sort.isSelected()));
RefreshAction.getInstance().actionPerformed(null);
}
boolean enable = TestTreePanel.getCurrentSelectedTests() > 0;
addButton.setEnabled(enable);
testsNumSpinner.setEnabled(enable);
}
private JToolBar createToolBar() {
JToolBar toolBar = SwingUtils.getJToolBarWithBgImage("tests tree", JToolBar.HORIZONTAL, ImageCenter
.getInstance().getImage(ImageCenter.ICON_SCEANRIO_TOOLBAR_BG));
toolBar.setLayout(new FlowLayout(FlowLayout.LEFT, 1, 1));
toolBar.setRollover(true);
addButton = new JButton(ImageCenter.getInstance().getImage(ImageCenter.ICON_ADD));
addButton.setToolTipText(JsystemMapping.getInstance().getAddTestsButton());
addButton.setBackground(new Color(0, 0, 0, 0));
addButton.addActionListener(this);
toolBar.add(addButton);
String value = JSystemProperties.getInstance().getPreference(FrameworkOptions.MAX_BUILDING_BLOCKS_NUMBER);
if (value == null) {
value = ((Integer) FrameworkOptions.MAX_BUILDING_BLOCKS_NUMBER.getDefaultValue()).toString();
JSystemProperties.getInstance().setPreference(FrameworkOptions.MAX_BUILDING_BLOCKS_NUMBER, value);
}
int max = Integer.parseInt(value);
testsNumSpinner = new JSpinner(new SpinnerNumberModel(1, 1, max, 1));
testsNumSpinner.setName("testsNumSpinner");
testsNumSpinner.setToolTipText("Number of tests to be added to scenario tree");
toolBar.add(testsNumSpinner);
toolBar.addSeparator(new Dimension(40, 0));
filter = new JComboBox(GroupsManager.getInstance().getGroups());
filter.setEditable(true);
filter.setToolTipText(JsystemMapping.getInstance().getFilterToolTip());
filter.getEditor().getEditorComponent().addKeyListener(this);
((JTextField) filter.getEditor().getEditorComponent()).setColumns(10);
filter.addActionListener(this);
// filter.setMinimumSize(new Dimension(40, filter.getHeight()));
toolBar.add(filter);
toolBar.addSeparator(new Dimension(40, 0));
sutFilter = new JToggleButton(ImageCenter.getInstance().getImage(ImageCenter.ICON_FILTER_TESTS_TREE));
sutFilter.setEnabled(true);
sutFilter.setToolTipText("Filter SUT tree");
sutFilter.addActionListener(this);
if ("true".equals(JSystemProperties.getInstance().getPreference(FrameworkOptions.FILTER_SUT_IN_ASSETS_TREE))) {
sutFilter.setSelected(true);
} else {
sutFilter.setSelected(false);
}
toolBar.add(sutFilter);
sort = new JToggleButton(ImageCenter.getInstance().getImage(ImageCenter.ICON_SORT_TESTS_TREE));
sort.setEnabled(true);
sort.setToolTipText("Sort Assets Tree Alphabetically");
sort.addActionListener(this);
if ("true".equals(JSystemProperties.getInstance().getPreferenceOrDefault(FrameworkOptions.SORT_ASSETS_TREE))) {
sort.setSelected(true);
} else {
sort.setSelected(false);
}
toolBar.add(sort);
toolBar.setPreferredSize(new Dimension(160, 30));
toolBar.setFloatable(false);
return toolBar;
}
public JTree getTree() {
return testBrowser.getTree();
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
// The code was moved from keyTyped() method into keyReleased() method
// since
// keyTyped() method was not updated with the last pressed character.
//Support for OR operator.
String filterText= ((JTextField) filter.getEditor().getEditorComponent()).getText().replaceAll(" OR ", "|");
//Support for AND operator.
String filterTextArr[] = filterText.split(" AND ");
if (filterTextArr != null && filterTextArr.length !=0 && filterTextArr[0].isEmpty()) {
filterTextArr = null;
}
String[] originalFilterArr = TestFilterManager.getInstance().getFilter();
if (originalFilterArr == null && filterTextArr == null) {
return;
}
if (originalFilterArr != null && Arrays.equals(filterTextArr, originalFilterArr)) {
return;
}
TestFilterManager.getInstance().setFilter(filterTextArr);
}
@Override
public void keyTyped(KeyEvent e) {
}
}