1 14 package org.wings.session; 15 16 import org.apache.commons.logging.Log; 17 import org.apache.commons.logging.LogFactory; 18 import org.wings.LowLevelEventListener; 19 import org.wings.SButton; 20 import org.wings.SCheckBox; 21 import org.wings.SClickable; 22 import org.wings.SComponent; 23 import org.wings.SConstants; 24 import org.wings.SFrame; 25 import org.wings.SPageScroller; 26 import org.wings.SRadioButton; 27 import org.wings.SScrollBar; 28 import org.wings.STabbedPane; 29 import org.wings.STable; 30 import org.wings.SToggleButton; 31 import org.wings.STree; 32 33 import java.util.ArrayList ; 34 import java.util.Arrays ; 35 import java.util.HashMap ; 36 import java.util.LinkedList ; 37 import java.util.List ; 38 39 43 public final class LowLevelEventDispatcher 44 implements java.io.Serializable { 45 private final transient static Log log = LogFactory.getLog(LowLevelEventDispatcher.class); 46 47 private final HashMap listeners = new HashMap (); 48 49 protected boolean namedEvents = true; 50 51 56 private static final List ieButtonFixClasses = Arrays.asList(new Class [] { 57 SButton.class, SToggleButton.class, SClickable.class, 58 SPageScroller.class, SRadioButton.class, SScrollBar.class, 59 STabbedPane.class, STable.class, STree.class}); 60 61 public LowLevelEventDispatcher() {} 62 63 public final void addLowLevelEventListener(LowLevelEventListener gl, 64 String eventId) { 65 List l = (List ) listeners.get(eventId); 66 if (l == null) { 67 l = new ArrayList (2); 68 l.add(gl); 69 listeners.put(eventId, l); 70 } else if (!l.contains(gl)) 71 l.add(gl); 72 } 73 74 public final void removeLowLevelEventListener(LowLevelEventListener gl, 75 String eventId) { 76 List l = (List ) listeners.get(eventId); 77 if (l != null) { 78 l.remove(gl); 79 if (l.size() == 0) 80 listeners.remove(eventId); 81 } 82 } 83 84 public final LowLevelEventListener getLowLevelEventListener(String eventId) { 85 return (LowLevelEventListener) listeners.get(eventId); 86 } 87 88 public final void setNamedEvents(boolean b) { 89 namedEvents = b; 90 } 91 92 98 public void register(LowLevelEventListener gl) { 99 if (gl == null) 100 return; 101 102 String key = gl.getLowLevelEventId(); 103 104 log.debug("dispatcher: register '" + key + "' type: " + gl.getClass()); 105 addLowLevelEventListener(gl, key); 106 107 if (namedEvents) { 108 key = gl.getName(); 109 if (key != null && key.trim().length() > 0) { 110 log.debug("dispatcher: register named '" + key + "'"); 111 addLowLevelEventListener(gl, key); 112 } 113 } 114 } 115 116 120 public void unregister(LowLevelEventListener gl) { 121 if (gl == null) 122 return; 123 124 String key = gl.getLowLevelEventId(); 125 126 log.debug("unregister '" + key + "'"); 127 removeLowLevelEventListener(gl, key); 128 129 key = gl.getName(); 130 if (key != null && key.trim().length() > 0) { 131 log.debug("unregister named '" + key + "'"); 132 removeLowLevelEventListener(gl, key); 133 } 134 135 } 136 137 144 public boolean dispatch(String name, String [] values) { 145 if (log.isDebugEnabled()) 146 log.debug("dispatch " + name + " = " + Arrays.asList(values)); 147 148 boolean result = false; 149 int dividerIndex = name.indexOf(SConstants.UID_DIVIDER); 150 String epoch = null; 151 boolean isIE = SessionManager.getSession().getUserAgent().getBrowserType() == BrowserType.IE; 152 153 if (dividerIndex > 0) { 155 epoch = name.substring(0, dividerIndex); 156 name = name.substring(dividerIndex + 1); 157 } 158 159 if (name.endsWith(".x") || name.endsWith(".X")) { 162 name = name.substring(0, name.length() - 2); 163 } else if (name.endsWith(".y") || name.endsWith(".Y")) { 164 log.debug("discard '.y' part of image event"); 166 return false; 167 } 168 169 int p = name.indexOf(SConstants.UID_DIVIDER); 171 if (p > -1) { 172 String v = name.substring(p + 1); 173 name = name.substring(0, p); 174 String [] va = new String [values.length + 1]; 175 System.arraycopy(values, 0, va, 0, values.length); 176 va[values.length] = v; 177 values = va; 178 } 179 180 200 if (isIE && name.equals(SConstants.IEFIX_BUTTONACTION)) { 201 String buttonId = values[0]; 202 String [] vals = new String [] {""}; 203 int pos = buttonId.indexOf(SConstants.UID_DIVIDER); 204 if (pos > -1) { 205 String val = buttonId.substring(pos + 1); 206 buttonId = buttonId.substring(0, pos); 207 vals[0] = val; 208 } 209 List l = (List ) listeners.get(buttonId); 210 if (l != null && l.size() > 0) { 211 if (log.isDebugEnabled()) { 212 log.debug("process special IE workaround event '" + epoch + SConstants.UID_DIVIDER + name + "'"); 213 } 214 for (int i = 0; i < l.size(); ++i) { 215 LowLevelEventListener gl = (LowLevelEventListener) l.get(i); 216 if (gl.isEnabled()) { 217 if (checkEpoch(epoch, buttonId, gl)) { 218 if (log.isDebugEnabled()) { 219 log.debug("process event '" + buttonId + "' by " + 220 gl.getClass() + "(" + gl.getLowLevelEventId() + 221 ")"); 222 } 223 gl.processLowLevelEvent(buttonId,vals); 224 result = true; 225 } 226 } 227 } 228 } 229 } 230 List l = (List ) listeners.get(name); 231 if (l != null && l.size() > 0) { 232 log.debug("process event '" + epoch + SConstants.UID_DIVIDER + name + "'"); 233 for (int i = 0; i < l.size(); ++i) { 234 LowLevelEventListener gl = (LowLevelEventListener) l.get(i); 235 if (gl.isEnabled()) { 236 if (checkEpoch(epoch, name, gl)) { 237 if (isIE) { 238 boolean isFormEvent = ((SComponent)gl).getResidesInForm() && ((SComponent)gl).getShowAsFormComponent(); 240 if (isFormEvent) { 241 boolean isButton = ieButtonFixClasses.contains(gl.getClass()); 243 if (isButton) { 244 log.debug("circumventing IE bug, not processing event '" + name + "' by " + 245 gl.getClass() + "(" + gl.getLowLevelEventId() + 246 ")"); 247 } else { 248 log.debug("process form event not caused by a button tag'" + name + "' by " + 249 gl.getClass() + "(" + gl.getLowLevelEventId() + 250 ")"); 251 gl.processLowLevelEvent(name, values); 252 result = true; 253 } 254 } else { 255 log.debug("process event '" + name + "' by " + 256 gl.getClass() + "(" + gl.getLowLevelEventId() + 257 ")"); 258 gl.processLowLevelEvent(name, values); 259 result = true; 260 } 261 } else { 262 log.debug("process event '" + name + "' by " + 263 gl.getClass() + "(" + gl.getLowLevelEventId() + 264 ")"); 265 gl.processLowLevelEvent(name, values); 266 result = true; 267 } 268 } 269 } 270 } 271 } 272 return result; 273 } 274 275 protected boolean checkEpoch(String epoch, String name, 276 LowLevelEventListener gl) { 277 if (epoch != null) { 278 SFrame frame = ((SComponent) gl).getParentFrame(); 279 if (frame == null) { 280 if (log.isDebugEnabled()) 281 log.debug("request for dangling component '" + epoch + SConstants.UID_DIVIDER + name); 282 unregister(gl); 283 return false; 284 } 285 if (!epoch.equals(frame.getEventEpoch())) { 286 if (log.isDebugEnabled()) { 287 log.debug("### got outdated event '" + epoch + SConstants.UID_DIVIDER + name 288 + "' from frame '" + frame.getName() + "'; expected epoch: " + frame.getEventEpoch()); 289 } 290 frame.fireInvalidLowLevelEventListener(gl); 291 return false; 292 } 293 } 294 return true; 295 } 296 297 void clear() { 298 listeners.clear(); 299 } 300 } 301 302 303 | Popular Tags |