1 38 package com.gargoylesoftware.htmlunit.javascript.configuration; 39 40 import java.lang.reflect.Method ; 41 import java.util.HashMap ; 42 import java.util.Iterator ; 43 import java.util.Map ; 44 import java.util.Set ; 45 46 53 public final class ClassConfiguration { 54 private static final String GETTER_PREFIX = "jsxGet_"; 55 private static final String SETTER_PREFIX = "jsxSet_"; 56 private static final String FUNCTION_PREFIX = "jsxFunction_"; 57 58 private HashMap propertyMap_ = new HashMap (); 59 private HashMap functionMap_ = new HashMap (); 60 private String extendedClass_; 61 64 private final String className_; 65 private final Class linkedClass_; 66 private final String htmlClassname_; 67 private final boolean jsObject_; 68 69 79 public ClassConfiguration(final String classname, final String implementingClass, 80 final String extendedClass, final String htmlClass, final boolean jsObject) 81 throws ClassNotFoundException { 82 className_ = classname; 83 extendedClass_ = extendedClass; 84 linkedClass_ = Class.forName(implementingClass); 85 jsObject_ = jsObject; 86 if (htmlClass != null && htmlClass.length() != 0) { 87 htmlClassname_ = htmlClass; 88 } 89 else { 90 htmlClassname_ = null; 91 } 92 } 93 94 95 98 public String getClassName() { 99 return className_; 100 } 101 102 103 109 public void addProperty(final String name, final boolean readable, final boolean writeable) { 110 final PropertyInfo info = new PropertyInfo(); 111 info.setReadable(readable); 112 info.setWriteable(writeable); 113 try { 114 if (readable) { 115 info.setReadMethod(linkedClass_.getMethod(GETTER_PREFIX + name, null)); 116 } 117 } 118 catch (final NoSuchMethodException e) { 119 throw new IllegalStateException ("Method '" + GETTER_PREFIX + name + "' was not found for " 120 + name + " property in " + linkedClass_.getName()); 121 } 122 if (writeable) { 125 final Method [] methods = linkedClass_.getMethods(); 126 final String setMethodName = SETTER_PREFIX + name; 127 for( int i=0; i<methods.length; i++ ) { 128 if( methods[i].getName().equals(setMethodName) && methods[i].getParameterTypes().length == 1 ) { 129 info.setWriteMethod(methods[i]); 130 break; 131 } 132 } 133 if(info.getWriteMethod() == null) { 134 throw new IllegalStateException ("Method '" + SETTER_PREFIX + name + "' was not found for " + name 135 + " property in " + linkedClass_.getName()); 136 } 137 } 138 propertyMap_.put(name, info); 139 } 140 141 145 public Set propertyKeys() { 146 return propertyMap_.keySet(); 147 } 148 149 153 public Set functionKeys() { 154 return functionMap_.keySet(); 155 } 156 160 public void addFunction(final String name) { 161 final FunctionInfo info = new FunctionInfo(); 162 final Method [] methods = linkedClass_.getMethods(); 163 final String setMethodName = FUNCTION_PREFIX + name; 164 for( int i=0; i<methods.length; i++ ) { 165 if( methods[i].getName().equals(setMethodName)) { 166 info.setFunctionMethod(methods[i]); 167 break; 168 } 169 } 170 if(info.getFunctionMethod() == null) { 171 throw new IllegalStateException ("Method '" + FUNCTION_PREFIX + name + "' was not found for " + name 172 + " function in " + linkedClass_.getName()); 173 } 174 functionMap_.put(name, info); 175 } 176 177 178 184 public void setBrowser(final String propertyName, final String browserName) 185 throws IllegalStateException { 186 final PropertyInfo property = getPropertyInfo(propertyName); 187 if (property == null) { 188 throw new IllegalStateException ("Property does not exist to set browser"); 189 } 190 property.setBrowser(new BrowserInfo(browserName)); 191 } 192 193 196 public String getExtendedClass() { 197 return extendedClass_; 198 } 199 200 203 public void setExtendedClass(final String extendedClass) { 204 extendedClass_ = extendedClass; 205 } 206 207 212 protected PropertyInfo getPropertyInfo(final String propertyName) { 213 return (PropertyInfo) propertyMap_.get(propertyName); 214 } 215 216 217 private FunctionInfo getFunctionInfo(final String functionName) { 218 return (FunctionInfo) functionMap_.get(functionName); 219 } 220 221 228 public boolean equals(final Object obj) { 229 if (! (obj instanceof ClassConfiguration)) { 230 return false; 231 } 232 final ClassConfiguration config = (ClassConfiguration) obj; 233 if (propertyMap_.size() != config.propertyMap_.size()) { 234 return false; 235 } 236 if (functionMap_.size() != config.functionMap_.size()) { 237 return false; 238 } 239 final Set keys = config.propertyMap_.keySet(); 240 final Iterator it = keys.iterator(); 241 while (it.hasNext()) { 242 final String key = (String ) it.next(); 243 if (!(((PropertyInfo)config.propertyMap_.get(key)).valueEquals(propertyMap_.get(key)))) { 244 return false; 245 } 246 } 247 248 final Set fkeys = config.functionMap_.keySet(); 249 final Iterator fit = fkeys.iterator(); 250 while (fit.hasNext()) { 251 final String fkey = (String ) fit.next(); 252 if (!(((FunctionInfo)config.functionMap_.get(fkey)).valueEquals(functionMap_.get(fkey)))) { 253 return false; 254 } 255 } 256 return true; 257 } 258 259 263 public int hashCode() { 264 return className_.hashCode(); 265 } 266 267 273 public Method getPropertyReadMethod(final String propertyName) { 274 final PropertyInfo info = getPropertyInfo(propertyName); 275 if (info == null) { 276 return null; 277 } 278 return info.getReadMethod(); 279 } 280 281 287 public Method getPropertyWriteMethod(final String propertyName) { 288 final PropertyInfo info = getPropertyInfo(propertyName); 289 if (info == null) { 290 return null; 291 } 292 return info.getWriteMethod(); 293 } 294 295 301 public Method getFunctionMethod(final String functionName) { 302 final FunctionInfo info = getFunctionInfo(functionName); 303 if (info == null) { 304 return null; 305 } 306 return info.getFunctionMethod(); 307 } 308 309 313 public Class getLinkedClass() { 314 return linkedClass_; 315 } 316 317 320 public String getHtmlClassname() { 321 return htmlClassname_; 322 } 323 324 327 public boolean isJsObject() { 328 return jsObject_; 329 } 330 334 protected class PropertyInfo { 335 private boolean readable_ = false; 336 private boolean writeable_ = false; 337 private boolean hasBrowsers_ = false; 338 private Map browserMap_; 339 private Method readMethod_; 340 private Method writeMethod_; 341 342 345 public Method getReadMethod() { 346 return readMethod_; 347 } 348 349 352 public void setReadMethod(final Method readMethod) { 353 readMethod_ = readMethod; 354 } 355 356 359 public Method getWriteMethod() { 360 return writeMethod_; 361 } 362 363 366 public void setWriteMethod(final Method writeMethod) { 367 writeMethod_ = writeMethod; 368 } 369 370 private void setBrowser(final BrowserInfo browserInfo) { 371 if (browserMap_ == null) { 372 hasBrowsers_ = true; 373 browserMap_ = new HashMap (); 374 } 375 376 browserMap_.put(browserInfo.getBrowserName(), browserInfo); 377 } 378 379 386 private boolean valueEquals(final Object obj) { 387 if (!(obj instanceof PropertyInfo)) { 388 return false; 389 } 390 final PropertyInfo info = (PropertyInfo) obj; 391 if (hasBrowsers_ != info.hasBrowsers_) { 392 return false; 393 } 394 if (hasBrowsers_) { 395 if (browserMap_.size() != info.browserMap_.size()) { 396 return false; 397 } 398 final Set keys = browserMap_.keySet(); 399 final Iterator it = keys.iterator(); 400 while (it.hasNext()) { 401 final String key = (String ) it.next(); 402 if (!(((BrowserInfo)browserMap_.get(key)).valueEquals(info.browserMap_.get(key)))) { 403 return false; 404 } 405 } 406 407 } 408 return (readable_ == info.readable_) && 409 (writeable_ == info.writeable_); 410 } 411 412 415 private void setReadable(final boolean readable) { 416 readable_ = readable; 417 } 418 419 422 private void setWriteable(final boolean writeable) { 423 writeable_ = writeable; 424 } 425 } 426 427 private class FunctionInfo { 428 private boolean hasBrowsers_ = false; 429 private Map browserMap_; 430 private Method functionMethod_; 431 432 439 private boolean valueEquals(final Object obj) { 440 if (!(obj instanceof FunctionInfo)) { 441 return false; 442 } 443 final FunctionInfo info = (FunctionInfo) obj; 444 if (hasBrowsers_ != info.hasBrowsers_) { 445 return false; 446 } 447 if (hasBrowsers_) { 448 if (browserMap_.size() != info.browserMap_.size()) { 449 return false; 450 } 451 final Set keys = browserMap_.keySet(); 452 final Iterator it = keys.iterator(); 453 while (it.hasNext()) { 454 final String key = (String ) it.next(); 455 if (!(((BrowserInfo)browserMap_.get(key)).valueEquals(info.browserMap_.get(key)))) { 456 return false; 457 } 458 } 459 460 } 461 return true; 462 } 463 464 467 public Method getFunctionMethod() { 468 return functionMethod_; 469 } 470 471 474 public void setFunctionMethod(final Method functionMethod) { 475 functionMethod_ = functionMethod; 476 } 477 } 478 479 private class BrowserInfo { 480 private String browserName_; 481 private String minVersion_; 482 private String maxVersion_; 483 private String lessThanVersion_; 484 485 492 private boolean valueEquals(final Object obj) { 493 if (!(obj instanceof BrowserInfo)) { 494 return false; 495 } 496 final BrowserInfo info = (BrowserInfo) obj; 497 if (minVersion_ != null) { 498 if (! minVersion_.equals(info.minVersion_)) { 499 return false; 500 } 501 } 502 if (maxVersion_ != null) { 503 if (! maxVersion_.equals(info.maxVersion_)) { 504 return false; 505 } 506 } 507 if (lessThanVersion_ != null) { 508 if (! lessThanVersion_.equals(info.lessThanVersion_)) { 509 return false; 510 } 511 } 512 return (browserName_ == info.browserName_); 513 } 514 515 518 public BrowserInfo(final String browserName) { 519 browserName_ = browserName; 520 } 521 522 525 private String getBrowserName() { 526 return browserName_; 527 } 528 } 529 530 } 531 | Popular Tags |