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.config;
019:
020: import java.lang.reflect.Method;
021: import java.lang.reflect.InvocationTargetException;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.ArrayList;
025: import java.awt.AWTEvent;
026:
027: import net.xoetrope.swing.XButton;
028:
029: import org.ofbiz.base.config.GenericConfigException;
030: import org.ofbiz.base.config.ResourceLoader;
031: import org.ofbiz.base.util.GeneralException;
032: import org.ofbiz.base.util.UtilValidate;
033: import org.ofbiz.base.util.UtilXml;
034: import org.ofbiz.base.util.Debug;
035: import org.ofbiz.base.util.cache.UtilCache;
036: import org.ofbiz.pos.screen.PosScreen;
037:
038: import org.w3c.dom.Element;
039:
040: public class ButtonEventConfig implements java.io.Serializable {
041:
042: public static final String module = ButtonEventConfig.class
043: .getName();
044: public static final String BUTTON_EVENT_CONFIG = "buttonevents.xml";
045: private static transient UtilCache buttonConfig = new UtilCache(
046: "pos.ButtonEvent", 0, 0, 0, false, true);
047:
048: protected String buttonName = null;
049: protected String className = null;
050: protected String method = null;
051: protected int keyCode = -1;
052: protected boolean disableLock = false;
053:
054: public static void loadButtonConfig() throws GenericConfigException {
055: Element root = ResourceLoader
056: .getXmlRootElement(ButtonEventConfig.BUTTON_EVENT_CONFIG);
057: List buttonEvents = UtilXml.childElementList(root, "event");
058: if (!UtilValidate.isEmpty(buttonEvents)) {
059: Iterator i = buttonEvents.iterator();
060: while (i.hasNext()) {
061: Element e = (Element) i.next();
062: ButtonEventConfig bef = new ButtonEventConfig(e);
063: buttonConfig.put(bef.getName(), bef);
064: }
065: }
066: }
067:
068: public static boolean isLockable(String buttonName) {
069: ButtonEventConfig bef = (ButtonEventConfig) buttonConfig
070: .get(buttonName);
071: if (bef == null) {
072: return true;
073: }
074: return bef.isLockable();
075: }
076:
077: public static void invokeButtonEvents(List buttonNames,
078: PosScreen pos) throws ButtonEventNotFound,
079: ButtonEventException {
080: if (buttonNames != null) {
081: Iterator i = buttonNames.iterator();
082: while (i.hasNext()) {
083: invokeButtonEvent(((String) i.next()), pos, null);
084: }
085: }
086: }
087:
088: public static void invokeButtonEvent(String buttonName,
089: PosScreen pos, AWTEvent event) throws ButtonEventNotFound,
090: ButtonEventException {
091: // load / re-load the button configs
092: if (buttonConfig.size() == 0) {
093: synchronized (ButtonEventConfig.class) {
094: try {
095: loadButtonConfig();
096: } catch (GenericConfigException e) {
097: Debug.logError(e, module);
098: }
099: }
100: }
101:
102: // check for sku mapping buttons
103: if (buttonName.startsWith("SKU.")) {
104: buttonName = "menuSku";
105: }
106:
107: // invoke the button event
108: ButtonEventConfig bef = (ButtonEventConfig) buttonConfig
109: .get(buttonName);
110: if (bef == null) {
111: throw new ButtonEventNotFound(
112: "No button definition found for button - "
113: + buttonName);
114: }
115: bef.invoke(pos, event);
116: }
117:
118: public static List findButtonKeyAssign(int keyCode) {
119: List buttonAssignments = new ArrayList();
120: Iterator i = buttonConfig.values().iterator();
121: while (i.hasNext()) {
122: ButtonEventConfig bef = (ButtonEventConfig) i.next();
123: if (bef.getKeyCode() == keyCode) {
124: buttonAssignments.add(bef.getName());
125: }
126: }
127:
128: return buttonAssignments;
129: }
130:
131: public static String getButtonName(AWTEvent event) {
132: if (event == null) {
133: throw new IllegalArgumentException(
134: "AWTEvent parameter cannot be null");
135: }
136: Object source = event.getSource();
137: if (source instanceof XButton) {
138: XButton button = (XButton) source;
139: return button.getName();
140: } else {
141: return null;
142: }
143: }
144:
145: protected ButtonEventConfig() {
146: }
147:
148: protected ButtonEventConfig(Element element) {
149: this .buttonName = element.getAttribute("button-name");
150: this .className = element.getAttribute("class-name");
151: this .method = element.getAttribute("method-name");
152: String keyCodeStr = element.getAttribute("key-code");
153: if (UtilValidate.isNotEmpty(keyCodeStr)) {
154: try {
155: this .keyCode = Integer.parseInt(keyCodeStr);
156: } catch (Throwable t) {
157: Debug.logWarning("Key code definition for button ["
158: + buttonName + "] is not a valid Integer",
159: module);
160: }
161: }
162: this .disableLock = "true".equals(element
163: .getAttribute("disable-lock"));
164: }
165:
166: public String getName() {
167: return this .buttonName;
168: }
169:
170: public int getKeyCode() {
171: return this .keyCode;
172: }
173:
174: public boolean isLockable() {
175: return !disableLock;
176: }
177:
178: public void invoke(PosScreen pos, AWTEvent event)
179: throws ButtonEventNotFound, ButtonEventException {
180: ClassLoader cl = Thread.currentThread().getContextClassLoader();
181: if (cl == null) {
182: Debug.log("Unable to obtain the context classloader",
183: module);
184: cl = this .getClass().getClassLoader();
185: }
186:
187: // two variations are available
188: Class[] paramTypes1 = new Class[] { PosScreen.class,
189: AWTEvent.class };
190: Class[] paramTypes2 = new Class[] { PosScreen.class };
191: Object[] params1 = new Object[] { pos, event };
192: Object[] params2 = new Object[] { pos };
193:
194: // load the class
195: Class buttonClass = null;
196: try {
197: buttonClass = cl.loadClass(this .className);
198: } catch (ClassNotFoundException e) {
199: throw new ButtonEventNotFound(e);
200: }
201:
202: // load the method
203: Method buttonMethod = null;
204: int methodType = 0;
205: try {
206: buttonMethod = buttonClass.getMethod(this .method,
207: paramTypes1);
208: methodType = 1;
209: } catch (NoSuchMethodException e) {
210: try {
211: buttonMethod = buttonClass.getMethod(this .method,
212: paramTypes2);
213: methodType = 2;
214: } catch (NoSuchMethodException e2) {
215: Debug.logError(e2,
216: "No method found with matching signatures - "
217: + this .buttonName, module);
218: throw new ButtonEventNotFound(e);
219: }
220: }
221:
222: // invoke the method
223: try {
224: switch (methodType) {
225: case 1:
226: buttonMethod.invoke(null, params1);
227: break;
228: case 2:
229: buttonMethod.invoke(null, params2);
230: break;
231: default:
232: throw new ButtonEventNotFound(
233: "No class method found for button - "
234: + this .buttonName);
235: }
236: } catch (IllegalAccessException e) {
237: throw new ButtonEventException(e);
238: } catch (InvocationTargetException e) {
239: throw new ButtonEventException(e);
240: } catch (Throwable t) {
241: throw new ButtonEventException(t);
242: }
243: }
244:
245: public static class ButtonEventNotFound extends GeneralException {
246: public ButtonEventNotFound() {
247: super ();
248: }
249:
250: public ButtonEventNotFound(String str) {
251: super (str);
252: }
253:
254: public ButtonEventNotFound(String str, Throwable nested) {
255: super (str, nested);
256: }
257:
258: public ButtonEventNotFound(Throwable nested) {
259: super (nested);
260: }
261: }
262:
263: public static class ButtonEventException extends GeneralException {
264: public ButtonEventException() {
265: super ();
266: }
267:
268: public ButtonEventException(String str) {
269: super (str);
270: }
271:
272: public ButtonEventException(String str, Throwable nested) {
273: super (str, nested);
274: }
275:
276: public ButtonEventException(Throwable nested) {
277: super(nested);
278: }
279: }
280: }
|