1 29 30 package com.caucho.config; 31 32 import com.caucho.el.EL; 33 import com.caucho.el.EnvironmentContext; 34 import com.caucho.relaxng.CompactVerifierFactoryImpl; 35 import com.caucho.relaxng.Schema; 36 import com.caucho.relaxng.Verifier; 37 import com.caucho.relaxng.VerifierFilter; 38 import com.caucho.util.L10N; 39 import com.caucho.util.Log; 40 import com.caucho.util.LruCache; 41 import com.caucho.vfs.MergePath; 42 import com.caucho.vfs.Path; 43 import com.caucho.vfs.ReadStream; 44 import com.caucho.xml.DOMBuilder; 45 import com.caucho.xml.QDocument; 46 import com.caucho.xml.QName; 47 import com.caucho.xml.Xml; 48 49 import org.w3c.dom.Node ; 50 import org.xml.sax.InputSource ; 51 52 import javax.el.ELContext; 53 import javax.el.ELException; 54 import javax.el.ELResolver; 55 import java.io.IOException ; 56 import java.io.InputStream ; 57 import java.lang.ref.SoftReference ; 58 import java.lang.reflect.Constructor ; 59 import java.lang.reflect.Method ; 60 import java.lang.reflect.Modifier ; 61 import java.util.HashMap ; 62 import java.util.Map ; 63 import java.util.logging.Logger ; 64 65 68 public class Config { 69 private static final L10N L = new L10N(Config.class); 70 private static final Logger log = Log.open(Config.class); 71 72 private static LruCache<Path,SoftReference <QDocument>> _parseCache = 73 new LruCache<Path,SoftReference <QDocument>>(32); 74 75 private ConfigVariableResolver _varResolver; 77 78 private HashMap <String ,Object > _vars 79 = new HashMap <String ,Object >(); 80 81 private ClassLoader _classLoader; 83 84 private ConfigLibrary _configLibrary; 85 86 private boolean _isEL = true; 87 private boolean _allowResinInclude; 88 89 public Config() 90 { 91 this(Thread.currentThread().getContextClassLoader()); 92 } 93 94 97 public Config(ClassLoader loader) 98 { 99 _classLoader = loader; 100 101 _configLibrary = ConfigLibrary.getLocal(_classLoader); 102 } 103 104 107 public void setResinInclude(boolean useResinInclude) 108 { 109 _allowResinInclude = useResinInclude; 110 } 111 112 115 public boolean isEL() 116 { 117 return _isEL; 118 } 119 120 123 public void setEL(boolean isEL) 124 { 125 _isEL = isEL; 126 } 127 128 131 public void setConfigVariableResolver(ConfigVariableResolver varResolver) 132 { 133 _varResolver = varResolver; 134 } 135 136 139 public ConfigVariableResolver getConfigVariableResolver() 140 { 141 return _varResolver; 142 } 143 144 147 public Object configure(Object obj, Path path) 148 throws Exception 149 { 150 QDocument doc = parseDocument(path, null); 151 152 return configure(obj, doc.getDocumentElement()); 153 } 154 155 158 public Object configure(Object obj, InputStream is) 159 throws Exception 160 { 161 QDocument doc = parseDocument(is, null); 162 163 return configure(obj, doc.getDocumentElement()); 164 } 165 166 169 public Object configure(Object obj, Path path, String schemaLocation) 170 throws Exception 171 { 172 Schema schema = findCompactSchema(schemaLocation); 173 174 QDocument doc = parseDocument(path, schema); 175 176 return configure(obj, doc.getDocumentElement()); 177 } 178 179 182 public Object configure(Object obj, Path path, Schema schema) 183 throws Exception 184 { 185 QDocument doc = parseDocument(path, schema); 186 187 return configure(obj, doc.getDocumentElement()); 188 } 189 190 193 public Object configure(Object obj, 194 InputStream is, 195 String schemaLocation) 196 throws Exception 197 { 198 Schema schema = findCompactSchema(schemaLocation); 199 200 QDocument doc = parseDocument(is, schema); 201 202 return configure(obj, doc.getDocumentElement()); 203 } 204 205 208 public Object configure(Object obj, 209 InputStream is, 210 Schema schema) 211 throws Exception 212 { 213 QDocument doc = parseDocument(is, schema); 214 215 return configure(obj, doc.getDocumentElement()); 216 } 217 218 221 public Object configure(Object obj, Node topNode) 222 throws Exception 223 { 224 Thread thread = Thread.currentThread(); 225 ClassLoader oldLoader = thread.getContextClassLoader(); 226 227 try { 228 thread.setContextClassLoader(_classLoader); 229 230 NodeBuilder builder = createBuilder(); 231 232 return builder.configure(obj, topNode); 233 } finally { 234 thread.setContextClassLoader(oldLoader); 235 } 236 } 237 238 241 public void configureBean(Object obj, 242 Path path, 243 String schemaLocation) 244 throws Exception 245 { 246 Schema schema = findCompactSchema(schemaLocation); 247 248 QDocument doc = parseDocument(path, schema); 249 250 configureBean(obj, doc.getDocumentElement()); 251 } 252 253 256 public void configureBean(Object obj, Path path) 257 throws Exception 258 { 259 QDocument doc = parseDocument(path, null); 260 261 configureBean(obj, doc.getDocumentElement()); 262 } 263 264 268 public void configureBean(Object obj, Node topNode) 269 throws Exception 270 { 271 Thread thread = Thread.currentThread(); 272 ClassLoader oldLoader = thread.getContextClassLoader(); 273 274 try { 275 thread.setContextClassLoader(_classLoader); 276 277 NodeBuilder builder = createBuilder(); 278 279 builder.configureBean(obj, topNode); 280 } finally { 281 thread.setContextClassLoader(oldLoader); 282 } 283 } 284 285 private NodeBuilder createBuilder() 286 { 287 NodeBuilder builder = new NodeBuilder(this); 288 289 for (String var : _vars.keySet()) 290 builder.putVar(var, _vars.get(var)); 291 292 ConfigLibrary lib = ConfigLibrary.getLocal(); 293 294 HashMap <String ,Method > methodMap = lib.getMethodMap(); 295 296 for (Map.Entry <String ,Method > entry : methodMap.entrySet()) { 297 builder.putVar(entry.getKey(), entry.getValue()); 298 } 299 300 return builder; 301 } 302 303 306 public void configureBean(Object obj, 307 Path path, 308 Schema schema) 309 throws Exception 310 { 311 QDocument doc = parseDocument(path, schema); 312 313 configureBean(obj, doc.getDocumentElement()); 314 } 315 316 319 private QDocument parseDocument(Path path, Schema schema) 320 throws LineConfigException, IOException , org.xml.sax.SAXException 321 { 322 SoftReference <QDocument> docRef = null; QDocument doc; 325 326 if (docRef != null) { 327 doc = docRef.get(); 328 329 if (doc != null && ! doc.isModified()) 330 return doc; 331 } 332 333 ReadStream is = path.openRead(); 334 335 try { 336 doc = parseDocument(is, schema); 337 338 340 return doc; 341 } finally { 342 is.close(); 343 } 344 } 345 346 349 private QDocument parseDocument(InputStream is, Schema schema) 350 throws LineConfigException, 351 IOException , 352 org.xml.sax.SAXException 353 { 354 QDocument doc = new QDocument(); 355 DOMBuilder builder = new DOMBuilder(); 356 357 builder.init(doc); 358 String systemId = null; 359 if (is instanceof ReadStream) { 360 systemId = ((ReadStream) is).getPath().getUserPath(); 361 } 362 363 doc.setSystemId(systemId); 364 builder.setSystemId(systemId); 365 builder.setSkipWhitespace(true); 366 367 InputSource in = new InputSource (); 368 in.setByteStream(is); 369 in.setSystemId(systemId); 370 371 Xml xml = new Xml(); 372 xml.setOwner(doc); 373 xml.setResinInclude(_allowResinInclude); 374 375 if (schema != null) { 376 Verifier verifier = schema.newVerifier(); 377 VerifierFilter filter = verifier.getVerifierFilter(); 378 379 filter.setParent(xml); 380 filter.setContentHandler(builder); 381 filter.setErrorHandler(builder); 382 383 filter.parse(in); 384 } 385 else { 386 xml.setContentHandler(builder); 387 xml.parse(in); 388 } 389 390 return doc; 391 } 392 393 private Schema findCompactSchema(String location) 394 throws IOException , ConfigException 395 { 396 try { 397 if (location == null) 398 return null; 399 400 MergePath schemaPath = new MergePath(); 401 schemaPath.addClassPath(); 402 403 Path path = schemaPath.lookup(location); 404 if (path.canRead()) { 405 407 CompactVerifierFactoryImpl factory; 408 factory = new CompactVerifierFactoryImpl(); 409 410 return factory.compileSchema(path); 411 } 412 else 413 return null; 414 } catch (IOException e) { 415 throw e; 416 } catch (Exception e) { 417 throw new ConfigException(e); 418 } 419 } 420 421 424 public Object configureMap(Object obj, Map <String ,Object > map) 425 throws Exception 426 { 427 return new MapBuilder().configure(obj, map); 428 } 429 430 433 public static void checkCanInstantiate(Class beanClass) 434 throws ConfigException 435 { 436 if (beanClass == null) 437 throw new ConfigException(L.l("null classes can't be instantiated.")); 438 else if (beanClass.isInterface()) 439 throw new ConfigException(L.l("`{0}' must be a concrete class. Interfaces cannot be instantiated.", beanClass.getName())); 440 else if (! Modifier.isPublic(beanClass.getModifiers())) 441 throw new ConfigException(L.l("Custom bean class `{0}' is not public. Bean classes must be public, concrete, and have a zero-argument constructor.", beanClass.getName())); 442 else if (Modifier.isAbstract(beanClass.getModifiers())) 443 throw new ConfigException(L.l("Custom bean class `{0}' is abstract. Bean classes must be public, concrete, and have a zero-argument constructor.", beanClass.getName())); 444 445 Constructor []constructors = beanClass.getDeclaredConstructors(); 446 447 Constructor constructor = null; 448 449 for (int i = 0; i < constructors.length; i++) { 450 if (constructors[i].getParameterTypes().length == 0) { 451 constructor = constructors[i]; 452 break; 453 } 454 } 455 456 if (constructor == null) 457 throw new ConfigException(L.l("Custom bean class `{0}' doesn't have a zero-arg constructor. Bean classes must be have a zero-argument constructor.", beanClass.getName())); 458 459 if (! Modifier.isPublic(constructor.getModifiers())) { 460 throw new ConfigException(L.l("The zero-argument constructor for `{0}' isn't public. Bean classes must have a public zero-argument constructor.", beanClass.getName())); 461 } 462 } 463 464 467 public static void validate(Class cl, Class api) 468 throws ConfigException 469 { 470 checkCanInstantiate(cl); 471 472 if (! api.isAssignableFrom(cl)) { 473 throw new ConfigException(L.l("{0} must implement {1}.", 474 cl.getName(), api.getName())); 475 } 476 } 477 478 485 public static void setAttribute(Object obj, String attr, Object value) 486 throws Exception 487 { 488 TypeStrategy strategy = TypeStrategyFactory.getTypeStrategy(obj.getClass()); 489 490 QName attrName = new QName(attr); 491 AttributeStrategy attrStrategy = strategy.getAttributeStrategy(attrName); 492 attrStrategy.setAttribute(obj, attrName, value); 493 } 494 495 public static void init(Object bean) 496 throws ConfigException 497 { 498 try { 499 TypeStrategy strategy; 500 501 strategy = TypeStrategyFactory.getTypeStrategy(bean.getClass()); 502 503 strategy.init(bean); 504 } catch (RuntimeException e) { 505 throw e; 506 } catch (Exception e) { 507 throw new ConfigException(e); 508 } 509 } 510 511 public static Object replaceObject(Object bean) throws Exception 512 { 513 TypeStrategy strategy = TypeStrategyFactory.getTypeStrategy(bean.getClass()); 514 515 return strategy.replaceObject(bean); 516 } 517 518 521 public static ELContext getEnvironment() 522 { 523 NodeBuilder builder = NodeBuilder.getCurrentBuilder(); 524 525 if (builder != null) { 526 return builder.getELContext(); 527 } 528 else 529 return EL.getEnvironment(); 530 } 531 532 535 public static ConfigELContext getELContext() 536 { 537 NodeBuilder builder = NodeBuilder.getCurrentBuilder(); 538 539 if (builder != null) { 540 return builder.getELContext(); 541 } 542 else 543 return null; 544 } 545 546 549 public static void setELContext(ConfigELContext context) 550 { 551 NodeBuilder builder = NodeBuilder.getCurrentBuilder(); 552 553 if (builder != null) { 554 builder.setELContext(context); 555 } 556 } 557 558 561 public void setVar(String var, Object value) 562 { 563 setCurrentVar(var, value); 564 565 _vars.put(var, value); 566 } 567 568 571 public static void setCurrentVar(String var, Object value) 572 { 573 NodeBuilder builder = NodeBuilder.getCurrentBuilder(); 574 575 if (builder != null) 576 builder.putVar(var, value); 577 } 578 579 582 public static Object getCurrentVar(String var) 583 { 584 NodeBuilder builder = NodeBuilder.getCurrentBuilder(); 585 586 if (builder != null) 587 return builder.getVar(var); 588 else 589 return null; 590 } 591 592 595 public static Object getVar(String var) throws ELException 596 { 597 return getEnvironment().getELResolver().getValue(getEnvironment(), 598 var, null); 599 } 600 601 604 public static String evalString(String str) 605 throws ELException 606 { 607 return AttributeStrategy.evalString(str); 608 } 609 610 613 public static String evalString(String str, HashMap <String ,Object > varMap) 614 throws ELException 615 { 616 return EL.evalString(str, getEnvironment(varMap)); 617 } 618 619 622 public static boolean evalBoolean(String str) 623 throws ELException 624 { 625 return AttributeStrategy.evalBoolean(str); 626 } 627 628 public static ELContext getEnvironment(HashMap <String ,Object > varMap) 629 { 630 ELContext context = Config.getEnvironment(); 631 632 ELResolver parent = null; 633 634 if (context != null) 635 parent = context.getELResolver(); 636 637 if (varMap != null) 638 return new EnvironmentContext(varMap); 639 else 640 return new EnvironmentContext(); 641 } 642 } 643 644 | Popular Tags |