001 // Copyright May 20, 2006 The Apache Software Foundation 002 // 003 // Licensed under the Apache License, Version 2.0 (the "License"); 004 // you may not use this file except in compliance with the License. 005 // You may obtain a copy of the License at 006 // 007 // http://www.apache.org/licenses/LICENSE-2.0 008 // 009 // Unless required by applicable law or agreed to in writing, software 010 // distributed under the License is distributed on an "AS IS" BASIS, 011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 012 // See the License for the specific language governing permissions and 013 // limitations under the License. 014 package org.apache.tapestry.event; 015 016 import org.apache.hivemind.ApplicationRuntimeException; 017 import org.apache.hivemind.util.Defense; 018 import org.apache.tapestry.IRequestCycle; 019 import org.apache.tapestry.json.JSONArray; 020 021 import java.text.ParseException; 022 import java.util.Arrays; 023 import java.util.HashMap; 024 import java.util.Map; 025 026 027 /** 028 * Represents a client side generated browser event. 029 */ 030 public class BrowserEvent 031 { 032 public static final String NAME="beventname"; 033 public static final String TYPE="beventtype"; 034 public static final String KEYS="beventkeys"; 035 public static final String CHAR_CODE="beventcharCode"; 036 public static final String PAGE_X="beventpageX"; 037 public static final String PAGE_Y="beventpageY"; 038 public static final String LAYER_X="beventlayerX"; 039 public static final String LAYER_Y="beventlayerY"; 040 041 public static final String TARGET="beventtarget"; 042 public static final String TARGET_ATTR_ID="id"; 043 public static final String COMPONENT_ID = "bcomponentid"; 044 045 public static final String METHOD_ARGUMENTS="methodArguments"; 046 047 private String _name; 048 private String _type; 049 private String[] _keys; 050 private String _charCode; 051 private String _pageX; 052 private String _pageY; 053 private String _layerX; 054 private String _layerY; 055 private EventTarget _target; 056 private String _componentId; 057 058 private String _methodArguments; 059 private JSONArray _methodArgumentsArray; 060 061 /** 062 * Creates a new browser event that will extract its own 063 * parameters. 064 * 065 * @param cycle 066 * The request cycle to extract parameters from. 067 */ 068 public BrowserEvent(IRequestCycle cycle) 069 { 070 Defense.notNull(cycle, "cycle"); 071 072 _name = cycle.getParameter(NAME); 073 _type = cycle.getParameter(TYPE); 074 _keys = cycle.getParameters(KEYS); 075 _charCode = cycle.getParameter(CHAR_CODE); 076 _pageX = cycle.getParameter(PAGE_X); 077 _pageY = cycle.getParameter(PAGE_Y); 078 _layerX = cycle.getParameter(LAYER_X); 079 _layerY = cycle.getParameter(LAYER_Y); 080 _componentId = cycle.getParameter(COMPONENT_ID); 081 082 Map props = new HashMap(); 083 _target = new EventTarget(props); 084 085 String targetId = cycle.getParameter(TARGET + "." + TARGET_ATTR_ID); 086 if (targetId != null) 087 { 088 props.put(TARGET_ATTR_ID, targetId); 089 } 090 091 _methodArguments = cycle.getParameter(METHOD_ARGUMENTS); 092 } 093 094 /** 095 * Creates a new browser event with the specified 096 * name/target properties. 097 * 098 * @param name The name of the event, ie "onClick", "onBlur", etc.. 099 * @param target The target of the client side event. 100 */ 101 public BrowserEvent(String name, EventTarget target) 102 { 103 this(name, null, target); 104 } 105 106 /** 107 * Creates a new browser event with the specified 108 * name/target properties. 109 * 110 * @param name The name of the event, ie "onClick", "onBlur", etc.. 111 * @param componentId Component targeted. 112 * @param target The target of the client side event. 113 */ 114 public BrowserEvent(String name, String componentId, EventTarget target) 115 { 116 _name = name; 117 _target = target; 118 _componentId = componentId; 119 } 120 121 /** 122 * The name of the event that was generated. 123 * 124 * <p> 125 * Examples would be <code>onClick,onSelect,onLoad,etc...</code>. 126 * </p> 127 * @return The event name. 128 */ 129 public String getName() 130 { 131 return _name; 132 } 133 134 /** 135 * Returns the target of the client side event. 136 * 137 * @return The target representation of the client side object event originally bound for. 138 */ 139 public EventTarget getTarget() 140 { 141 return _target; 142 } 143 144 /** 145 * Only when the event targeted a {@link org.apache.tapestry.IComponent} - will return the originating 146 * components id as returned from {@link org.apache.tapestry.IComponent#getId()}. <em>Not</em> present 147 * on element events. 148 * 149 * @return The originating component id that generated the event. 150 */ 151 public String getComponentId() 152 { 153 return _componentId; 154 } 155 156 /** 157 * @return the charCode 158 */ 159 public String getCharCode() 160 { 161 return _charCode; 162 } 163 164 /** 165 * @return the keys 166 */ 167 public String[] getKeys() 168 { 169 return _keys; 170 } 171 172 /** 173 * @return the layerX 174 */ 175 public String getLayerX() 176 { 177 return _layerX; 178 } 179 180 /** 181 * @return the layerY 182 */ 183 public String getLayerY() 184 { 185 return _layerY; 186 } 187 188 /** 189 * @return the pageX 190 */ 191 public String getPageX() 192 { 193 return _pageX; 194 } 195 196 /** 197 * @return the pageY 198 */ 199 public String getPageY() 200 { 201 return _pageY; 202 } 203 204 /** 205 * @return the type 206 */ 207 public String getType() 208 { 209 return _type; 210 } 211 212 213 /** 214 * @return the method arguments of an intercepted method-call, if any. If none 215 * are available, return an empty JSONArray, never null. 216 * 217 * @throws ApplicationRuntimeException when the JSON-String could not be 218 * parsed. 219 */ 220 public JSONArray getMethodArguments() 221 { 222 if ( _methodArgumentsArray == null) 223 { 224 try 225 { 226 _methodArgumentsArray = _methodArguments != null 227 ? new JSONArray( _methodArguments ) 228 : new JSONArray(); 229 } 230 catch (ParseException ex) 231 { 232 throw new ApplicationRuntimeException(ex); 233 } 234 } 235 236 return _methodArgumentsArray; 237 } 238 239 /** 240 * Utility method to check if the current request contains 241 * a browser event. 242 * 243 * @param cycle 244 * The associated request. 245 * @return True if the request contains browser event data. 246 */ 247 public static boolean hasBrowserEvent(IRequestCycle cycle) 248 { 249 Defense.notNull(cycle, "cycle"); 250 251 return cycle.getParameter(NAME) != null; 252 } 253 254 public String toString() 255 { 256 return "BrowserEvent[" + 257 "_name='" + _name + '\'' + 258 '\n' + 259 ", _type='" + _type + '\'' + 260 '\n' + 261 ", _keys=" + (_keys == null ? null : Arrays.asList(_keys)) + 262 '\n' + 263 ", _charCode='" + _charCode + '\'' + 264 '\n' + 265 ", _pageX='" + _pageX + '\'' + 266 '\n' + 267 ", _pageY='" + _pageY + '\'' + 268 '\n' + 269 ", _layerX='" + _layerX + '\'' + 270 '\n' + 271 ", _layerY='" + _layerY + '\'' + 272 '\n' + 273 ", _target=" + _target + 274 '\n' + 275 ", _methodArguments='" + _methodArguments + '\'' + 276 '\n' + 277 ", _methodArgumentsArray=" + _methodArgumentsArray + 278 '\n' + 279 ']'; 280 } 281 282 public boolean equals(Object o) 283 { 284 if (this == o) return true; 285 if (o == null || getClass() != o.getClass()) return false; 286 287 BrowserEvent event = (BrowserEvent) o; 288 289 if (_charCode != null ? !_charCode.equals(event._charCode) : event._charCode != null) return false; 290 if (!Arrays.equals(_keys, event._keys)) return false; 291 if (_layerX != null ? !_layerX.equals(event._layerX) : event._layerX != null) return false; 292 if (_layerY != null ? !_layerY.equals(event._layerY) : event._layerY != null) return false; 293 if (_methodArguments != null ? !_methodArguments.equals(event._methodArguments) : event._methodArguments != null) return false; 294 if (_methodArgumentsArray != null ? !_methodArgumentsArray.equals(event._methodArgumentsArray) : event._methodArgumentsArray != null) return false; 295 if (_name != null ? !_name.equals(event._name) : event._name != null) return false; 296 if (_pageX != null ? !_pageX.equals(event._pageX) : event._pageX != null) return false; 297 if (_pageY != null ? !_pageY.equals(event._pageY) : event._pageY != null) return false; 298 if (_target != null ? !_target.equals(event._target) : event._target != null) return false; 299 if (_type != null ? !_type.equals(event._type) : event._type != null) return false; 300 301 return true; 302 } 303 304 public int hashCode() 305 { 306 int result; 307 result = (_name != null ? _name.hashCode() : 0); 308 result = 31 * result + (_type != null ? _type.hashCode() : 0); 309 result = 31 * result + (_keys != null ? Arrays.hashCode(_keys) : 0); 310 result = 31 * result + (_charCode != null ? _charCode.hashCode() : 0); 311 result = 31 * result + (_pageX != null ? _pageX.hashCode() : 0); 312 result = 31 * result + (_pageY != null ? _pageY.hashCode() : 0); 313 result = 31 * result + (_layerX != null ? _layerX.hashCode() : 0); 314 result = 31 * result + (_layerY != null ? _layerY.hashCode() : 0); 315 result = 31 * result + (_target != null ? _target.hashCode() : 0); 316 result = 31 * result + (_methodArguments != null ? _methodArguments.hashCode() : 0); 317 result = 31 * result + (_methodArgumentsArray != null ? _methodArgumentsArray.hashCode() : 0); 318 return result; 319 } 320 }