1 28 29 package com.caucho.config; 30 31 import com.caucho.config.jaxb.JaxbBeanType; 32 import com.caucho.config.types.ClassTypeStrategy; 33 import com.caucho.config.types.InitProgram; 34 import com.caucho.config.types.RawString; 35 import com.caucho.loader.EnvironmentBean; 36 import com.caucho.loader.EnvironmentLocal; 37 import com.caucho.util.L10N; 38 import com.caucho.util.Log; 39 import com.caucho.xml.QName; 40 41 import org.w3c.dom.Node ; 42 43 import javax.xml.bind.annotation.XmlRootElement; 44 import java.io.InputStream ; 45 import java.net.URL ; 46 import java.util.Enumeration ; 47 import java.util.HashMap ; 48 import java.util.logging.Logger ; 49 50 53 public class TypeStrategyFactory { 54 private static final Logger log = Log.open(TypeStrategyFactory.class); 55 private static L10N L = new L10N(TypeStrategyFactory.class); 56 57 private static final HashMap <String ,TypeStrategy> _primitiveTypes 58 = new HashMap <String ,TypeStrategy>(); 59 60 private static final EnvironmentLocal<TypeStrategyFactory> _localFactory 61 = new EnvironmentLocal<TypeStrategyFactory>(); 62 63 private final HashMap <String ,TypeStrategy> _typeMap 64 = new HashMap <String ,TypeStrategy>(); 65 66 private final HashMap <QName,AttributeStrategy> _flowMap 67 = new HashMap <QName,AttributeStrategy>(); 68 69 private final HashMap <QName,AttributeStrategy> _envMap 70 = new HashMap <QName,AttributeStrategy>(); 71 72 private TypeStrategyFactory() 73 { 74 75 } 76 77 80 public static TypeStrategy getTypeStrategy(Class type) 81 throws Exception 82 { 83 TypeStrategyFactory factory = getFactory(type.getClassLoader()); 84 85 return factory.getTypeStrategyImpl(type); 86 } 87 88 public static AttributeStrategy getFlowAttribute(Class type, 89 QName name) throws Exception 90 { 91 return getFactory(type.getClassLoader()).getFlowAttribute(name); 92 } 93 94 private AttributeStrategy getFlowAttribute(QName name) 95 { 96 return _flowMap.get(name); 97 } 98 99 public static AttributeStrategy getEnvironmentAttribute(Class type, 100 QName name) throws Exception 101 { 102 return getFactory(type.getClassLoader()).getEnvironmentAttribute(name); 103 } 104 105 private AttributeStrategy getEnvironmentAttribute(QName name) 106 { 107 AttributeStrategy strategy = _envMap.get(name); 108 109 if (strategy != null) 110 return strategy; 111 112 if (name.getLocalName() != null && ! name.getLocalName().equals("")) { 113 strategy = _envMap.get(new QName(name.getLocalName(), null)); 114 return strategy; 115 } 116 else 117 return null; 118 } 119 120 private static TypeStrategyFactory getFactory(ClassLoader loader) 121 throws Exception 122 { 123 if (loader == null) 124 loader = ClassLoader.getSystemClassLoader(); 125 126 TypeStrategyFactory factory = _localFactory.getLevel(loader); 127 128 if (factory == null) { 129 factory = new TypeStrategyFactory(); 130 _localFactory.set(factory, loader); 131 factory.init(loader); 132 } 133 134 return factory; 135 } 136 137 143 private void init(ClassLoader loader) 144 throws Exception 145 { 146 Enumeration <URL > urls = loader.getResources("META-INF/caucho/config-types.xml"); 147 148 while (urls.hasMoreElements()) { 149 URL url = urls.nextElement(); 150 151 InputStream is = url.openStream(); 152 try { 153 new Config(loader).configure(this, is); 154 } catch (Throwable e) { 155 e.printStackTrace(); } finally { 157 is.close(); 158 } 159 } 160 } 161 162 165 public void addTypeStrategy(TypeStrategyConfig config) 166 { 167 _typeMap.put(config.getName(), config.getType()); 168 } 169 170 173 public FlowAttributeConfig createFlowAttribute() 174 { 175 return new FlowAttributeConfig(); 176 } 177 178 181 public EnvironmentAttributeConfig createEnvironmentAttribute() 182 { 183 return new EnvironmentAttributeConfig(); 184 } 185 186 private TypeStrategy getTypeStrategyImpl(Class type) 187 { 188 TypeStrategy strategy = _typeMap.get(type.getName()); 189 190 if (strategy == null) { 191 strategy = _primitiveTypes.get(type.getName()); 192 193 if (strategy != null) { 194 } 195 else if (EnvironmentBean.class.isAssignableFrom(type)) 196 strategy = new EnvironmentTypeStrategy(type); 197 else if (type.isAnnotationPresent(XmlRootElement.class)) 198 strategy = new JaxbBeanType(type); 199 else 200 strategy = new BeanTypeStrategy(type); 201 202 _typeMap.put(type.getName(), strategy); 203 } 204 205 return strategy; 206 } 207 208 public static class TypeStrategyConfig { 210 private String _name; 211 private TypeStrategy _type; 212 213 public void setName(Class type) 214 { 215 _name = type.getName(); 216 } 217 218 public String getName() 219 { 220 return _name; 221 } 222 223 public void setType(Class type) 224 throws ConfigException, IllegalAccessException , InstantiationException 225 { 226 Config.validate(type, TypeStrategy.class); 227 228 _type = (TypeStrategy) type.newInstance(); 229 } 230 231 public TypeStrategy getType() 232 { 233 return _type; 234 } 235 } 236 237 public class EnvironmentAttributeConfig { 238 public void put(QName name, Class type) 239 { 240 TypeStrategy typeStrategy = getTypeStrategyImpl(type); 241 242 _envMap.put(name, new EnvironmentAttributeStrategy(typeStrategy)); 243 } 244 } 245 246 public class FlowAttributeConfig { 247 public void put(QName name, Class type) 248 { 249 TypeStrategy typeStrategy = getTypeStrategyImpl(type); 250 251 _flowMap.put(name, new EnvironmentAttributeStrategy(typeStrategy)); 252 } 253 } 254 256 private static class PrimitiveBooleanTypeStrategy extends TypeStrategy { 257 264 public Object configure(NodeBuilder builder, Node node, Object parent) 265 throws Exception 266 { 267 String value = builder.configureRawString(node); 268 269 if (value == null || value.equals("")) 270 return Boolean.TRUE; else 272 return builder.evalBoolean(value) ? Boolean.TRUE : Boolean.FALSE; 273 } 274 } 275 276 private static class PrimitiveByteTypeStrategy extends TypeStrategy { 277 284 public Object configure(NodeBuilder builder, Node node, Object parent) 285 throws Exception 286 { 287 String value = builder.configureString(node); 288 289 if (value == null || value.equals("")) 290 return new Byte ((byte) 0); 291 else 292 return new Byte (value); 293 } 294 } 295 296 private static class PrimitiveShortTypeStrategy extends TypeStrategy { 297 304 public Object configure(NodeBuilder builder, Node node, Object parent) 305 throws Exception 306 { 307 String value = builder.configureString(node); 308 309 if (value == null || value.equals("")) 310 return new Short ((short) 0); 311 else 312 return new Short (value); 313 } 314 } 315 316 private static class PrimitiveIntTypeStrategy extends TypeStrategy { 317 324 public Object configure(NodeBuilder builder, Node node, Object parent) 325 throws Exception 326 { 327 String value = builder.configureString(node); 328 329 if (value == null || value.equals("")) 330 return new Integer (0); 331 else 332 return new Integer (value); 333 } 334 } 335 336 private static class PrimitiveLongTypeStrategy extends TypeStrategy { 337 344 public Object configure(NodeBuilder builder, Node node, Object parent) 345 throws Exception 346 { 347 String value = builder.configureString(node); 348 349 if (value == null || value.equals("")) 350 return new Long (0); 351 else 352 return new Long (value); 353 } 354 } 355 356 private static class PrimitiveFloatTypeStrategy extends TypeStrategy { 357 364 public Object configure(NodeBuilder builder, Node node, Object parent) 365 throws Exception 366 { 367 String value = builder.configureString(node); 368 369 if (value == null || value.equals("")) 370 return new Float (0); 371 else 372 return new Float (value); 373 } 374 } 375 376 private static class PrimitiveDoubleTypeStrategy extends TypeStrategy { 377 384 public Object configure(NodeBuilder builder, Node node, Object parent) 385 throws Exception 386 { 387 String value = builder.configureString(node); 388 389 if (value == null || value.equals("")) 390 return new Double (0); 391 else 392 return new Double (value); 393 } 394 } 395 396 private static class PrimitiveCharTypeStrategy extends TypeStrategy { 397 404 public Object configure(NodeBuilder builder, Node node, Object parent) 405 throws Exception 406 { 407 String value = builder.configureString(node); 408 409 if (value == null || value.length() == 0) 410 return new Character ((char) 0); 411 else if (value.length() == 1) 412 return new Character (value.charAt(0)); 413 else 414 throw builder.error(L.l("Character must be a single char '{0}'", value), 415 node); 416 } 417 } 418 419 private static class BooleanTypeStrategy extends TypeStrategy { 420 427 public Object configure(NodeBuilder builder, Node node, Object parent) 428 throws Exception 429 { 430 String value = builder.configureRawString(node); 431 432 if (value == null || value.equals("")) 433 return null; 434 else 435 return builder.evalBoolean(value) ? Boolean.TRUE : Boolean.FALSE; 436 } 437 } 438 439 private static class ByteTypeStrategy extends TypeStrategy { 440 447 public Object configure(NodeBuilder builder, Node node, Object parent) 448 throws Exception 449 { 450 String value = builder.configureString(node); 451 452 if (value == null || value.equals("")) 453 return null; 454 else 455 return new Byte (value); 456 } 457 } 458 459 private static class ShortTypeStrategy extends TypeStrategy { 460 467 public Object configure(NodeBuilder builder, Node node, Object parent) 468 throws Exception 469 { 470 String value = builder.configureString(node); 471 472 if (value == null || value.equals("")) 473 return null; 474 else 475 return new Short (value); 476 } 477 } 478 479 private static class IntegerTypeStrategy extends TypeStrategy { 480 487 public Object configure(NodeBuilder builder, Node node, Object parent) 488 throws Exception 489 { 490 String value = builder.configureString(node); 491 492 if (value == null || value.equals("")) 493 return null; 494 else 495 return new Integer (value); 496 } 497 } 498 499 private static class LongTypeStrategy extends TypeStrategy { 500 507 public Object configure(NodeBuilder builder, Node node, Object parent) 508 throws Exception 509 { 510 String value = builder.configureString(node); 511 512 if (value == null || value.equals("")) 513 return null; 514 else 515 return new Long (value); 516 } 517 } 518 519 private static class FloatTypeStrategy extends TypeStrategy { 520 527 public Object configure(NodeBuilder builder, Node node, Object parent) 528 throws Exception 529 { 530 String value = builder.configureString(node); 531 532 if (value == null || value.equals("")) 533 return null; 534 else 535 return new Float (value); 536 } 537 } 538 539 private static class DoubleTypeStrategy extends TypeStrategy { 540 547 public Object configure(NodeBuilder builder, Node node, Object parent) 548 throws Exception 549 { 550 String value = builder.configureString(node); 551 552 if (value == null || value.equals("")) 553 return null; 554 else 555 return new Double (value); 556 } 557 } 558 559 private static class CharacterTypeStrategy extends TypeStrategy { 560 567 public Object configure(NodeBuilder builder, Node node, Object parent) 568 throws Exception 569 { 570 String value = builder.configureString(node); 571 572 if (value == null || value.length() == 0) 573 return null; 574 else if (value.length() == 1) 575 return new Character (value.charAt(0)); 576 else 577 throw builder.error(L.l("Character must be a single char '{0}'", value), 578 node); 579 } 580 } 581 582 private static class StringTypeStrategy extends TypeStrategy { 583 590 public Object configure(NodeBuilder builder, Node node, Object parent) 591 throws Exception 592 { 593 return builder.configureString(node); 594 } 595 } 596 597 private static class RawStringTypeStrategy extends TypeStrategy { 598 605 public Object configure(NodeBuilder builder, Node node, Object parent) 606 throws Exception 607 { 608 return new RawString(builder.configureRawStringNoTrim(node)); 609 } 610 } 611 612 private static class NodeTypeStrategy extends TypeStrategy { 613 620 public Object configure(NodeBuilder builder, Node node, Object parent) 621 throws Exception 622 { 623 return node; 624 } 625 } 626 627 private static class ObjectTypeStrategy extends TypeStrategy { 628 635 public Object configure(NodeBuilder builder, Node node, Object parent) 636 throws Exception 637 { 638 return builder.configureObject(node, parent); 639 } 640 } 641 642 private static class InitProgramTypeStrategy extends TypeStrategy { 643 650 public void configureBean(NodeBuilder builder, Object bean, Node node) 651 throws Exception 652 { 653 InitProgram program = (InitProgram) bean; 654 655 program.addBuilderProgram(new NodeBuilderProgram(builder, node)); 656 } 657 658 665 public Object configure(NodeBuilder builder, Node node, Object parent) 666 throws Exception 667 { 668 return new InitProgram(new NodeBuilderProgram(builder, node)); 669 } 670 } 671 672 private static class BuilderProgramTypeStrategy extends TypeStrategy { 673 680 public Object configure(NodeBuilder builder, Node node, Object parent) 681 throws Exception 682 { 683 return new NodeBuilderChildProgram(builder, node); 684 } 685 } 686 687 static { 688 _primitiveTypes.put("boolean", new PrimitiveBooleanTypeStrategy()); 689 _primitiveTypes.put("byte", new PrimitiveByteTypeStrategy()); 690 _primitiveTypes.put("short", new PrimitiveShortTypeStrategy()); 691 _primitiveTypes.put("int", new PrimitiveIntTypeStrategy()); 692 _primitiveTypes.put("long", new PrimitiveLongTypeStrategy()); 693 _primitiveTypes.put("float", new PrimitiveFloatTypeStrategy()); 694 _primitiveTypes.put("double", new PrimitiveDoubleTypeStrategy()); 695 _primitiveTypes.put("char", new PrimitiveCharTypeStrategy()); 696 697 _primitiveTypes.put("java.lang.Boolean", new BooleanTypeStrategy()); 698 _primitiveTypes.put("java.lang.Byte", new ByteTypeStrategy()); 699 _primitiveTypes.put("java.lang.Short", new ShortTypeStrategy()); 700 _primitiveTypes.put("java.lang.Integer", new IntegerTypeStrategy()); 701 _primitiveTypes.put("java.lang.Long", new LongTypeStrategy()); 702 _primitiveTypes.put("java.lang.Float", new FloatTypeStrategy()); 703 _primitiveTypes.put("java.lang.Double", new DoubleTypeStrategy()); 704 _primitiveTypes.put("java.lang.Character", new CharacterTypeStrategy()); 705 706 _primitiveTypes.put("java.lang.Object", new ObjectTypeStrategy()); 707 _primitiveTypes.put("java.lang.String", new StringTypeStrategy()); 708 _primitiveTypes.put("com.caucho.config.types.RawString", 709 new RawStringTypeStrategy()); 710 _primitiveTypes.put("org.w3c.dom.Node", new NodeTypeStrategy()); 711 _primitiveTypes.put("java.lang.Class", new ClassTypeStrategy()); 712 713 _primitiveTypes.put("com.caucho.config.types.InitProgram", 714 new InitProgramTypeStrategy()); 715 _primitiveTypes.put("com.caucho.config.BuilderProgram", 716 new BuilderProgramTypeStrategy()); 717 } 718 } 719 | Popular Tags |