Coverage Report - org.eclipse.swtbot.swt.finder.keyboard.KeyboardLayout
 
Classes in this File Line Coverage Branch Coverage Complexity
KeyboardLayout
77%
38/49
71%
10/14
2.364
 
 1  
 /*******************************************************************************
 2  
  * Copyright (c) 2009 Ketan Padegaonkar and others.
 3  
  * All rights reserved. This program and the accompanying materials
 4  
  * are made available under the terms of the Eclipse Public License v1.0
 5  
  * which accompanies this distribution, and is available at
 6  
  * http://www.eclipse.org/legal/epl-v10.html
 7  
  *
 8  
  * Contributors:
 9  
  *     Ketan Padegaonkar - initial API and implementation
 10  
  *******************************************************************************/
 11  
 package org.eclipse.swtbot.swt.finder.keyboard;
 12  
 
 13  
 import java.io.BufferedReader;
 14  
 import java.io.IOException;
 15  
 import java.io.StringReader;
 16  
 import java.net.URL;
 17  
 
 18  
 import org.eclipse.jface.bindings.keys.KeyStroke;
 19  
 import org.eclipse.jface.bindings.keys.ParseException;
 20  
 import org.eclipse.swt.SWT;
 21  
 import org.eclipse.swtbot.swt.finder.utils.BidiMap;
 22  
 import org.eclipse.swtbot.swt.finder.utils.FileUtils;
 23  
 import org.eclipse.swtbot.swt.finder.utils.SWTBotPreferences;
 24  
 
 25  
 /**
 26  
  * Allows mapping of characters to {@link KeyStroke}s based on keyboard layouts.
 27  
  * 
 28  
  * @author Ketan Padegaonkar <KetanPadegaonkar [at] gmail [dot] com>
 29  
  * @version $Id$
 30  
  */
 31  
 class KeyboardLayout {
 32  3
         private final BidiMap<Character, KeyStroke>        keyStrokes        = new BidiMap<Character, KeyStroke>();
 33  
         private final String                                                layoutName;
 34  
 
 35  3
         private KeyboardLayout(String name, URL resource) throws IOException {
 36  3
                 this.layoutName = name;
 37  3
                 initialiseDefaults();
 38  3
                 parseKeyStrokes(resource);
 39  3
         }
 40  
 
 41  
         public String toString() {
 42  0
                 return layoutName + " keyboard layout";
 43  
         }
 44  
 
 45  
         /**
 46  
          * Returns the keystroke for typing the specified character.
 47  
          * <p>
 48  
          * E.g. 'T' will correspond to SHIFT+T. 't' will correspond to 'T'. '!' will correspond to SHIFT+1 on the US
 49  
          * keyboard.
 50  
          * </p>
 51  
          * 
 52  
          * @param ch a character.
 53  
          * @return the keystroke applicable corresponding to the character.
 54  
          */
 55  
         public KeyStroke keyStrokeFor(char ch) {
 56  98
                 KeyStroke keyStroke = keyStrokes.getValue(ch);
 57  98
                 if (keyStroke != null) {
 58  98
                         return keyStroke;
 59  
                 }
 60  0
                 throw new IllegalArgumentException("no stroke available for character '" + ch + "'");
 61  
         }
 62  
 
 63  
         public char toCharacter(KeyStroke key) {
 64  0
                 Character ch = keyStrokes.getKey(key);
 65  0
                 if (ch == null)
 66  0
                         ch = (char) key.getNaturalKey();
 67  0
                 return ch;
 68  
         }
 69  
 
 70  
         /**
 71  
          * @return the default keyboard layout.
 72  
          * @see SWTBotPreferences#KEYBOARD_LAYOUT
 73  
          */
 74  
         public static KeyboardLayout getDefaultKeyboardLayout() {
 75  2
                 return getKeyboardLayout(SWTBotPreferences.KEYBOARD_LAYOUT);
 76  
         }
 77  
 
 78  
         /**
 79  
          * @param layoutName the layout of the keyboard.
 80  
          * @return the keyboard layout corresponding to the specified layout.
 81  
          */
 82  
         public static KeyboardLayout getKeyboardLayout(String layoutName) {
 83  3
                 ClassLoader classLoader = KeyboardLayout.class.getClassLoader();
 84  3
                 URL configURL = classLoader.getResource(toFolder(myPackage() + "." + layoutName) + ".keyboard");
 85  
 
 86  3
                 if (configURL == null)
 87  2
                         configURL = classLoader.getResource(toFolder(layoutName) + ".keyboard");
 88  3
                 if (configURL == null)
 89  0
                         throw new IllegalArgumentException(layoutName + ".keyboard not found, see http://wiki.eclipse.org/SWTBot/Keyboard_Layouts for more information.");
 90  
 
 91  
                 try {
 92  3
                         return new KeyboardLayout(layoutName, configURL);
 93  0
                 } catch (IOException e) {
 94  0
                         throw new IllegalStateException("could not parse " + layoutName + " keyboard layout properties");
 95  
                 }
 96  
         }
 97  
 
 98  
         private static String myPackage() {
 99  3
                 return KeyboardLayout.class.getPackage().getName();
 100  
         }
 101  
 
 102  
         private static String toFolder(String layoutName) {
 103  5
                 return layoutName.replaceAll("\\.", "/");
 104  
         }
 105  
 
 106  
         private void initialiseDefaults() {
 107  33
                 for (char ch = '0'; ch <= '9'; ch++) {
 108  30
                         keyStrokes.put(ch, KeyStroke.getInstance(0, ch));
 109  
                 }
 110  81
                 for (char ch = 'A'; ch <= 'Z'; ch++) {
 111  78
                         keyStrokes.put(Character.toLowerCase(ch), KeyStroke.getInstance(0, ch));
 112  78
                         keyStrokes.put(ch, KeyStroke.getInstance(SWT.SHIFT, ch));
 113  
                 }
 114  3
                 keyStrokes.put('\n', KeyStroke.getInstance(0, '\n'));
 115  3
                 keyStrokes.put('\r', KeyStroke.getInstance(0, '\n'));
 116  3
                 keyStrokes.put('\t', KeyStroke.getInstance(0, '\t'));
 117  3
                 keyStrokes.put('\b', KeyStroke.getInstance(0, '\b'));
 118  3
                 keyStrokes.put(' ', KeyStroke.getInstance(0, ' '));
 119  3
         }
 120  
 
 121  
         private void parseKeyStrokes(URL resource) throws IOException {
 122  3
                 String contents = FileUtils.read(resource);
 123  3
                 BufferedReader in = new BufferedReader(new StringReader(contents));
 124  3
                 parseKeyStrokes(in);
 125  3
         }
 126  
 
 127  
         private void parseKeyStrokes(BufferedReader in) throws IOException {
 128  
                 String line;
 129  40
                 while ((line = in.readLine()) != null) {
 130  34
                         char ch = line.charAt(0);
 131  34
                         String keyStrokeSpec = line.substring(2).replaceAll(" \\+ ", "+");
 132  
                         try {
 133  34
                                 keyStrokes.put(ch, KeyStroke.getInstance(keyStrokeSpec));
 134  0
                         } catch (ParseException e) {
 135  0
                                 throw new RuntimeException(e);
 136  
                         }
 137  
                 }
 138  3
         }
 139  
 }