001: /*
002: DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003:
004: Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005:
006:
007: The contents of this file are subject to the terms of either the GNU
008: General Public License Version 2 only ("GPL") or the Common
009: Development and Distribution License("CDDL") (collectively, the
010: "License"). You may not use this file except in compliance with the
011: License. You can obtain a copy of the License at
012: http://www.netbeans.org/cddl-gplv2.html
013: or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
014: specific language governing permissions and limitations under the
015: License. When distributing the software, include this License Header
016: Notice in each file and include the License file at
017: nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
018: particular file as subject to the "Classpath" exception as provided
019: by Sun in the GPL Version 2 section of the License file that
020: accompanied this code. If applicable, add the following below the
021: License Header, with the fields enclosed by brackets [] replaced by
022: your own identifying information:
023: "Portions Copyrighted [year] [name of copyright owner]"
024:
025: Contributor(s):
026:
027: The Original Software is NetBeans. The Initial Developer of the Original
028: Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
029: Microsystems, Inc. All Rights Reserved.
030:
031: If you wish your version of this file to be governed by only the CDDL
032: or only the GPL Version 2, indicate your decision by adding
033: "[Contributor] elects to include this software in this distribution
034: under the [CDDL or GPL Version 2] license." If you do not indicate a
035: single choice of license, a recipient has the option to distribute
036: your version of this file under either the CDDL, the GPL Version 2 or
037: to extend the choice of license to its licensees as provided above.
038: However, if you add GPL Version 2 code and therefore, elected the GPL
039: Version 2 license, then the option applies only if the new code is
040: made subject to such option by the copyright holder.
041: */
042: package org.netbeans.modules.visualweb.gravy.plugins;
043:
044: import java.util.*;
045: import java.io.*;
046: import java.awt.*;
047: import javax.swing.*;
048: import org.netbeans.jemmy.*;
049: import org.netbeans.jemmy.operators.*;
050: import org.netbeans.modules.visualweb.gravy.*;
051:
052: public class PluginsOperator extends JDialogOperator {
053: private static final String MAIN_MENU_ITEM_TOOLS = "Tools",
054: MAIN_MENU_ITEM_TOOLS_PLUGINS = MAIN_MENU_ITEM_TOOLS
055: + "|Plugins",
056: DIALOG_TITLE_PLUGINS = "Plugins",
057: DIALOG_TITLE_NETBEANS_IDE_INSTALLER = "NetBeans IDE Installer",
058: DIALOG_TITLE_VALIDATION_WARNING = "Validation Warning",
059:
060: TAB_TITLE_AVAILABLE_PLUGINS = "Available Plugins",
061: TAB_TITLE_DOWNLOADED_PLUGINS = "Downloaded",
062:
063: COLUMN_TITLE_NAME = "Name",
064: COLUMN_TITLE_INSTALL = "Install",
065:
066: RADIO_BUTTON_LICENSE_AGREEMENT_ACCEPT_TEXT = "I accept",
067:
068: BUTTON_LABEL_ADD_PLUGINS = "Add Plugins",
069: BUTTON_LABEL_RELOAD_CATALOG = "Reload Catalog",
070: BUTTON_LABEL_INSTALL = "Install",
071: BUTTON_LABEL_NEXT = "Next",
072: BUTTON_LABEL_CONTINUE = "Continue",
073: BUTTON_LABEL_FINISH = "Finish",
074: BUTTON_LABEL_CLOSE = "Close";
075:
076: private JTabbedPaneOperator tabbedPane;
077: private JButtonOperator btnClose;
078: private boolean pluginsAvailable;
079:
080: public static PluginsOperator getInstance() {
081: display(); // check whether the appropriate dialog is opened or not
082: return (new PluginsOperator());
083: }
084:
085: private PluginsOperator() {
086: super (DIALOG_TITLE_PLUGINS);
087: verify();
088: }
089:
090: public void installAvailablePlugins() {
091: installAvailablePlugins(Collections.EMPTY_LIST);
092: }
093:
094: public void installAvailablePlugins(String pluginName) {
095: installAvailablePlugins(new String[] { pluginName });
096: }
097:
098: public void installAvailablePlugins(String[] pluginNames) {
099: installAvailablePlugins(Arrays.asList(pluginNames));
100: }
101:
102: public void installAvailablePlugins(
103: java.util.List<String> pluginNames) {
104: ContainerOperator containerOp = waitTabEnabled(TAB_TITLE_AVAILABLE_PLUGINS);
105: JTableOperator pluginTable = new JTableOperator(containerOp);
106: fillAvailablePluginsTable(containerOp, pluginTable);
107: selectPlugins(pluginTable, pluginNames);
108: if (pluginsAvailable)
109: installSelectedPlugins(containerOp);
110: else
111: System.out
112: .println("WARNING: Necessary plugins are absent!");
113: closeDialog();
114: }
115:
116: public void installDownloadedPlugins(String nbmPath) {
117: ContainerOperator containerOp = waitTabEnabled(TAB_TITLE_DOWNLOADED_PLUGINS);
118: new JButtonOperator(containerOp, BUTTON_LABEL_ADD_PLUGINS)
119: .pushNoBlock();
120: Util.wait(500);
121: new QueueTool().waitEmpty();
122:
123: addDownloadedPlugins(nbmPath, containerOp);
124: JTableOperator pluginTable = new JTableOperator(containerOp);
125: waitPluginsTableFilling(pluginTable);
126:
127: installSelectedPlugins(containerOp);
128: closeDialog();
129: }
130:
131: private ContainerOperator waitTabEnabled(String tabTitle) {
132: for (int i = 0; i < 200; i++) {
133: int cursorType = tabbedPane.getCursor().getType();
134: //debugOutput("Cursor Name = " + tabbedPane.getCursor().getName());
135: if (cursorType == Cursor.WAIT_CURSOR) {
136: Util.wait(1000);
137: new QueueTool().waitEmpty();
138: } else {
139: break;
140: }
141: }
142: int tabIndex = findTab(tabTitle);
143: if (tabIndex > -1) {
144: tabbedPane.setSelectedIndex(tabIndex);
145: ContainerOperator containerOp = new ContainerOperator(
146: (Container) tabbedPane.getComponentAt(tabIndex));
147: Util.wait(500);
148: new QueueTool().waitEmpty();
149: return containerOp;
150: } else {
151: throw new RuntimeException("Tab with title [" + tabTitle
152: + "] isn't found in the dialog [" + this .getTitle()
153: + "]");
154: }
155: }
156:
157: private int findTab(String tabTitle) {
158: // int tabIndex = tabbedPane.indexOfTab(tabTitle); // only j2sdk 1.6
159: // return tabIndex;
160: int tabCount = tabbedPane.getTabCount();
161: for (int i = 0; i < tabCount; i++) {
162: // Component component = tabbedPane.getComponentAt(i);
163: // only j2sdk 1.6: Component tabComponent = ((JTabbedPane) tabbedPane.getSource()).getTabComponentAt(i);
164: String title = tabbedPane.getTitleAt(i);
165: //debugOutput("+++ Tab Title = [" + title + "]");
166: //if (title.equals(tabTitle)) {
167: if (title.indexOf(tabTitle) > -1) {
168: return i;
169: }
170: }
171: return (-1);
172: }
173:
174: private int getColumnIndexByName(JTableOperator tableOp,
175: String columnName) {
176: int colCount = tableOp.getColumnCount();
177: for (int i = 0; i < colCount; i++) {
178: String name = tableOp.getColumnName(i);
179: if (name.indexOf(columnName) > -1) {
180: return i;
181: }
182: }
183: return (-1);
184: }
185:
186: private void fillAvailablePluginsTable(
187: ContainerOperator containerOp, JTableOperator pluginTable) {
188: int rowCount = pluginTable.getRowCount();
189: //debugOutput("pluginTable.getRowCount() = " + rowCount,
190: // "pluginTable.getColumnCount() = " + pluginTable.getColumnCount());
191: if (rowCount == 0) {
192: new JButtonOperator(containerOp,
193: BUTTON_LABEL_RELOAD_CATALOG).pushNoBlock();
194: Util.wait(500);
195: new QueueTool().waitEmpty();
196: waitPluginsTableFilling(pluginTable);
197: }
198: }
199:
200: private void waitPluginsTableFilling(JTableOperator pluginTable) {
201: for (int i = 0; i < 200; i++) {
202: int rowCount = pluginTable.getRowCount();
203: //debugOutput("pluginTable.getRowCount() = " + rowCount);
204: if (rowCount < 1) {
205: Util.wait(1000);
206: new QueueTool().waitEmpty();
207: } else {
208: break;
209: }
210: }
211: }
212:
213: private void selectPlugins(JTableOperator pluginTable,
214: java.util.List<String> pluginNames) {
215: java.util.List<String> selectedPlugins = new ArrayList();
216: int nameColumnIndex = getColumnIndexByName(pluginTable,
217: COLUMN_TITLE_NAME);
218: int installColumnIndex = getColumnIndexByName(pluginTable,
219: COLUMN_TITLE_INSTALL), rowCount = pluginTable
220: .getRowCount();
221: for (int row = 0; row < rowCount; row++) {
222: Object cellValue = pluginTable.getValueAt(row,
223: nameColumnIndex);
224: //debugOutput("cellValue[" + row + "] = [" + cellValue + "]");
225: if (isPluginInList(pluginNames, cellValue.toString())) {
226: int rowIndex = row;
227: pluginTable.clickOnCell(rowIndex, installColumnIndex);
228: Util.wait(500);
229: new QueueTool().waitEmpty();
230: selectedPlugins.add(cellValue.toString());
231: }
232: }
233: if (selectedPlugins.isEmpty())
234: pluginsAvailable = false;
235: else
236: pluginsAvailable = true;
237: }
238:
239: private boolean isPluginInList(java.util.List<String> pluginNames,
240: String checkedPluginName) {
241: // if a list of plugin names is empty, it means that
242: // all plugins in a table should be selected
243: if (pluginNames.isEmpty())
244: return true;
245: return pluginNames.contains(checkedPluginName);
246: }
247:
248: private void addDownloadedPlugins(String nbmPath,
249: ContainerOperator containerOp) {
250: new JButtonOperator(containerOp, BUTTON_LABEL_ADD_PLUGINS)
251: .pushNoBlock();
252: Util.wait(500);
253: new QueueTool().waitEmpty();
254:
255: JFileChooserOperator fileChooserOp = new JFileChooserOperator();
256: fileChooserOp.setSelectedFile(new File(nbmPath));
257: Util.wait(500);
258: new QueueTool().waitEmpty();
259:
260: fileChooserOp.approve();
261: Util.wait(500);
262: new QueueTool().waitEmpty();
263: }
264:
265: private void installSelectedPlugins(ContainerOperator containerOp) {
266: JButtonOperator btnInstall = new JButtonOperator(containerOp,
267: BUTTON_LABEL_INSTALL);
268: if (btnInstall.isEnabled()) {
269: btnInstall.pushNoBlock();
270: Util.wait(500);
271: new QueueTool().waitEmpty();
272: } else {
273: throw new RuntimeException("The button ["
274: + BUTTON_LABEL_INSTALL
275: + "] isn't enabled in the dialog ["
276: + DIALOG_TITLE_PLUGINS + "]");
277: }
278: workInstallerDialog();
279: }
280:
281: private void workInstallerDialog() {
282: JDialogOperator installerDialog = new JDialogOperator(
283: DIALOG_TITLE_NETBEANS_IDE_INSTALLER);
284: Util.wait(3000);
285: new QueueTool().waitEmpty();
286:
287: String timeoutName = "ComponentOperator.WaitComponentTimeout";
288: long previousTimeoutValue = JemmyProperties
289: .getCurrentTimeout(timeoutName), newTimeoutValue = 1000;
290: JemmyProperties.getCurrentTimeouts().setTimeout(timeoutName,
291: newTimeoutValue);
292: try {
293: new JButtonOperator(installerDialog, BUTTON_LABEL_NEXT)
294: .pushNoBlock();
295: Util.wait(1000);
296: new QueueTool().waitEmpty();
297:
298: JCheckBoxOperator cbLicenseAgreements = new JCheckBoxOperator(
299: installerDialog,
300: RADIO_BUTTON_LICENSE_AGREEMENT_ACCEPT_TEXT);
301: cbLicenseAgreements.changeSelection(true);
302: Util.wait(500);
303: new QueueTool().waitEmpty();
304:
305: Util.wait(500);
306: new QueueTool().waitEmpty();
307: } catch (TimeoutExpiredException tee) {
308: tee.printStackTrace(System.out);
309: } catch (Exception e) {
310: e.printStackTrace(System.out);
311: throw new RuntimeException(e);
312: } finally {
313: JemmyProperties.getCurrentTimeouts().setTimeout(
314: timeoutName, previousTimeoutValue);
315: }
316: new JButtonOperator(installerDialog, BUTTON_LABEL_INSTALL)
317: .pushNoBlock();
318: Util.wait(500);
319: new QueueTool().waitEmpty();
320:
321: waitInstallationFinish(installerDialog);
322: }
323:
324: private void waitInstallationFinish(JDialogOperator dialogOp) {
325: String timeoutName = "DialogWaiter.WaitDialogTimeout";
326: long previousTimeoutValue = JemmyProperties
327: .getCurrentTimeout(timeoutName), newTimeoutValue = 1000;
328: JemmyProperties.getCurrentTimeouts().setTimeout(timeoutName,
329: newTimeoutValue);
330:
331: //DialogWatcher warningDialogThread = new DialogWatcher(
332: // DIALOG_TITLE_VALIDATION_WARNING, BUTTON_LABEL_CONTINUE);
333: //warningDialogThread.startWatch();
334:
335: JButtonOperator btnFinish = null;
336: for (int i = 0; i < 600; i++) {
337: btnFinish = checkButtonFinishAppearance(dialogOp);
338: if ((btnFinish != null) && (btnFinish.isEnabled()))
339: break;
340: }
341: //warningDialogThread.stopWatch();
342: JemmyProperties.getCurrentTimeouts()
343: .setTimeout(
344: timeoutName,
345: previousTimeoutValue > 0 ? previousTimeoutValue
346: : 60000);
347: //debugOutput("btnFinish = [" + btnFinish + "]", "btnFinish.isEnabled() = [" + btnFinish.isEnabled() + "]");
348: if ((btnFinish != null) && (btnFinish.isEnabled())) {
349: btnFinish.pushNoBlock();
350: Util.wait(500);
351: new QueueTool().waitEmpty();
352: } else {
353: throw new RuntimeException("The button ["
354: + BUTTON_LABEL_FINISH
355: + "] is not found or disabled in the dialog ["
356: + DIALOG_TITLE_NETBEANS_IDE_INSTALLER + "]");
357: }
358: }
359:
360: private JButtonOperator checkButtonFinishAppearance(
361: JDialogOperator dialogOp) {
362: String timeoutName = "ComponentOperator.WaitComponentTimeout";
363: long previousTimeoutValue = JemmyProperties
364: .getCurrentTimeout(timeoutName), newTimeoutValue = 1000;
365: JemmyProperties.getCurrentTimeouts().setTimeout(timeoutName,
366: newTimeoutValue);
367: JButtonOperator btnFinish = null;
368: try {
369: btnFinish = new JButtonOperator(dialogOp,
370: BUTTON_LABEL_FINISH);
371: return btnFinish;
372: } catch (TimeoutExpiredException tee) {
373: Util.wait(500);
374: new QueueTool().waitEmpty();
375: } catch (Exception e) {
376: e.printStackTrace(System.out);
377: throw new RuntimeException(e);
378: } finally {
379: JemmyProperties.getCurrentTimeouts().setTimeout(
380: timeoutName, previousTimeoutValue);
381: }
382: return null;
383: }
384:
385: private void closeDialog() {
386: btnClose.pushNoBlock();
387: Util.wait(500);
388: new QueueTool().waitEmpty();
389: }
390:
391: public static void display() {
392: String timeoutName = "DialogWaiter.WaitDialogTimeout";
393: long previousTimeoutValue = JemmyProperties
394: .getCurrentTimeout(timeoutName), newTimeoutValue = 1500;
395: JemmyProperties.getCurrentTimeouts().setTimeout(timeoutName,
396: newTimeoutValue);
397: try {
398: new JDialogOperator(DIALOG_TITLE_PLUGINS);
399: } catch (TimeoutExpiredException tee) { // dialog isn't open yet
400: Util.getMainMenu().pushMenuNoBlock(
401: MAIN_MENU_ITEM_TOOLS_PLUGINS);
402: Util.wait(1000);
403: new QueueTool().waitEmpty();
404: } catch (Exception e) {
405: e.printStackTrace(System.out);
406: throw new RuntimeException(e);
407: } finally {
408: JemmyProperties.getCurrentTimeouts().setTimeout(
409: timeoutName,
410: previousTimeoutValue > 0 ? previousTimeoutValue
411: : 60000);
412: }
413: }
414:
415: public JTabbedPaneOperator checkTabbedPane() {
416: if (tabbedPane == null) {
417: tabbedPane = new JTabbedPaneOperator(this );
418: }
419: return tabbedPane;
420: }
421:
422: private JButtonOperator checkButtonClose() {
423: if (btnClose == null) {
424: btnClose = new JButtonOperator(this , BUTTON_LABEL_CLOSE);
425: }
426: return btnClose;
427: }
428:
429: /**
430: * Initializes all necessary controls.
431: */
432: public void verify() {
433: checkTabbedPane();
434: checkButtonClose();
435: }
436:
437: private void debugOutput(Object... dataArray) {
438: System.out.println();
439: for (Object obj : dataArray) {
440: System.out.println(obj.toString());
441: }
442: System.out.println();
443: }
444:
445: //============================================================================//
446: private class DialogWatcher implements Runnable {
447: private String dialogTitle, buttonLabel;
448: private boolean stopWatch = true;
449: private Thread watchThread = new Thread(this );
450:
451: public DialogWatcher(String dialogTitle, String buttonLabel) {
452: this .dialogTitle = dialogTitle;
453: this .buttonLabel = buttonLabel;
454: }
455:
456: public void startWatch() {
457: stopWatch = false;
458: watchThread.start();
459: }
460:
461: public void stopWatch() {
462: stopWatch = true;
463: do { // wait until a thread, which is used in this internal class, is died
464: //debugOutput("+++ watchThread.isAlive() = " + watchThread.isAlive());
465: Util.wait(500);
466: } while (watchThread.isAlive());
467: //debugOutput("+++ watchThread.isAlive() = " + watchThread.isAlive());
468: Util.wait(1000);
469: }
470:
471: public void run() {
472: while (true) {
473: if (stopWatch)
474: return;
475: synchronized (this ) {
476: try {
477: wait(1000);
478: } catch (Exception e) {
479: e.printStackTrace(System.out);
480: throw new RuntimeException(e);
481: }
482: }
483: JDialogOperator dialogOp = checkDialogAppearance();
484: if (dialogOp != null) {
485: new JButtonOperator(dialogOp, buttonLabel)
486: .pushNoBlock();
487: Util.wait(500);
488: new QueueTool().waitEmpty();
489: stopWatch = true;
490: }
491: }
492: }
493:
494: private JDialogOperator checkDialogAppearance() {
495: String timeoutName = "DialogWaiter.WaitDialogTimeout";
496: long previousTimeoutValue = JemmyProperties
497: .getCurrentTimeout(timeoutName), newTimeoutValue = 1000;
498: JemmyProperties.getCurrentTimeouts().setTimeout(
499: timeoutName, newTimeoutValue);
500: try {
501: JDialogOperator dialogOp = new JDialogOperator(
502: dialogTitle);
503: return dialogOp;
504: } catch (TimeoutExpiredException tee) {
505: Util.wait(500);
506: new QueueTool().waitEmpty();
507: } catch (Exception e) {
508: e.printStackTrace(System.out);
509: throw new RuntimeException(e);
510: } finally {
511: JemmyProperties.getCurrentTimeouts().setTimeout(
512: timeoutName, previousTimeoutValue);
513: }
514: return null;
515: }
516: }
517: }
|