View Javadoc

1   /*
2    * $Id: KeyTools.java,v 1.18 2011/06/16 09:29:41 jbmeslin Exp $
3    * 
4    */
5   package org.rcfaces.core.internal.util;
6   
7   import java.util.StringTokenizer;
8   
9   import javax.faces.FacesException;
10  
11  import org.rcfaces.core.internal.converter.KeyFlagsConverter;
12  import org.rcfaces.core.internal.converter.VirtualKeyConverter;
13  import org.rcfaces.core.internal.lang.StringAppender;
14  
15  /**
16   * 
17   * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
18   * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
19   */
20  public class KeyTools {
21      private static final String REVISION = "$Revision: 1.18 $";
22  
23      public static State parseKeyBinding(String keyBinding) {
24          StringTokenizer st = new StringTokenizer(keyBinding, "+ ", true);
25  
26          boolean compose = false;
27  
28          State state = new State(keyBinding);
29  
30          for (; st.hasMoreTokens();) {
31              String token = st.nextToken();
32  
33              if (token.length() == 1) {
34                  char c = token.charAt(0);
35  
36                  if (c == '+') {
37                      if (compose) {
38                          compose = false;
39                          continue;
40                      }
41  
42                      state.setCharacter('c');
43                      compose = true;
44                      continue;
45                  }
46  
47                  if (Character.isWhitespace(c)) {
48                      continue;
49                  }
50  
51                  compose = true;
52                  state.setCharacter(Character.toUpperCase(c));
53                  continue;
54              }
55  
56              compose = true;
57              String utoken = token.toUpperCase();
58  
59              Integer flag = KeyFlagsConverter.convertUpperCase(utoken);
60              if (flag != null) {
61                  state.addFlag(flag.intValue());
62                  continue;
63              }
64  
65              Integer vkey = VirtualKeyConverter.convertUpperCase(utoken);
66              if (vkey != null) {
67                  state.setVirtualKey(vkey);
68                  continue;
69              }
70  
71              throw new FacesException("Too many character for '" + token
72                      + "' in expression '" + keyBinding + "'.");
73          }
74  
75          if (compose == false) {
76              throw new FacesException("Invalid keyBinding expression '"
77                      + keyBinding + "'.");
78          }
79  
80          return state;
81      }
82  
83      /**
84       * 
85       * @author Olivier Oeuillot (latest modification by $Author: jbmeslin $)
86       * @version $Revision: 1.18 $ $Date: 2011/06/16 09:29:41 $
87       */
88      public static final class State {
89          private static final String REVISION = "$Revision: 1.18 $";
90  
91          private final String keyBinding;
92  
93          public int keyFlags;
94  
95          public Integer virtualKey;
96  
97          public char character;
98  
99          public State(String keyBinding) {
100             this.keyBinding = keyBinding;
101         }
102 
103         public void setCharacter(char character) {
104             if (this.character != 0) {
105                 throw new FacesException(
106                         "Can not specify more one character in keyBinding '"
107                                 + keyBinding + "'.");
108             }
109             if (virtualKey != null) {
110                 throw new FacesException(
111                         "Can not specify a character when a virtualKey is already defined in keyBinding '"
112                                 + keyBinding + "'.");
113             }
114 
115             this.character = character;
116         }
117 
118         public void addFlag(int keyFlags) {
119             this.keyFlags |= keyFlags;
120         }
121 
122         public void setVirtualKey(Integer virtualKey) {
123             if (this.virtualKey != null) {
124                 throw new FacesException(
125                         "Only one virtual key can be defined in keyBinding '"
126                                 + keyBinding + "'.");
127             }
128             if (character != 0) {
129                 throw new FacesException(
130                         "Can not specify a virtual key when a character is already defined in keyBinding '"
131                                 + keyBinding + "'.");
132             }
133             this.virtualKey = virtualKey;
134         }
135 
136         public String format() {
137             StringAppender sb = new StringAppender(32);
138 
139             if ((keyFlags & KeyFlagsConverter.CONTROL_FLAG) > 0) {
140                 sb.append("Ctrl");
141             }
142             if ((keyFlags & KeyFlagsConverter.META_FLAG) > 0) {
143                 if (sb.length() > 0) {
144                     sb.append('+');
145                 }
146                 sb.append("Meta");
147             }
148             if ((keyFlags & KeyFlagsConverter.ALT_FLAG) > 0) {
149                 if (sb.length() > 0) {
150                     sb.append('+');
151                 }
152                 sb.append("Alt");
153             }
154             if ((keyFlags & KeyFlagsConverter.SHIFT_FLAG) > 0) {
155                 if (sb.length() > 0) {
156                     sb.append('+');
157                 }
158                 sb.append("Shift");
159             }
160 
161             if (character > 0) {
162                 if (sb.length() > 0) {
163                     sb.append('+');
164                 }
165                 sb.append(character);
166 
167             } else if (virtualKey != null) {
168                 if (sb.length() > 0) {
169                     sb.append('+');
170                 }
171                 sb.append(VirtualKeyConverter.SINGLETON.getAsString(null, null,
172                         virtualKey));
173             }
174 
175             return sb.toString();
176         }
177     }
178 }