All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.jellytools.OutputTabOperator Maven / Gradle / Ivy

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.netbeans.jellytools;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;
import javax.swing.KeyStroke;
import javax.swing.text.Document;
import org.netbeans.jellytools.actions.Action;
import org.netbeans.jellytools.actions.CopyAction;
import org.netbeans.jellytools.actions.FindAction;
import org.netbeans.jellytools.actions.ActionNoBlock;
import org.netbeans.jemmy.ComponentChooser;
import org.netbeans.jemmy.JemmyException;
import org.netbeans.jemmy.operators.*;
import org.openide.util.Lookup;

/** Operator for Output tab. It resides in output top component.
 * 

* Usage:
*

 *      // find output tab with given name
 *      OutputTabOperator oto = new OutputTabOperator("compile-single");
 *      // wait for a message appears in output
 *      oto.waitText("my message");
 *      // get the text
 *      String wholeOutput = oto.getText();
 *      // close this output
 *      oto.close();
 * 
* * @author Jiri Skrivanek * @see OutputOperator */ public class OutputTabOperator extends JComponentOperator { // operator of OutputPane component ComponentOperator outputPaneOperator; // actions used only in OutputTabOperator private static final Action findNextAction = new Action(null, Bundle.getString("org.netbeans.core.output2.Bundle", "ACTION_FIND_NEXT"), null, KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0)); private static final Action wrapTextAction = new Action(null, Bundle.getString("org.netbeans.core.output2.Bundle", "ACTION_WRAP"), null, System.getProperty("os.name").toLowerCase().indexOf("mac") > -1 ? KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.META_MASK) : KeyStroke.getKeyStroke(KeyEvent.VK_W, KeyEvent.CTRL_MASK)); private static final ActionNoBlock saveAsAction = new ActionNoBlock(null, Bundle.getString("org.netbeans.core.output2.Bundle", "ACTION_SAVEAS"), null, System.getProperty("os.name").toLowerCase().indexOf("mac") > -1 ? KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.META_MASK) : KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK)); private static final Action nextErrorAction = new Action(null, null, null, KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0)); private static final Action previousErrorAction = new Action(null, null, null, KeyStroke.getKeyStroke(KeyEvent.VK_F12, InputEvent.SHIFT_MASK)); private static final Action closeAction = new Action(null, Bundle.getString("org.netbeans.core.output2.Bundle", "ACTION_CLOSE"), null, System.getProperty("os.name").toLowerCase().indexOf("mac") > -1 ? KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.META_MASK) : KeyStroke.getKeyStroke(KeyEvent.VK_F4, KeyEvent.CTRL_MASK)); private static final Action clearAction = new Action(null, Bundle.getString("org.netbeans.core.output2.Bundle", "ACTION_CLEAR"), null, System.getProperty("os.name").toLowerCase().indexOf("mac") > -1 ? KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.META_MASK) : KeyStroke.getKeyStroke(KeyEvent.VK_L, KeyEvent.CTRL_MASK)); private static final CopyAction copyAction = new CopyAction(); private static final FindAction findAction = new FindAction(); /** * Buttons in the tool bar to the left of the currently active output tab. * They apply to depend on the currently open tab, so they're placed * here instead of OutputOperator. This way it's also more useful. */ private JButtonOperator btnReRun; private JButtonOperator btnReRunWithDifferentParameters; private JButtonOperator btnStop; private JButtonOperator btnAntSettings; /** Create new instance of OutputTabOperator from given component. * @param source JComponent source */ public OutputTabOperator(JComponent source) { // used in OutputOperator super(source); } /** Waits for output tab with given name. * It is activated by default. * @param name name of output tab to look for */ public OutputTabOperator(String name) { this(name, 0); } /** Waits for index-th output tab with given name. * It is activated by default. * @param name name of output tab to look for * @param index index of requested output tab with given name */ public OutputTabOperator(String name, int index) { super((JComponent) new OutputOperator().waitSubComponent(new OutputTabSubchooser(name), index)); makeComponentVisible(); } /** * Returns operator for the Re-Run button in the tool bar on the left of the tab. * The button is inside the parent of the output tab, but applies (depends) to the * currently active tab, so the methods are here instead of * OutputOperator. * * @return JButtonOperator for Re-run button */ public JButtonOperator btnReRun() { if (btnReRun == null) { btnReRun = new JButtonOperator((JButton) JButtonOperator.waitJComponent((Container) new OutputOperator().getSource(), "Re-run", true, true)); } return btnReRun; } /** * Returns operator for the "Re-run with Different Parameters" button * in the tool bar on the left of the tab. The button is inside the parent * of the output tab, but applies (depends) to the currently active tab, * so the methods are here instead of OutputOperator. * * @return JButtonOperator for Re-run with Different Parameters button */ public JButtonOperator btnReRunWithDifferentParameters() { if (btnReRunWithDifferentParameters == null) { btnReRunWithDifferentParameters = new JButtonOperator((JButton) JButtonOperator.waitJComponent((Container) new OutputOperator().getSource(), "Re-run with Different Parameters", true, true)); } return btnReRunWithDifferentParameters; } /** * Returns operator for the Stop button in the tool bar on the left of the tab. * The button is inside the parent of the output tab, but applies (depends) to the * currently active tab, so the methods are here instead of * OutputOperator. * * @return JButtonOperator for Stop button */ public JButtonOperator btnStop() { if (btnStop == null) { btnStop = new JButtonOperator((JButton) JButtonOperator.waitJComponent((Container) new OutputOperator().getSource(), "Stop", true, true)); } return btnStop; } /** * Returns operator for the Ant Settings button in the tool bar on the left of the tab. * The button is inside the parent of the output tab, but applies (depends) to the * currently active tab, so the methods are here instead of * OutputOperator. * * @return JButtonOperator for Ant Settings button */ public JButtonOperator btnAntSettings() { if (btnAntSettings == null) { btnAntSettings = new JButtonOperator((JButton) JButtonOperator.waitJComponent((Container) new OutputOperator().getSource(), "Ant Settings", true, true)); } return btnAntSettings; } /** Activates this output tab. If this output tab is in tabbed pane, it is selected. If * it is only tab in the Output top component, the Output top component * is activated. */ @Override public final void makeComponentVisible() { if (getParent() instanceof JTabbedPane) { super.makeComponentVisible(); // output tab is a tab of JTabbedPane new JTabbedPaneOperator((JTabbedPane) getParent()).setSelectedComponent(getSource()); } else { // output tab is sub component of Output top component new OutputOperator().makeComponentVisible(); } } /** Returns length of written text. It is a number of written characters. * @return length of already written text */ public int getLength() { // ((OutputTab)getSource()).getDocument().getLength(); return runMapping(new MapIntegerAction("getLength") { @Override public int map() { Document document = documentForTab(getSource()); try { if (getOutputDocumentClass().isInstance(document)) { Method getLengthMethod = getOutputDocumentClass().getDeclaredMethod("getLength", (Class[]) null); getLengthMethod.setAccessible(true); return ((Integer) getLengthMethod.invoke(document, (Object[]) null)).intValue(); } } catch (Exception e) { throw new JemmyException("getLength() by reflection failed.", e); } return 0; } }); } /** Finds a line number by text. * @param lineText String line text * @return line number of specified text starting at 0; -1 if text not found */ public int findLine(String lineText) { int lineCount = getLineCount(); if (lineCount < 1) { // no line yet return -1; } for (int i = 0; i < lineCount; i++) { if (getComparator().equals(getLine(i), lineText)) { return i; } } return -1; } /** Returns text from this output tab. * @return text from this output tab. */ public String getText() { final int length = getLength(); return (String) runMapping(new MapAction("getText") { @Override public Object map() { Document document = documentForTab(getSource()); try { if (getOutputDocumentClass().isInstance(document)) { Method getTextMethod = getOutputDocumentClass().getDeclaredMethod("getText", new Class[]{int.class, int.class}); getTextMethod.setAccessible(true); return getTextMethod.invoke(document, new Object[]{Integer.valueOf(0), Integer.valueOf(length)}).toString(); } } catch (Exception e) { throw new JemmyException("Getting text by reflection failed.", e); } return ""; } }); } /** Get text between startLine and endLine from this output tab. * Both startLine and endLine are included. * @param startLine first line to be included (starting at 0) * @param endLine last line to be included * @return text between startLine and endLine from this output tab */ public String getText(int startLine, int endLine) { StringBuilder result = new StringBuilder(); for (int i = startLine; i <= endLine; i++) { result.append(getLine(i)); result.append('\n'); } return result.toString(); } /** Waits for text to be displayed in this output tab. * @param text text to wait for */ public void waitText(final String text) { getOutput().printLine("Wait \"" + text + "\" text in component \n : " + toStringSource()); getOutput().printGolden("Wait \"" + text + "\" text"); waitState(new ComponentChooser() { @Override public boolean checkComponent(Component comp) { return (findLine(text) > -1); } @Override public String getDescription() { return ("\"" + text + "\" text"); } }); } /** Returns count of filled lines of this output tab. * @return count of filled lines of this output tab. */ public int getLineCount() { return ((Integer) runMapping(new MapAction("getLineCount") { @Override public Object map() { Document document = documentForTab(getSource()); try { if (getOutputDocumentClass().isInstance(document)) { Method getElementCountMethod = getOutputDocumentClass().getDeclaredMethod("getElementCount", (Class[]) null); getElementCountMethod.setAccessible(true); return (Integer) getElementCountMethod.invoke(document, (Object[]) null); } } catch (Exception e) { throw new JemmyException("getElementCount() by reflection failed.", e); } return 0; } })).intValue(); } private Class getOutputDocumentClass() throws ClassNotFoundException { ClassLoader scl = Lookup.getDefault().lookup(ClassLoader.class); return Class.forName("org.netbeans.core.output2.OutputDocument", true, scl); } /** Returns operator for OutputPane component. * All events should be dispatched to this component. * @return operator for OutputPane component */ public ComponentOperator outputPaneOperator() { // first make component visible because tab must be visible to dispatch events makeComponentVisible(); if (outputPaneOperator == null) { outputPaneOperator = ComponentOperator.createOperator(outputPaneForTab(getSource())); outputPaneOperator.copyEnvironment(this); // #217765 - wait for lazy loaded actions waitState(new ComponentChooser() { @Override public boolean checkComponent(Component comp) { try { Field actionsLoadedField = getSource().getClass().getDeclaredField("actionsLoaded"); actionsLoadedField.setAccessible(true); return actionsLoadedField.getBoolean(getSource()); } catch (Exception ex) { throw new JemmyException("Reflection failed: " + ex, ex); } } @Override public String getDescription() { return "Output tab actions loaded"; } }); } return outputPaneOperator; } /** Returns text from specified line. * @param line line number to get text from * @return text from the specified line (starting at 0) */ public String getLine(final int line) { return (String) runMapping(new MapAction("getText") { @Override public Object map() { Document document = documentForTab(getSource()); try { if (getOutputDocumentClass().isInstance(document)) { Class clazz = getOutputDocumentClass(); Method getLineStartMethod = clazz.getDeclaredMethod("getLineStart", new Class[]{int.class}); getLineStartMethod.setAccessible(true); Integer lineStart = (Integer) getLineStartMethod.invoke(document, new Object[]{Integer.valueOf(line)}); Method getLineEndMethod = clazz.getDeclaredMethod("getLineEnd", new Class[]{int.class}); getLineEndMethod.setAccessible(true); Integer lineEnd = (Integer) getLineEndMethod.invoke(document, new Object[]{Integer.valueOf(line)}); if (lineStart.intValue() == lineEnd.intValue()) { // line is empty return ""; } Method getTextMethod = clazz.getDeclaredMethod("getText", new Class[]{int.class, int.class}); getTextMethod.setAccessible(true); return getTextMethod.invoke(document, new Object[]{lineStart, Integer.valueOf(lineEnd.intValue() - lineStart.intValue())}).toString(); } } catch (Exception e) { throw new JemmyException("Getting text by reflection failed.", e); } return ""; } }); } private static Component outputPaneForTab(Component tab) { try { return (Component) tab.getClass().getMethod("getOutputPane").invoke(tab); } catch (Exception x) { throw new JemmyException("Reflection failed: " + x, x); } } private static Document documentForTab(Component tab) { Component pane = outputPaneForTab(tab); try { return (Document) pane.getClass().getMethod("getDocument").invoke(pane); } catch (Exception x) { throw new JemmyException("Reflection failed: " + x, x); } } /** SubChooser to determine OutputTab component * Used in findTopComponent method. */ protected static final class OutputTabSubchooser implements ComponentChooser { /** Name of OutputTab to search for. */ private String tabName = null; public OutputTabSubchooser() { } public OutputTabSubchooser(String tabName) { this.tabName = tabName; } @Override public boolean checkComponent(Component comp) { if (comp.getClass().getName().endsWith("OutputTab")) { // NOI18N return Operator.getDefaultStringComparator().equals(comp.getName(), tabName); } else { return false; } } @Override public String getDescription() { return "org.netbeans.core.output2.OutputTab" + // NOI18N ((tabName != null) ? " with \"" + tabName + "\" name" : ""); // NOI18N } } /** Performs verification by accessing all sub-components */ public void verify() { outputPaneOperator(); } /****************************** Actions *****************************/ /** Performs copy action. */ public void copy() { copyAction.perform(outputPaneOperator()); } /** Performs find action. */ public void find() { findAction.perform(outputPaneOperator()); } /** Performs find next action. */ public void findNext() { findNextAction.perform(outputPaneOperator()); } /** Performs next error action. */ public void nextError() { nextErrorAction.perform(outputPaneOperator()); } /** Performs next error action. */ public void previousError() { previousErrorAction.perform(outputPaneOperator()); } /** Performs wrap text action. */ public void wrapText() { wrapTextAction.perform(outputPaneOperator()); } /** Performs save as action. */ public void saveAs() { saveAsAction.perform(outputPaneOperator()); } /** Performs close action. */ public void close() { closeAction.perform(outputPaneOperator()); } /** Performs clear action. */ public void clear() { clearAction.perform(outputPaneOperator()); } /** Performs select all action. */ public void selectAll() { new JEditorPaneOperator(this).selectAll(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy