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