001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.pos.adaptor;
019:
020: import java.awt.Component;
021: import java.awt.Container;
022: import java.awt.event.KeyEvent;
023: import java.awt.event.KeyListener;
024: import java.util.Iterator;
025: import java.util.LinkedList;
026: import java.util.List;
027: import java.util.Map;
028:
029: import org.ofbiz.base.util.Debug;
030: import org.ofbiz.base.util.UtilProperties;
031:
032: import org.apache.commons.collections.map.LinkedMap;
033:
034: /**
035: * KeyboardAdaptor - Handles reading keyboard input
036: *
037: */
038: public class KeyboardAdaptor {
039:
040: public static final String module = KeyboardAdaptor.class.getName();
041:
042: public static final int EVENT_RELEASED = 2;
043: public static final int EVENT_PRESSED = 1;
044: public static final int EVENT_TYPED = 3;
045:
046: public static final int KEYBOARD_DATA = 100;
047: public static final int SCANNER_DATA = 101;
048: public static final int MSR_DATA = 102;
049: public static final int ALL_DATA = 999;
050:
051: protected static List loadedComponents = new LinkedList();
052: protected static Map receivers = new LinkedMap();
053: protected static KeyboardAdaptor adaptor = null;
054: protected static boolean running = true;
055:
056: protected KeyboardListener listener = null;
057:
058: public static KeyboardAdaptor getInstance(
059: KeyboardReceiver receiver, int dataType) {
060: if (adaptor == null) {
061: synchronized (KeyboardAdaptor.class) {
062: if (adaptor == null) {
063: adaptor = new KeyboardAdaptor();
064: }
065: }
066: }
067:
068: if (receiver != null && dataType > -1) {
069: receivers.put(receiver, new Integer(dataType));
070: }
071: return adaptor;
072: }
073:
074: public static KeyboardAdaptor getInstance() {
075: return getInstance(null, -1);
076: }
077:
078: public static void attachComponents(Component[] coms,
079: boolean recurse) {
080: // check the adaptor
081: if (adaptor == null) {
082: KeyboardAdaptor.getInstance();
083: }
084:
085: // add the new ones to listen on
086: if (adaptor != null && coms != null) {
087: adaptor.addComponents(coms, recurse);
088: }
089: }
090:
091: public static void attachComponents(Component[] coms) {
092: KeyboardAdaptor.attachComponents(coms, true);
093: }
094:
095: public static void attachComponents(Container parent,
096: boolean recurse) {
097: KeyboardAdaptor.attachComponents(new Component[] { parent },
098: recurse);
099: }
100:
101: public static void attachComponents(Container parent) {
102: KeyboardAdaptor.attachComponents(parent, true);
103: }
104:
105: public static void stop() {
106: running = false;
107: }
108:
109: private KeyboardAdaptor() {
110: this .listener = new KeyboardListener();
111: this .listener.setDaemon(false);
112: this .listener.setName(listener.toString());
113: this .listener.start();
114: KeyboardAdaptor.adaptor = this ;
115: }
116:
117: private void addComponents(Component[] coms, boolean recurse) {
118: listener.reader.configureComponents(coms, recurse);
119: }
120:
121: private class KeyboardListener extends Thread {
122:
123: public final Long MAX_WAIT_SCANNER = new Long(Long
124: .parseLong(UtilProperties.getPropertyValue(
125: "jpos.properties", "MaxWaitScanner", "100")));
126: public final Long MAX_WAIT_KEYBOARD = new Long(Long
127: .parseLong(UtilProperties.getPropertyValue(
128: "jpos.properties", "MaxWaitKeyboard", "10")));
129: // By default keyboard entry (login & password 1st)
130: public Long MAX_WAIT = MAX_WAIT_KEYBOARD;
131:
132: private List keyCodeData = new LinkedList();
133: private List keyCharData = new LinkedList();
134: private long lastKey = -1;
135: private KeyReader reader = null;
136:
137: public KeyboardListener() {
138: this .reader = new KeyReader(this );
139: }
140:
141: private int checkDataType(char[] chars) {
142: if (chars.length == 0) {
143: // non-character data from keyboard interface (i.e. FN keys, enter, esc, etc)
144: return KEYBOARD_DATA;
145: } else if (((int) chars[0]) == 2
146: && ((int) chars[chars.length - 1]) == 10) {
147: // test for scanner data
148: return SCANNER_DATA;
149: } else if (((int) chars[0]) == 37
150: && ((int) chars[chars.length - 1]) == 10) {
151: // test for MSR data
152: return MSR_DATA;
153: } else {
154: // otherwise it's keyboard data
155: return KEYBOARD_DATA;
156: }
157: }
158:
159: protected synchronized void receiveCode(int keycode) {
160: keyCodeData.add(new Integer(keycode));
161: }
162:
163: protected synchronized void receiveChar(char keychar) {
164: keyCharData.add(new Character(keychar));
165: if (keychar == '\2') {
166: MAX_WAIT = MAX_WAIT_SCANNER;
167: }
168: }
169:
170: protected synchronized void sendData() {
171: if (KeyboardAdaptor.receivers.size() > 0) {
172: if (keyCharData.size() > 0 || keyCodeData.size() > 0) {
173: char[] chars = new char[keyCharData.size()];
174: int[] codes = new int[keyCodeData.size()];
175:
176: for (int i = 0; i < codes.length; i++) {
177: Integer itg = (Integer) keyCodeData.get(i);
178: codes[i] = itg.intValue();
179: }
180:
181: for (int i = 0; i < chars.length; i++) {
182: Character ch = (Character) keyCharData.get(i);
183: chars[i] = ch.charValue();
184: }
185:
186: Iterator ri = KeyboardAdaptor.receivers.keySet()
187: .iterator();
188: while (ri.hasNext()) {
189: KeyboardReceiver receiver = (KeyboardReceiver) ri
190: .next();
191: int receiverType = ((Integer) receivers
192: .get(receiver)).intValue();
193: int this DataType = this .checkDataType(chars);
194: if (receiverType == ALL_DATA
195: || receiverType == this DataType) {
196: receiver.receiveData(codes, chars);
197: }
198: }
199:
200: keyCharData = new LinkedList();
201: keyCodeData = new LinkedList();
202: lastKey = -1;
203: MAX_WAIT = MAX_WAIT_KEYBOARD;
204: }
205: } else {
206: Debug
207: .logWarning(
208: "No receivers configured for key input",
209: module);
210: }
211: }
212:
213: protected synchronized void sendEvent(int eventType,
214: KeyEvent event) {
215: lastKey = System.currentTimeMillis();
216: if (KeyboardAdaptor.receivers.size() > 0) {
217: Iterator ri = KeyboardAdaptor.receivers.keySet()
218: .iterator();
219: while (ri.hasNext()) {
220: KeyboardReceiver receiver = (KeyboardReceiver) ri
221: .next();
222: if (receiver instanceof KeyListener) {
223: switch (eventType) {
224: case 1:
225: ((KeyListener) receiver).keyPressed(event);
226: break;
227: case 2:
228: ((KeyListener) receiver).keyTyped(event);
229: break;
230: case 3:
231: ((KeyListener) receiver).keyReleased(event);
232: break;
233: default:
234: break;
235: }
236: }
237: }
238: }
239: }
240:
241: public void run() {
242: while (running) {
243: long now = System.currentTimeMillis();
244: if ((lastKey > -1)
245: && (now - lastKey) >= MAX_WAIT.intValue()) {
246: this .sendData();
247: }
248:
249: if (!running) {
250: break;
251: } else {
252: try {
253: Thread.sleep(MAX_WAIT.intValue());
254: } catch (InterruptedException e) {
255: }
256: }
257: }
258: }
259: }
260:
261: class KeyReader implements KeyListener {
262:
263: private KeyboardListener k;
264:
265: public KeyReader(KeyboardListener k) {
266: this .k = k;
267: }
268:
269: private void configureComponents(Component[] coms,
270: boolean recurse) {
271: for (int i = 0; i < coms.length; i++) {
272: if (!loadedComponents.contains(coms[i])) {
273: coms[i].addKeyListener(this );
274: Debug.logInfo("Added [" + coms[i].getName()
275: + "] to KeyboardAdaptor", module);
276: }
277: if (recurse && coms[i] instanceof Container) {
278: Component[] nextComs = ((Container) coms[i])
279: .getComponents();
280: configureComponents(nextComs, true);
281: }
282: }
283: }
284:
285: public void keyTyped(KeyEvent e) {
286: k.receiveChar(e.getKeyChar());
287: k.sendEvent(EVENT_TYPED, e);
288: }
289:
290: public void keyPressed(KeyEvent e) {
291: k.receiveCode(e.getKeyCode());
292: k.sendEvent(EVENT_PRESSED, e);
293: }
294:
295: public void keyReleased(KeyEvent e) {
296: k.sendEvent(EVENT_RELEASED, e);
297: }
298: }
299: }
|