1/* 2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23package org.netbeans.jemmy.operators; 24 25import java.awt.Component; 26import java.awt.Dialog; 27import java.awt.Window; 28import java.util.Hashtable; 29 30import org.netbeans.jemmy.ComponentChooser; 31import org.netbeans.jemmy.DialogWaiter; 32import org.netbeans.jemmy.JemmyProperties; 33import org.netbeans.jemmy.TestOut; 34import org.netbeans.jemmy.TimeoutExpiredException; 35import org.netbeans.jemmy.Timeouts; 36 37/** 38 * <BR><BR>Timeouts used: <BR> 39 * DialogWaiter.WaitDialogTimeout - time to wait dialog displayed <BR> 40 * DialogWaiter.AfterDialogTimeout - time to sleep after dialog has been 41 * dispayed <BR> 42 * ComponentOperator.WaitStateTimeout - time to wait for title <BR>. 43 * 44 * @see org.netbeans.jemmy.Timeouts 45 * 46 * @author Alexandre Iline (alexandre.iline@oracle.com) 47 * 48 */ 49public class DialogOperator extends WindowOperator { 50 51 /** 52 * Identifier for a title property. 53 * 54 * @see #getDump 55 */ 56 public static final String TITLE_DPROP = "Title"; 57 58 /** 59 * Identifier for a modal property. 60 * 61 * @see #getDump 62 */ 63 public static final String IS_MODAL_DPROP = "Modal"; 64 65 /** 66 * Identifier for a resizable property. 67 * 68 * @see #getDump 69 */ 70 public static final String IS_RESIZABLE_DPROP = "Resizable"; 71 72 /** 73 * Constructs a DialogOperator object. 74 * 75 * @param w window 76 */ 77 public DialogOperator(Dialog w) { 78 super(w); 79 } 80 81 /** 82 * Constructs a DialogOperator object. 83 * 84 * @param chooser a component chooser specifying searching criteria. 85 * @param index an index between appropriate ones. 86 * @param env an operator to copy environment from. 87 */ 88 public DialogOperator(ComponentChooser chooser, int index, Operator env) { 89 this(waitDialog(new DialogFinder(chooser), 90 index, 91 env.getTimeouts(), 92 env.getOutput())); 93 copyEnvironment(env); 94 } 95 96 /** 97 * Constructs a DialogOperator object. 98 * 99 * @param chooser a component chooser specifying searching criteria. 100 * @param index an index between appropriate ones. 101 */ 102 public DialogOperator(ComponentChooser chooser, int index) { 103 this(chooser, index, Operator.getEnvironmentOperator()); 104 } 105 106 /** 107 * Constructs a DialogOperator object. 108 * 109 * @param chooser a component chooser specifying searching criteria. 110 */ 111 public DialogOperator(ComponentChooser chooser) { 112 this(chooser, 0); 113 } 114 115 /** 116 * Constructs a DialogOperator object. 117 * 118 * @param owner window - owner 119 * @param chooser a component chooser specifying searching criteria. 120 * @param index an index between appropriate ones. 121 */ 122 public DialogOperator(WindowOperator owner, ComponentChooser chooser, int index) { 123 this((Dialog) owner. 124 waitSubWindow(new DialogFinder(chooser), 125 index)); 126 copyEnvironment(owner); 127 } 128 129 /** 130 * Constructs a DialogOperator object. 131 * 132 * @param owner window - owner 133 * @param chooser a component chooser specifying searching criteria. 134 */ 135 public DialogOperator(WindowOperator owner, ComponentChooser chooser) { 136 this(owner, chooser, 0); 137 } 138 139 /** 140 * Constructor. Waits for a dialog to show. The dialog is identified as the 141 * {@code index+1}'th {@code java.awt.Dialog} that shows, is owned 142 * by the window managed by the {@code WindowOperator} 143 * {@code owner}, and that has the desired title. Uses owner's timeout 144 * and output for waiting and to init this operator. 145 * 146 * @param owner Operator pointing to a window owner. 147 * @param title The desired title. 148 * @param index Ordinal index. The first dialog has {@code index} 0. 149 * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean) 150 * @throws TimeoutExpiredException 151 */ 152 public DialogOperator(WindowOperator owner, String title, int index) { 153 this(waitDialog(owner, 154 new DialogByTitleFinder(title, 155 owner.getComparator()), 156 index)); 157 copyEnvironment(owner); 158 } 159 160 /** 161 * Uses owner's timeout and output for waiting and to init operator. Waits 162 * for a dialog to show. The dialog is identified as the first 163 * {@code java.awt.Dialog} that shows, is owned by the window managed 164 * by the {@code WindowOperator} {@code owner}, and that has the 165 * desired title. Uses owner's timeout and output for waiting and to init 166 * this operator. 167 * 168 * @param owner Operator pointing to a window owner. 169 * @param title The desired title. 170 * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean) 171 * @throws TimeoutExpiredException 172 */ 173 public DialogOperator(WindowOperator owner, String title) { 174 this(owner, title, 0); 175 } 176 177 /** 178 * Constructor. Waits for the index'th dialog between owner's children. Uses 179 * owner'th timeout and output for waiting and to init operator. 180 * 181 * @param owner Operator pointing to a window owner. 182 * @param index Ordinal component index. 183 * @throws TimeoutExpiredException 184 */ 185 public DialogOperator(WindowOperator owner, int index) { 186 this(waitDialog(owner, 187 new DialogFinder(), 188 index)); 189 copyEnvironment(owner); 190 } 191 192 /** 193 * Constructor. Waits for the first dialog between owner's children. Uses 194 * owner'th timeout and output for waiting and to init operator. 195 * 196 * @param owner Operator pointing to a window owner. 197 * @throws TimeoutExpiredException 198 */ 199 public DialogOperator(WindowOperator owner) { 200 this(owner, 0); 201 } 202 203 /** 204 * Constructor. Waits for the dialog with "title" subtitle. Constructor can 205 * be used in complicated cases when output or timeouts should differ from 206 * default. 207 * 208 * @param title a window title 209 * @param index Ordinal component index. 210 * @param env an operator to copy environment from. 211 * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean) 212 * @throws TimeoutExpiredException 213 */ 214 public DialogOperator(String title, int index, Operator env) { 215 this(new DialogByTitleFinder(title, 216 env.getComparator()), 217 index, 218 env); 219 } 220 221 /** 222 * Constructor. Waits for the dialog with "title" subtitle. Uses current 223 * timeouts and output values. 224 * 225 * @param title a window title 226 * @param index Ordinal component index. 227 * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean) 228 * @see JemmyProperties#getCurrentTimeouts() 229 * @see JemmyProperties#getCurrentOutput() 230 * @throws TimeoutExpiredException 231 */ 232 public DialogOperator(String title, int index) { 233 this(title, index, 234 ComponentOperator.getEnvironmentOperator()); 235 } 236 237 /** 238 * Constructor. Waits for the dialog with "title" subtitle. Uses current 239 * timeouts and output values. 240 * 241 * @param title a window title 242 * @see ComponentOperator#isCaptionEqual(String, String, boolean, boolean) 243 * @see JemmyProperties#getCurrentTimeouts() 244 * @see JemmyProperties#getCurrentOutput() 245 * @throws TimeoutExpiredException 246 */ 247 public DialogOperator(String title) { 248 this(title, 0); 249 } 250 251 /** 252 * Constructor. Waits for the index'th dialog. Uses current timeout and 253 * output for waiting and to init operator. 254 * 255 * @param index Ordinal component index. 256 * @throws TimeoutExpiredException 257 */ 258 public DialogOperator(int index) { 259 this(waitDialog(new DialogFinder(), 260 index, 261 ComponentOperator.getEnvironmentOperator().getTimeouts(), 262 ComponentOperator.getEnvironmentOperator().getOutput())); 263 copyEnvironment(ComponentOperator.getEnvironmentOperator()); 264 } 265 266 /** 267 * Constructor. Waits for the first dialog. Uses current timeout and output 268 * for waiting and to init operator. 269 * 270 * @throws TimeoutExpiredException 271 */ 272 public DialogOperator() { 273 this(0); 274 } 275 276 /** 277 * Waits for title. Uses getComparator() comparator. 278 * 279 * @param title Title to wait for. 280 */ 281 public void waitTitle(final String title) { 282 getOutput().printLine("Wait \"" + title + "\" title of dialog \n : " 283 + toStringSource()); 284 getOutput().printGolden("Wait \"" + title + "\" title"); 285 waitState(new DialogByTitleFinder(title, getComparator())); 286 } 287 288 /** 289 * Returns information about component. 290 */ 291 @Override 292 public Hashtable<String, Object> getDump() { 293 Hashtable<String, Object> result = super.getDump(); 294 if (((Dialog) getSource()).getTitle() != null) { 295 result.put(TITLE_DPROP, ((Dialog) getSource()).getTitle()); 296 } 297 result.put(IS_MODAL_DPROP, ((Dialog) getSource()).isModal() ? "true" : "false"); 298 result.put(IS_RESIZABLE_DPROP, ((Dialog) getSource()).isResizable() ? "true" : "false"); 299 return result; 300 } 301 302 //////////////////////////////////////////////////////// 303 //Mapping // 304 /** 305 * Maps {@code Dialog.getTitle()} through queue 306 */ 307 public String getTitle() { 308 return (runMapping(new MapAction<String>("getTitle") { 309 @Override 310 public String map() { 311 return ((Dialog) getSource()).getTitle(); 312 } 313 })); 314 } 315 316 /** 317 * Maps {@code Dialog.isModal()} through queue 318 */ 319 public boolean isModal() { 320 return (runMapping(new MapBooleanAction("isModal") { 321 @Override 322 public boolean map() { 323 return ((Dialog) getSource()).isModal(); 324 } 325 })); 326 } 327 328 /** 329 * Maps {@code Dialog.isResizable()} through queue 330 */ 331 public boolean isResizable() { 332 return (runMapping(new MapBooleanAction("isResizable") { 333 @Override 334 public boolean map() { 335 return ((Dialog) getSource()).isResizable(); 336 } 337 })); 338 } 339 340 /** 341 * Maps {@code Dialog.setModal(boolean)} through queue 342 */ 343 public void setModal(final boolean b) { 344 runMapping(new MapVoidAction("setModal") { 345 @Override 346 public void map() { 347 ((Dialog) getSource()).setModal(b); 348 } 349 }); 350 } 351 352 /** 353 * Maps {@code Dialog.setResizable(boolean)} through queue 354 */ 355 public void setResizable(final boolean b) { 356 runMapping(new MapVoidAction("setResizable") { 357 @Override 358 public void map() { 359 ((Dialog) getSource()).setResizable(b); 360 } 361 }); 362 } 363 364 /** 365 * Maps {@code Dialog.setTitle(String)} through queue 366 */ 367 public void setTitle(final String string) { 368 runMapping(new MapVoidAction("setTitle") { 369 @Override 370 public void map() { 371 ((Dialog) getSource()).setTitle(string); 372 } 373 }); 374 } 375 376 //End of mapping // 377 //////////////////////////////////////////////////////// 378 /** 379 * A method to be used from subclasses. Uses timeouts and output passed as 380 * parameters during the waiting. 381 * 382 * @param chooser org.netbeans.jemmy.ComponentChooser implementation. 383 * @param index Ordinal component index. 384 * @param timeouts timeouts to be used during the waiting. 385 * @param output an output to be used during the waiting. 386 * @return Component instance or null if component was not found. 387 */ 388 protected static Dialog waitDialog(ComponentChooser chooser, int index, 389 Timeouts timeouts, TestOut output) { 390 try { 391 DialogWaiter waiter = new DialogWaiter(); 392 waiter.setTimeouts(timeouts); 393 waiter.setOutput(output); 394 return waiter.waitDialog(new DialogFinder(chooser), index); 395 } catch (InterruptedException e) { 396 output.printStackTrace(e); 397 return null; 398 } 399 } 400 401 /** 402 * A method to be used from subclasses. Uses {@code owner}'s timeouts 403 * and output during the waiting. 404 * 405 * @param owner a window - dialog owner. 406 * @param chooser org.netbeans.jemmy.ComponentChooser implementation. 407 * @param index Ordinal component index. 408 * @return Component instance or null if component was not found. 409 */ 410 protected static Dialog waitDialog(WindowOperator owner, ComponentChooser chooser, int index) { 411 return (waitDialog((Window) owner.getSource(), 412 chooser, index, 413 owner.getTimeouts(), owner.getOutput())); 414 } 415 416 /** 417 * A method to be used from subclasses. Uses timeouts and output passed as 418 * parameters during the waiting. 419 * 420 * @param owner a window - dialog owner. 421 * @param chooser org.netbeans.jemmy.ComponentChooser implementation. 422 * @param index Ordinal component index. 423 * @param timeouts timeouts to be used during the waiting. 424 * @param output an output to be used during the waiting. 425 * @return Component instance or null if component was not found. 426 */ 427 protected static Dialog waitDialog(Window owner, ComponentChooser chooser, int index, 428 Timeouts timeouts, TestOut output) { 429 try { 430 DialogWaiter waiter = new DialogWaiter(); 431 waiter.setTimeouts(timeouts); 432 waiter.setOutput(output); 433 return (waiter. 434 waitDialog(owner, new DialogFinder(chooser), index)); 435 } catch (InterruptedException e) { 436 JemmyProperties.getCurrentOutput().printStackTrace(e); 437 return null; 438 } 439 } 440 441 /** 442 * Checks component type. 443 */ 444 public static class DialogFinder extends Finder { 445 446 /** 447 * Constructs DialogFinder. 448 * 449 * @param sf other searching criteria. 450 */ 451 public DialogFinder(ComponentChooser sf) { 452 super(Dialog.class, sf); 453 } 454 455 /** 456 * Constructs DialogFinder. 457 */ 458 public DialogFinder() { 459 super(Dialog.class); 460 } 461 } 462 463 /** 464 * Allows to find component by title. 465 */ 466 public static class DialogByTitleFinder implements ComponentChooser { 467 468 String title; 469 StringComparator comparator; 470 471 /** 472 * Constructs DialogByTitleFinder. 473 * 474 * @param t a text pattern 475 * @param comparator specifies string comparision algorithm. 476 */ 477 public DialogByTitleFinder(String t, StringComparator comparator) { 478 title = t; 479 this.comparator = comparator; 480 } 481 482 /** 483 * Constructs DialogByTitleFinder. 484 * 485 * @param t a text pattern 486 */ 487 public DialogByTitleFinder(String t) { 488 this(t, Operator.getDefaultStringComparator()); 489 } 490 491 @Override 492 public boolean checkComponent(Component comp) { 493 if (comp instanceof Dialog) { 494 if (comp.isShowing() && ((Dialog) comp).getTitle() != null) { 495 return comparator.equals(((Dialog) comp).getTitle(), title); 496 } 497 } 498 return false; 499 } 500 501 @Override 502 public String getDescription() { 503 return "Dialog with title \"" + title + "\""; 504 } 505 506 @Override 507 public String toString() { 508 return "DialogByTitleFinder{" + "title=" + title + ", comparator=" + comparator + '}'; 509 } 510 } 511} 512