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.
   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  */
  23 package org.jemmy.input;
  24 
  25 import org.jemmy.action.Action;
  26 import org.jemmy.control.Wrap;
  27 import org.jemmy.env.Environment;
  28 import org.jemmy.env.Timeout;
  29 import org.jemmy.interfaces.Focusable;
  30 import org.jemmy.interfaces.Keyboard;
  31 import org.jemmy.interfaces.Modifier;
  32 
  33 /**
  34  * KeyDriver
  35  *
  36  * @author Alexandre Iline(alexandre.iline@sun.com)
  37  */
  38 public class KeyboardImpl implements Keyboard {
  39 
  40     private final CharBindingMap<KeyboardButton, KeyboardModifier> map;
  41     private final Environment env;
  42     private final Wrap<?> target;
  43     private final RobotDriver robotDriver;
  44     private volatile boolean detached = false;
  45     /**
  46      * Constructs a KeyRobotDriver object.
  47      * @param target
  48      */
  49     public KeyboardImpl(Wrap<?> target) {
  50         //TODO: super(target.getEnvironment().getTimeout(RobotDriver.ROBOT_DELAY_TIMEOUT_NAME));
  51         robotDriver = new RobotDriver(target.getEnvironment());
  52         this.env = target.getEnvironment();
  53         this.map = target.getEnvironment().getBindingMap();
  54         this.target = target;
  55     }
  56 
  57     static {
  58         //TODO: Environment.getEnvironment().setTimeout(new Timeout(RobotDriver.ROBOT_DELAY_TIMEOUT_NAME, 10));
  59         Environment.getEnvironment().setTimeout(new Timeout(PUSH.getName(), 100));
  60         Environment.getEnvironment().setBindingMap(new DefaultCharBindingMap());
  61     }
  62 
  63     private void runAction(Action action) {
  64         if(detached) {
  65             target.getEnvironment().getExecutor().executeDetached(target.getEnvironment(), false, action);
  66         } else {
  67             target.getEnvironment().getExecutor().execute(target.getEnvironment(), false, action);
  68         }
  69     }
  70 
  71     /**
  72      *
  73      * @return Environment
  74      */
  75     public Environment getEnvironment() {
  76         return env;
  77     }
  78 
  79     /**
  80      *
  81      * @param kbdButton
  82      * @param modifiers
  83      * @param pushTime
  84      */
  85     public void pushKey(final KeyboardButton kbdButton, final Modifier modifiers[], final Timeout pushTime) {
  86         runAction(new Action() {
  87             public void run(Object... parameters) {
  88                 if(target.is(Focusable.class)) target.as(Focusable.class).focuser().focus();
  89                 pressKey(kbdButton, modifiers);
  90                 pushTime.sleep();
  91                 releaseKey(kbdButton, modifiers);
  92             }
  93             @Override
  94             public String toString() {
  95                 return "push " + kbdButton + " key with " + modifiers + " modifiers";
  96             }
  97         });
  98     }
  99 
 100     /**
 101      *
 102      * @param keyChar
 103      * @param pushTime
 104      */
 105     @Override
 106     public void typeChar(char keyChar, Timeout pushTime) {
 107         pushKey(pushTime, map.getCharKey(keyChar), map.getCharModifiers(keyChar));
 108     }
 109 
 110     /**
 111      * Press the keyboard key specified by kbdButton preceding with
 112      * pressing of modifier buttons specified by modifiers
 113      * @param kbdButton one of InputEvent.VK_* constants
 114      * @param modifiers combination of InputEvent.*_DOWN_MASK constants
 115      * @see java.awt.event.InputEvent
 116      */
 117     @Override
 118     public void pressKey(final KeyboardButton kbdButton, final Modifier... modifiers) {
 119         runAction(new Action() {
 120             public void run(Object... parameters) {
 121                 robotDriver.pressKey(kbdButton, modifiers);
 122             }
 123             @Override
 124             public String toString() {
 125                 return "press " + kbdButton + " key with " + modifiers + " modifiers";
 126             }
 127         });
 128     }
 129 
 130     /**
 131      * Release the keyboard key specified by kbdButton and then release
 132      * all the modifier keys specified by modifiers
 133      * @param kbdButton one of InputEvent.VK_* constants
 134      * @param modifiers combination of InputEvent.*_DOWN_MASK constants
 135      * @see java.awt.event.InputEvent
 136      */
 137     @Override
 138     public void releaseKey(final KeyboardButton kbdButton, final Modifier... modifiers) {
 139         runAction(new Action() {
 140             public void run(Object... parameters) {
 141                 robotDriver.releaseKey(kbdButton, modifiers);
 142             }
 143             @Override
 144             public String toString() {
 145                 return "press " + kbdButton + " key with " + modifiers + " modifiers";
 146             }
 147         });
 148     }
 149 
 150     /**
 151      *
 152      * @param kbdButton
 153      */
 154     @Override
 155     public void pressKey(KeyboardButton kbdButton) {
 156         pressKey(kbdButton, new Modifier[]{});
 157     }
 158 
 159     /**
 160      *
 161      * @param kbdButton
 162      */
 163     @Override
 164     public void releaseKey(KeyboardButton kbdButton) {
 165         releaseKey(kbdButton, new Modifier[]{});
 166     }
 167 
 168     /**
 169      *
 170      * @param kbdButton
 171      * @param modifiers
 172      */
 173     @Override
 174     public void pushKey(KeyboardButton kbdButton, Modifier... modifiers) {
 175         pushKey(kbdButton, modifiers, getEnvironment().getTimeout(PUSH.getName()));
 176     }
 177 
 178     /**
 179      *
 180      * @param kbdButton
 181      */
 182     @Override
 183     public void pushKey(KeyboardButton kbdButton) {
 184         pushKey(kbdButton, new Modifier[]{});
 185     }
 186 
 187     /**
 188      *
 189      * @param keyChar
 190      */
 191     @Override
 192     public void typeChar(char keyChar) {
 193         typeChar(keyChar, getEnvironment().getTimeout(PUSH.getName()));
 194     }
 195 
 196     @Override
 197     public Keyboard detached() {
 198         detached = true;
 199         return this;
 200     }
 201 
 202     @Override
 203     public void pushKey(Timeout pushTime, KeyboardButton key, Modifier... modifiers) {
 204         pushKey(key, modifiers, pushTime);
 205     }
 206 }