ContainerOperator.java revision 13978:1993af50385d
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.Container;
27import java.awt.Graphics;
28import java.awt.Insets;
29import java.awt.LayoutManager;
30import java.awt.Point;
31import java.awt.event.ContainerListener;
32
33import org.netbeans.jemmy.ComponentChooser;
34import org.netbeans.jemmy.ComponentSearcher;
35import org.netbeans.jemmy.JemmyException;
36import org.netbeans.jemmy.Outputable;
37import org.netbeans.jemmy.TestOut;
38import org.netbeans.jemmy.TimeoutExpiredException;
39import org.netbeans.jemmy.Timeoutable;
40import org.netbeans.jemmy.Timeouts;
41import org.netbeans.jemmy.Waitable;
42import org.netbeans.jemmy.Waiter;
43
44/**
45 * <BR><BR>Timeouts used: <BR>
46 * ComponentOperator.WaitComponentTimeout - time to wait container displayed
47 * <BR>.
48 *
49 * @see org.netbeans.jemmy.Timeouts
50 *
51 * @author Alexandre Iline (alexandre.iline@oracle.com)
52 *
53 */
54public class ContainerOperator<T extends Container> extends ComponentOperator
55        implements Timeoutable, Outputable {
56
57    private final static long WAIT_SUBCOMPONENT_TIMEOUT = 60000;
58
59    private ComponentSearcher searcher;
60    private Timeouts timeouts;
61    private TestOut output;
62
63    /**
64     * Constructor.
65     *
66     * @param b Container component.
67     */
68    public ContainerOperator(Container b) {
69        super(b);
70        searcher = new ComponentSearcher(b);
71        searcher.setOutput(TestOut.getNullOutput());
72    }
73
74    /**
75     * Constructs a ContainerOperator object.
76     *
77     * @param cont container
78     * @param chooser a component chooser specifying searching criteria.
79     * @param index an index between appropriate ones.
80     */
81    public ContainerOperator(ContainerOperator<?> cont, ComponentChooser chooser, int index) {
82        this((Container) cont.
83                waitSubComponent(new ContainerFinder(chooser),
84                        index));
85        copyEnvironment(cont);
86    }
87
88    /**
89     * Constructs a ContainerOperator object.
90     *
91     * @param cont container
92     * @param chooser a component chooser specifying searching criteria.
93     */
94    public ContainerOperator(ContainerOperator<?> cont, ComponentChooser chooser) {
95        this(cont, chooser, 0);
96    }
97
98    /**
99     * Constructor. Waits component in container first. Uses cont's timeout and
100     * output for waiting and to init operator.
101     *
102     * @param cont Operator pointing a container to search component in.
103     * @param index Ordinal component index.
104     * @throws TimeoutExpiredException
105     */
106    public ContainerOperator(ContainerOperator<?> cont, int index) {
107        this((Container) waitComponent(cont,
108                new ContainerFinder(),
109                index));
110        copyEnvironment(cont);
111    }
112
113    /**
114     * Constructor. Waits component in container first. Uses cont's timeout and
115     * output for waiting and to init operator.
116     *
117     * @param cont Operator pointing a container to search component in.
118     * @throws TimeoutExpiredException
119     */
120    public ContainerOperator(ContainerOperator<?> cont) {
121        this(cont, 0);
122    }
123
124    /**
125     * Searches Container in container.
126     *
127     * @param cont Container to search component in.
128     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
129     * @param index Ordinal component index.
130     * @return Container instance or null if component was not found.
131     */
132    public static Container findContainer(Container cont, ComponentChooser chooser, int index) {
133        return (Container) findComponent(cont, new ContainerFinder(chooser), index);
134    }
135
136    /**
137     * Searches 0'th Container in container.
138     *
139     * @param cont Container to search component in.
140     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
141     * @return Container instance or null if component was not found.
142     */
143    public static Container findContainer(Container cont, ComponentChooser chooser) {
144        return findContainer(cont, chooser, 0);
145    }
146
147    /**
148     * Searches Container in container.
149     *
150     * @param cont Container to search component in.
151     * @param index Ordinal component index.
152     * @return Container instance or null if component was not found.
153     */
154    public static Container findContainer(Container cont, int index) {
155        return findContainer(cont, ComponentSearcher.getTrueChooser(Integer.toString(index) + "'th Container instance"), index);
156    }
157
158    /**
159     * Searches 0'th Container in container.
160     *
161     * @param cont Container to search component in.
162     * @return Container instance or null if component was not found.
163     */
164    public static Container findContainer(Container cont) {
165        return findContainer(cont, 0);
166    }
167
168    /**
169     * Searches Container object which component lies on.
170     *
171     * @param comp Component to find Container under.
172     * @param chooser a chooser specifying searching criteria.
173     * @return Container instance or null if component was not found.
174     */
175    public static Container findContainerUnder(Component comp, ComponentChooser chooser) {
176        return (new ComponentOperator(comp).
177                getContainer(new ContainerFinder(chooser)));
178    }
179
180    /**
181     * Searches Container object which component lies on.
182     *
183     * @param comp Component to find Container under.
184     * @return Container instance or null if component was not found.
185     */
186    public static Container findContainerUnder(Component comp) {
187        return findContainerUnder(comp, ComponentSearcher.getTrueChooser("Container"));
188    }
189
190    /**
191     * Waits Container in container.
192     *
193     * @param cont Container to search component in.
194     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
195     * @param index Ordinal component index.
196     * @return Container instance.
197     * @throws TimeoutExpiredException
198     */
199    public static Container waitContainer(Container cont, ComponentChooser chooser, int index) {
200        return (Container) waitComponent(cont, new ContainerFinder(chooser), index);
201    }
202
203    /**
204     * Waits 0'th Container in container.
205     *
206     * @param cont Container to search component in.
207     * @param chooser org.netbeans.jemmy.ComponentChooser implementation.
208     * @return Container instance.
209     * @throws TimeoutExpiredException
210     */
211    public static Container waitContainer(Container cont, ComponentChooser chooser) {
212        return waitContainer(cont, chooser, 0);
213    }
214
215    /**
216     * Waits Container in container.
217     *
218     * @param cont Container to search component in.
219     * @param index Ordinal component index.
220     * @return Container instance.
221     * @throws TimeoutExpiredException
222     */
223    public static Container waitContainer(Container cont, int index) {
224        return waitContainer(cont, ComponentSearcher.getTrueChooser(Integer.toString(index) + "'th Container instance"), index);
225    }
226
227    /**
228     * Waits 0'th Container in container.
229     *
230     * @param cont Container to search component in.
231     * @return Container instance.
232     * @throws TimeoutExpiredException
233     */
234    public static Container waitContainer(Container cont) {
235        return waitContainer(cont, 0);
236    }
237
238    static {
239        Timeouts.initDefault("ComponentOperator.WaitComponentTimeout", WAIT_SUBCOMPONENT_TIMEOUT);
240    }
241
242    @Override
243    public void setTimeouts(Timeouts timeouts) {
244        super.setTimeouts(timeouts);
245        this.timeouts = timeouts;
246    }
247
248    @Override
249    public Timeouts getTimeouts() {
250        return timeouts;
251    }
252
253    @Override
254    public void setOutput(TestOut out) {
255        output = out;
256        super.setOutput(output.createErrorOutput());
257    }
258
259    @Override
260    public TestOut getOutput() {
261        return output;
262    }
263
264    /**
265     * Searches for a subcomponent.
266     *
267     * @param chooser a chooser specifying searching criteria.
268     * @param index Ordinal component index.
269     * @return Component instance.
270     */
271    public Component findSubComponent(ComponentChooser chooser, int index) {
272        getOutput().printLine("Looking for \"" + chooser.getDescription()
273                + "\" subcomponent");
274        return searcher.findComponent(chooser, index);
275    }
276
277    /**
278     * Searches for a subcomponent.
279     *
280     * @param chooser a chooser specifying searching criteria.
281     * @return Component instance.
282     */
283    public Component findSubComponent(ComponentChooser chooser) {
284        return findSubComponent(chooser, 0);
285    }
286
287    /**
288     * Waits for a subcomponent.
289     *
290     * @param chooser a chooser specifying searching criteria.
291     * @param index Ordinal component index.
292     * @return Component instance.
293     */
294    public Component waitSubComponent(final ComponentChooser chooser, final int index) {
295        getOutput().printLine("Waiting for \"" + chooser.getDescription()
296                + "\" subcomponent");
297        final ComponentSearcher searcher = new ComponentSearcher((Container) getSource());
298        searcher.setOutput(getOutput().createErrorOutput());
299        Waiter<Component, Void> waiter = new Waiter<>(new Waitable<Component, Void>() {
300            @Override
301            public Component actionProduced(Void obj) {
302                return searcher.findComponent(chooser, index);
303            }
304
305            @Override
306            public String getDescription() {
307                return ("Wait for \"" + chooser.getDescription()
308                        + "\" subcomponent to be displayed");
309            }
310
311            @Override
312            public String toString() {
313                return "ContainerOperator.waitSubComponent.Waitable{description = " + getDescription() + '}';
314            }
315        });
316        waiter.setTimeoutsToCloneOf(getTimeouts(), "ComponentOperator.WaitComponentTimeout");
317        waiter.setOutput(getOutput());
318        try {
319            return waiter.waitAction(null);
320        } catch (InterruptedException e) {
321            throw (new JemmyException("Waiting for \"" + chooser.getDescription()
322                    + "\" component has been interrupted", e));
323        }
324    }
325
326    /**
327     * Waits for a subcomponent.
328     *
329     * @param chooser a chooser specifying searching criteria.
330     * @return Component instance.
331     */
332    public Component waitSubComponent(ComponentChooser chooser) {
333        return waitSubComponent(chooser, 0);
334    }
335
336    /**
337     * Waits for a subcomponent and creates an operator.
338     *
339     * @param chooser a chooser specifying searching criteria.
340     * @param index Ordinal component index.
341     * @return Component instance.
342     */
343    public ComponentOperator createSubOperator(ComponentChooser chooser, int index) {
344        return createOperator(waitSubComponent(chooser, index));
345    }
346
347    /**
348     * Waits for a subcomponent and creates an operator.
349     *
350     * @param chooser a chooser specifying searching criteria.
351     * @return Component instance.
352     */
353    public ComponentOperator createSubOperator(ComponentChooser chooser) {
354        return createSubOperator(chooser, 0);
355    }
356
357    ////////////////////////////////////////////////////////
358    //Mapping                                             //
359    /**
360     * Maps {@code Container.add(Component)} through queue
361     */
362    public Component add(final Component component) {
363        return (runMapping(new MapAction<Component>("add") {
364            @Override
365            public Component map() {
366                return ((Container) getSource()).add(component);
367            }
368        }));
369    }
370
371    /**
372     * Maps {@code Container.add(Component, int)} through queue
373     */
374    public Component add(final Component component, final int i) {
375        return (runMapping(new MapAction<Component>("add") {
376            @Override
377            public Component map() {
378                return ((Container) getSource()).add(component, i);
379            }
380        }));
381    }
382
383    /**
384     * Maps {@code Container.add(Component, Object)} through queue
385     */
386    public void add(final Component component, final Object object) {
387        runMapping(new MapVoidAction("add") {
388            @Override
389            public void map() {
390                ((Container) getSource()).add(component, object);
391            }
392        });
393    }
394
395    /**
396     * Maps {@code Container.add(Component, Object, int)} through queue
397     */
398    public void add(final Component component, final Object object, final int i) {
399        runMapping(new MapVoidAction("add") {
400            @Override
401            public void map() {
402                ((Container) getSource()).add(component, object, i);
403            }
404        });
405    }
406
407    /**
408     * Maps {@code Container.add(String, Component)} through queue
409     */
410    public Component add(final String string, final Component component) {
411        return (runMapping(new MapAction<Component>("add") {
412            @Override
413            public Component map() {
414                return ((Container) getSource()).add(string, component);
415            }
416        }));
417    }
418
419    /**
420     * Maps {@code Container.addContainerListener(ContainerListener)}
421     * through queue
422     */
423    public void addContainerListener(final ContainerListener containerListener) {
424        runMapping(new MapVoidAction("addContainerListener") {
425            @Override
426            public void map() {
427                ((Container) getSource()).addContainerListener(containerListener);
428            }
429        });
430    }
431
432    /**
433     * Maps {@code Container.findComponentAt(int, int)} through queue
434     */
435    public Component findComponentAt(final int i, final int i1) {
436        return (runMapping(new MapAction<Component>("findComponentAt") {
437            @Override
438            public Component map() {
439                return ((Container) getSource()).findComponentAt(i, i1);
440            }
441        }));
442    }
443
444    /**
445     * Maps {@code Container.findComponentAt(Point)} through queue
446     */
447    public Component findComponentAt(final Point point) {
448        return (runMapping(new MapAction<Component>("findComponentAt") {
449            @Override
450            public Component map() {
451                return ((Container) getSource()).findComponentAt(point);
452            }
453        }));
454    }
455
456    /**
457     * Maps {@code Container.getComponent(int)} through queue
458     */
459    public Component getComponent(final int i) {
460        return (runMapping(new MapAction<Component>("getComponent") {
461            @Override
462            public Component map() {
463                return ((Container) getSource()).getComponent(i);
464            }
465        }));
466    }
467
468    /**
469     * Maps {@code Container.getComponentCount()} through queue
470     */
471    public int getComponentCount() {
472        return (runMapping(new MapIntegerAction("getComponentCount") {
473            @Override
474            public int map() {
475                return ((Container) getSource()).getComponentCount();
476            }
477        }));
478    }
479
480    /**
481     * Maps {@code Container.getComponents()} through queue
482     */
483    public Component[] getComponents() {
484        return ((Component[]) runMapping(new MapAction<Object>("getComponents") {
485            @Override
486            public Object map() {
487                return ((Container) getSource()).getComponents();
488            }
489        }));
490    }
491
492    /**
493     * Maps {@code Container.getInsets()} through queue
494     */
495    public Insets getInsets() {
496        return (runMapping(new MapAction<Insets>("getInsets") {
497            @Override
498            public Insets map() {
499                return ((Container) getSource()).getInsets();
500            }
501        }));
502    }
503
504    /**
505     * Maps {@code Container.getLayout()} through queue
506     */
507    public LayoutManager getLayout() {
508        return (runMapping(new MapAction<LayoutManager>("getLayout") {
509            @Override
510            public LayoutManager map() {
511                return ((Container) getSource()).getLayout();
512            }
513        }));
514    }
515
516    /**
517     * Maps {@code Container.isAncestorOf(Component)} through queue
518     */
519    public boolean isAncestorOf(final Component component) {
520        return (runMapping(new MapBooleanAction("isAncestorOf") {
521            @Override
522            public boolean map() {
523                return ((Container) getSource()).isAncestorOf(component);
524            }
525        }));
526    }
527
528    /**
529     * Maps {@code Container.paintComponents(Graphics)} through queue
530     */
531    public void paintComponents(final Graphics graphics) {
532        runMapping(new MapVoidAction("paintComponents") {
533            @Override
534            public void map() {
535                ((Container) getSource()).paintComponents(graphics);
536            }
537        });
538    }
539
540    /**
541     * Maps {@code Container.printComponents(Graphics)} through queue
542     */
543    public void printComponents(final Graphics graphics) {
544        runMapping(new MapVoidAction("printComponents") {
545            @Override
546            public void map() {
547                ((Container) getSource()).printComponents(graphics);
548            }
549        });
550    }
551
552    /**
553     * Maps {@code Container.remove(int)} through queue
554     */
555    public void remove(final int i) {
556        runMapping(new MapVoidAction("remove") {
557            @Override
558            public void map() {
559                ((Container) getSource()).remove(i);
560            }
561        });
562    }
563
564    /**
565     * Maps {@code Container.remove(Component)} through queue
566     */
567    public void remove(final Component component) {
568        runMapping(new MapVoidAction("remove") {
569            @Override
570            public void map() {
571                ((Container) getSource()).remove(component);
572            }
573        });
574    }
575
576    /**
577     * Maps {@code Container.removeAll()} through queue
578     */
579    public void removeAll() {
580        runMapping(new MapVoidAction("removeAll") {
581            @Override
582            public void map() {
583                ((Container) getSource()).removeAll();
584            }
585        });
586    }
587
588    /**
589     * Maps {@code Container.removeContainerListener(ContainerListener)}
590     * through queue
591     */
592    public void removeContainerListener(final ContainerListener containerListener) {
593        runMapping(new MapVoidAction("removeContainerListener") {
594            @Override
595            public void map() {
596                ((Container) getSource()).removeContainerListener(containerListener);
597            }
598        });
599    }
600
601    /**
602     * Maps {@code Container.setLayout(LayoutManager)} through queue
603     */
604    public void setLayout(final LayoutManager layoutManager) {
605        runMapping(new MapVoidAction("setLayout") {
606            @Override
607            public void map() {
608                ((Container) getSource()).setLayout(layoutManager);
609            }
610        });
611    }
612
613    //End of mapping                                      //
614    ////////////////////////////////////////////////////////
615    /**
616     * Checks component type.
617     */
618    public static class ContainerFinder extends Finder {
619
620        /**
621         * Constructs ContainerFinder.
622         *
623         * @param sf other searching criteria.
624         */
625        public ContainerFinder(ComponentChooser sf) {
626            super(Container.class, sf);
627        }
628
629        /**
630         * Constructs ContainerFinder.
631         */
632        public ContainerFinder() {
633            super(Container.class);
634        }
635    }
636}
637