1 10 package mondrian.util; 11 12 import org.eigenbase.util.property.StringProperty; 13 import java.lang.reflect.Constructor ; 14 import java.lang.reflect.InvocationHandler ; 15 import java.lang.reflect.Proxy ; 16 import java.util.Properties ; 17 18 281 public abstract class ObjectFactory<V> { 282 283 private static final Class [] EMPTY_CLASS_ARRAY = new Class [0]; 284 private static final Object [] EMPTY_OBJECT_ARRAY = new Object [0]; 285 286 289 private final Class <V> interfaceClass; 290 291 299 protected ObjectFactory(final Class <V> interfaceClass) { 300 this.interfaceClass = interfaceClass; 301 } 302 303 311 protected final V getObject() throws CreationException { 312 return getObject(System.getProperties()); 313 } 314 315 326 protected final V getObject(final Properties props) throws CreationException { 327 return getObject(props, EMPTY_CLASS_ARRAY, EMPTY_OBJECT_ARRAY); 328 } 329 330 342 protected final V getObject(final Class [] parameterTypes, 343 final Object [] parameterValues) 344 throws CreationException { 345 return getObject(System.getProperties(), 346 parameterTypes, 347 parameterValues); 348 } 349 350 368 protected V getObject(final Properties props, 369 final Class [] parameterTypes, 370 final Object [] parameterValues) 371 throws CreationException { 372 373 final String className = getClassName(); 375 if (className != null) { 376 return getObject(className, parameterTypes, parameterValues); 377 } 378 379 final String propClassName = getClassName(props); 380 return (propClassName != null) 381 ? getObject(propClassName, parameterTypes, parameterValues) 383 : getDefault(parameterTypes, parameterValues); 385 } 386 387 407 protected V getObject(final String className, 408 final Class [] parameterTypes, 409 final Object [] parameterValues) 410 throws CreationException { 411 try { 412 final ClassLoader loader = 415 Thread.currentThread().getContextClassLoader(); 416 final Class <?> genericClass = 417 Class.forName(className, true, loader); 418 419 if (InvocationHandler .class.isAssignableFrom(genericClass)) { 421 final Constructor constructor = 422 genericClass.getConstructor(parameterTypes); 423 InvocationHandler handler = (InvocationHandler ) 424 constructor.newInstance(parameterValues); 425 return (V) Proxy.newProxyInstance( 426 loader, 427 new Class [] { this.interfaceClass }, 428 handler); 429 } else { 430 final Class <? extends V> specificClass = 431 asSubclass(this.interfaceClass, genericClass); 432 final Constructor <? extends V> constructor = 433 specificClass.getConstructor(parameterTypes); 434 435 return constructor.newInstance(parameterValues); 436 } 437 438 } catch (Exception exc) { 439 throw new CreationException("Error creating object of type \"" + 440 this.interfaceClass.getName() + "\"" , exc); 441 } 442 } 443 444 455 private static <V> Class <? extends V> asSubclass(final Class <V> clazz, 456 final Class <?> genericClass) { 457 if (clazz.isAssignableFrom(genericClass)) { 458 return (Class <? extends V>) genericClass; 459 } else { 460 throw new ClassCastException (genericClass.toString()); 461 } 462 } 463 464 476 protected String getClassName() { 477 return null; 478 } 479 480 490 protected String getClassName(final Properties props) { 491 final StringProperty stringProp = getStringProperty(); 492 final String className = stringProp.get(); 493 return (className != null) 494 ? className 495 : (props == null) 496 ? null : props.getProperty(stringProp.getPath()); 497 } 498 499 504 protected abstract StringProperty getStringProperty(); 505 506 517 protected abstract V getDefault(Class [] parameterTypes, 518 Object [] parameterValues) 519 throws CreationException; 520 521 527 protected CreationException defaultCreationException() { 531 return new CreationException("Error creating object of type \"" + 532 this.interfaceClass.getName() + "\""); 533 } 534 535 543 public Object removeContext() { 544 return null; 545 } 546 547 554 public void restoreContext(final Object context) { 555 } 557 558 559 563 public abstract static class Singleton<T> extends ObjectFactory<T> { 564 565 568 protected T singleInstance; 569 570 575 protected T testSingleInstance; 576 577 585 protected Singleton(final Class <T> interfaceClass) { 586 super(interfaceClass); 587 } 588 589 609 protected T getObject(final Properties props, 610 final Class [] parameterTypes, 611 final Object [] parameterValues) 612 throws CreationException { 613 614 final String className = getClassName(); 616 if (className != null) { 617 if (this.testSingleInstance == null) { 618 this.testSingleInstance = getTestObject(className, 619 parameterTypes, 620 parameterValues); 621 } 622 return this.testSingleInstance; 623 } 624 625 if (this.singleInstance == null) { 634 final String propClassName = getClassName(props); 635 636 this.singleInstance = (propClassName != null) 637 ? getObject(propClassName, parameterTypes, parameterValues) 639 : getDefault(parameterTypes, parameterValues); 641 642 } 643 return this.singleInstance; 644 } 645 646 657 protected T getTestObject(final String className, 658 final Class [] parameterTypes, 659 final Object [] parameterValues) 660 throws CreationException { 661 return getObject(className, parameterTypes, parameterValues); 662 } 663 } 664 665 684 public interface Context { 685 } 686 } 687 688 | Popular Tags |