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 
  26 package org.jemmy.input;
  27 
  28 
  29 import java.util.Enumeration;
  30 import java.util.Hashtable;
  31 import org.jemmy.env.Environment;
  32 import org.jemmy.interfaces.Keyboard.KeyboardButton;
  33 import org.jemmy.interfaces.Keyboard.KeyboardButtons;
  34 import org.jemmy.interfaces.Keyboard.KeyboardModifier;
  35 import static org.jemmy.interfaces.Keyboard.KeyboardButtons.*;
  36 import static org.jemmy.interfaces.Keyboard.KeyboardModifiers.*;
  37 
  38 
  39 
  40 /**
  41  * Default implementation of CharBindingMap interface.
  42  * Provides a mapping for the following symbols:<BR>
  43  *
  44  * @author shura
  45  */
  46 
  47 public class DefaultCharBindingMap implements CharBindingMap<KeyboardButton, KeyboardModifier> {
  48 
  49     private Hashtable<Character, CharKey> chars;
  50 
  51     /**
  52      * Constructor.
  53      */
  54     public DefaultCharBindingMap() {
  55         initMap();
  56     }
  57 
  58     /**
  59      * Returns the code of the primary key used to type a symbol.
  60      * @param c Character.
  61      * @return a KeyboardButton.
  62      * @see CharBindingMap#getCharKey(char)
  63      */
  64     public KeyboardButton getCharKey(char c) {
  65         CharKey charKey = (CharKey)chars.get(new Character(c));
  66         if (charKey != null) {
  67             return charKey.key;
  68         } else {
  69             return null;
  70         }
  71     }
  72 
  73     /**
  74      * Returns the modifiers that should be pressed to type a symbol.
  75      * @param c Character.
  76      * @return an array of KeyboardModifier constants.
  77      * @see CharBindingMap#getCharModifiers(char)
  78      * @see KeyboardModifier
  79      */
  80     public KeyboardModifier[] getCharModifiers(char c) {
  81         CharKey charKey = (CharKey)chars.get(new Character(c));
  82         if(charKey != null) {
  83             return charKey.modifiers;
  84         } else {
  85             return null;
  86         }
  87     }
  88 
  89     /**
  90      * Returns an array of all supported chars.
  91      * @return an array of chars representing the supported chars values.
  92      */
  93     public char[] getSupportedChars() {
  94         char[] charArray = new char[chars.size()];
  95         Enumeration keys = chars.keys();
  96         int index = 0;
  97         while(keys.hasMoreElements()) {
  98             charArray[index] = ((Character)keys.nextElement()).charValue();
  99         }
 100         return(charArray);
 101     }
 102 
 103     /**
 104      * Removes a char from supported.
 105      * @param c Symbol code.
 106      */
 107     public void removeChar(char c) {
 108         chars.remove(new Character(c));
 109     }
 110 
 111     /**
 112      * Adds a char to supported.
 113      * @param c Symbol code.
 114      * @param key key code.
 115      * @param modifiers a combination of InputEvent MASK fields.
 116      */
 117     public void addChar(char c, KeyboardButton key, KeyboardModifier... modifiers) {
 118         chars.put(new Character(c), new CharKey(key, modifiers));
 119     }
 120 
 121     private void initMap() {
 122         chars = new Hashtable<Character, CharKey>();
 123         //first add letters and digits represented by . fields
 124         KeyboardButtons[] buttons = KeyboardButtons.values();
 125         for(int i = 0; i < buttons.length; i++) {
 126             String name = buttons[i].name();
 127             String letter;
 128             if (name.length() == 1 && Character.isLetter(name.charAt(0))) {
 129                 letter = name;
 130             } else if (name.length() == 2 && name.startsWith("D") && Character.isDigit(name.charAt(1))) {
 131                 letter = name.substring(1);
 132             } else {
 133                 continue;
 134             }
 135             addChar(letter.toLowerCase().charAt(0), buttons[i]);
 136             if(!letter.toUpperCase().equals(letter.toLowerCase())) {
 137                 addChar(letter.toUpperCase().charAt(0), buttons[i], SHIFT_DOWN_MASK);
 138             }
 139         }
 140         //add special simbols
 141         addChar('\t', TAB);
 142         addChar(' ', SPACE);
 143         addChar('!', D1 , SHIFT_DOWN_MASK);
 144         addChar('"', QUOTE , SHIFT_DOWN_MASK);
 145         addChar('#', D3 , SHIFT_DOWN_MASK);
 146         addChar('$', D4 , SHIFT_DOWN_MASK);
 147         addChar('%', D5 , SHIFT_DOWN_MASK);
 148         addChar('&', D7 , SHIFT_DOWN_MASK);
 149         addChar('\'', QUOTE);
 150         addChar('(', D9 , SHIFT_DOWN_MASK);
 151         addChar(')', D0 , SHIFT_DOWN_MASK);
 152         addChar('*', D8 , SHIFT_DOWN_MASK);
 153         addChar(',', COMMA);
 154         addChar('-', MINUS);
 155         addChar('.', PERIOD);
 156         addChar('/', SLASH);
 157         addChar(';', SEMICOLON);
 158         addChar('<', COMMA , SHIFT_DOWN_MASK);
 159         addChar('>', PERIOD , SHIFT_DOWN_MASK);
 160         addChar('?', SLASH , SHIFT_DOWN_MASK);
 161         addChar('@', D2 , SHIFT_DOWN_MASK);
 162         addChar('[', OPEN_BRACKET);
 163         addChar(']', CLOSE_BRACKET);
 164         addChar('^', D6 , SHIFT_DOWN_MASK);
 165         addChar('_', MINUS , SHIFT_DOWN_MASK);
 166         addChar('`', BACK_QUOTE);
 167         addChar('{', OPEN_BRACKET , SHIFT_DOWN_MASK);
 168         addChar('|', BACK_SLASH , SHIFT_DOWN_MASK);
 169         addChar('}', CLOSE_BRACKET, SHIFT_DOWN_MASK);
 170         addChar('\n', ENTER);
 171 
 172        if ("sv".equals(Environment.getEnvironment().getProperty("LANG"))) {
 173            addChar('+', PLUS);
 174            addChar(':', PERIOD, SHIFT_DOWN_MASK);
 175            addChar('\\', PLUS, CTRL_DOWN_MASK, ALT_DOWN_MASK);
 176            addChar('~', DEAD_DIAERESIS, CTRL_DOWN_MASK, ALT_DOWN_MASK);
 177            addChar('=', D0, SHIFT_DOWN_MASK);
 178        } else {
 179            addChar('+', EQUALS , SHIFT_DOWN_MASK);
 180            addChar(':', SEMICOLON , SHIFT_DOWN_MASK);
 181            addChar('\\', BACK_SLASH);
 182            addChar('~', BACK_QUOTE , SHIFT_DOWN_MASK);
 183            addChar('=', EQUALS);
 184        }
 185     }
 186 
 187     private static class CharKey {
 188         public KeyboardButton key;
 189         public KeyboardModifier modifiers[];
 190         public CharKey(KeyboardButton key, KeyboardModifier... modifiers) {
 191             this.key = key;
 192             this.modifiers = modifiers;
 193         }
 194     }
 195 
 196 }