1 /* 2 * Copyright (c) 2007, 2017 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 package org.jemmy.control; 26 27 import org.jemmy.JemmyException; 28 import org.jemmy.interfaces.Selectable; 29 import org.jemmy.interfaces.Selector; 30 import org.jemmy.interfaces.Showable; 31 import org.jemmy.timing.State; 32 33 /** 34 * 35 * @param <CONTROL> 36 * @param <STATE> 37 * @author shura 38 */ 39 public class SelectorImpl<CONTROL, STATE> implements Selector<STATE> { 40 41 Wrap<? extends CONTROL> target; 42 Selectable<STATE> selectable; 43 44 /** 45 * 46 * @param target 47 * @param selectable 48 */ 49 public SelectorImpl(Wrap<? extends CONTROL> target, Selectable<STATE> selectable) { 50 this.target = target; 51 this.selectable = selectable; 52 } 53 54 /** 55 * 56 * @param state 57 */ 58 @SuppressWarnings("unchecked") 59 public void select(final STATE state) { 60 if (target.is(Showable.class)) { 61 target.as(Showable.class).shower().show(); 62 } 63 int attempts = 0; 64 if (!selectable.getState().equals(state)) { 65 do { 66 final STATE currentState = selectable.getState(); 67 if (attempts >= selectable.getStates().size()) { 68 throw new JemmyException("State is not reached in " + attempts + " attempts", state); 69 } 70 target.mouse().click(clickCount(state)); 71 target.getEnvironment().getWaiter(Wrap.WAIT_STATE_TIMEOUT.getName()).ensureState(new State() { 72 73 public Object reached() { 74 return selectable.getState().equals(currentState) ? null : ""; 75 } 76 77 @Override 78 public String toString() { 79 return "selectable state (" + selectable.getState() + ") equals '" + state + "'"; 80 } 81 82 }); 83 attempts++; 84 } while (!selectable.getState().equals(state)); 85 } 86 } 87 88 private int clickCount(STATE state) { 89 int current = selectable.getStates().indexOf(selectable.getState()); 90 int desired = selectable.getStates().indexOf(state); 91 if (desired >= current) { 92 return desired - current; 93 } else { 94 return selectable.getStates().size() - current + desired; 95 } 96 } 97 98 private class StateChangeState implements State<STATE> { 99 100 Selectable<STATE> source; 101 STATE original; 102 103 public StateChangeState(Selectable<STATE> source) { 104 this.source = source; 105 this.original = source.getState(); 106 } 107 108 public STATE reached() { 109 return (source.getState() != original) ? source.getState() : null; 110 } 111 } 112 }