001/*
002// This software is subject to the terms of the Eclipse Public License v1.0
003// Agreement, available at the following URL:
004// http://www.eclipse.org/legal/epl-v10.html.
005// You must accept the terms of that agreement to use this software.
006//
007// Copyright (C) 2007-2012 Pentaho and others
008// All Rights Reserved.
009*/
010package mondrian.util;
011
012import org.eigenbase.util.property.StringProperty;
013
014import java.lang.reflect.*;
015import java.util.Properties;
016
017/**
018 * Concrete derived classes of the generic <code>ObjectFactory</code> class
019 * are used to produce an implementation of an interface (a
020 * normal interface implementation or a Proxy). In general, a
021 * factory should produce a default implementation for general application
022 * use as well as particular implementations used during testing.
023 * During testing of application code and during normal execution,
024 * the application code uses one of the <code>ObjectFactory</code>'s
025 * methods for producing implementation instances - the same method is
026 * used both for test and non-test modes. There are two ways of
027 * modifying the implementation returned to the application code.
028 *
029 * <p>The first is for the application to use Properties.
030 * The <code>ObjectFactory</code> implementation looks for a given
031 * property (by default the name of the property is the class name
032 * of the interfaceClass object) and if found uses it as the classname
033 * to create.</p>
034 *
035 * <p>A second approach is to use a ThreadLocal; if the ThreadLocal
036 * is non-empty then use it as the class name.</p>
037 *
038 * <p>When to use a Factory?
039 *
040 * <p>Everyone has an opinion. For me, there are two criteria: enabling
041 * unit testing and providing end-user/developer-customizer overriding.
042 *
043 * <p>If a method has side-effects, either its result depends upon
044 * a side-effect or calling it causes a side-effect, then the Object
045 * hosting the method is a candidate for having a factory. Why?
046 * Well, consider the case where a method returns the value of
047 * a System property and the System property is determined only once
048 * and set to a static final variable:
049 *
050 * <pre>
051 *      class OneValue {
052 *          private static final boolean propValue;
053 *          static {
054 *              propValue = Boolean.getBoolean("com.app.info.value");
055 *          }
056 *          .....
057 *          public boolean hasInfo() {
058 *              return propValue;
059 *          }
060 *      }
061 * </pre>
062 *
063 * <p>In this case, only one value is ever returned. If you have a
064 * module, a client of the above code, that uses the value returned
065 * by a call to the
066 * <code>hasInfo()</code> method, how do you write a unit test of
067 * your module that tests both possible return values?
068 * You can not, its value is based upon a side-effect, an external
069 * value that can not be controlled by the unit test.</p>
070 *
071 * <p>If the <code>OneValue</code> class was an interface and there was a
072 * factory, then the unit test could arrange that its own version of the
073 * <code>OneValue</code>
074 * interface was returned and in one test arrange that <code>true</code>
075 * was returned and in a second test, arrange that <code>false</code>
076 * was returned.</p>
077 *
078 * <p>The above is a trivial example of code that disallows clients of the
079 * code from being properly tested.</p>
080 *
081 * <p>Another example might be a module that directly initializes a JMS
082 * queue and receives JMS message
083 * from the JMS queue. This code can not be tested without having a live
084 * JMS queue. On the other hand, if one defines an interface allowing
085 * one to wrap access to the JMS queue and accesses the implementation
086 * via a factory, then unit tests can be create that use a mock
087 * JMS queue.</p>
088 *
089 * <p>With regards to providing end-user/developer-customizer overriding,
090 * its generally good to have a flexible application framework.
091 * Experimental or just different implementations can be developed and
092 * tested without having to touch a lot of the application code itself.</p>
093 *
094 * <p>There is, of course, a trade-off between the use of a factory
095 * and the size or simplicity of the object being created.</p>
096 *
097 * <p>What are the requirements for a template ObjectFactory?</p>
098 *
099 * <p>First, every implementation must support the writing of unit tests.
100 * What this means it that test cases can override what the factory
101 * produces. The test cases can all use the same produced Object or
102 * each can request an Object targeted to its particular test. All this
103 * without changing the <code>default</code> behavior of the factory.</p>
104 *
105 * <p>Next, it should be possible to create a factory from the template that
106 * is intended to deliver the same Object each time it is called, a
107 * different, new Object each time it is called, or, based on the
108 * calling environment (parameters, properties, <code>ThreadLocal</code>,
109 * etc.) one of a set of Objects. These are possible <code>default</code>
110 * behaviors, but, again, they can be overridden for test purposes.</p>
111 *
112 * <p>While a factory has a <code>default</code> behavior in an
113 * application, it must be possible for every factory's behavior
114 * in that application to be globally overridden. What that means is
115 * if the application designer has dictated a <code>default</code>, the
116 * application user should be able to change the default. An example of
117 * this is overriding what Object is returned based upon a
118 * <code>System</code> property value.</p>
119 *
120 * <p>Lastly, every factory is a singleton - if an interface with
121 * an implementation whose creation is mediated by a factory, then
122 * there is a single factory that does that creating.
123 * This does not mean that such a factory always return the same value,
124 * rather that there is only one instance of the factory itself.</p>
125 *
126 * <p>The following is an example class that generates a factory
127 * singleton. In this case, the factory extends the
128 * <code>ObjectFactory</code>
129 * rather than the <code>ObjectFactory.Singleton</code>:</p>
130 *
131 * <pre>
132 *
133 *      public final class FooFactory extends ObjectFactory<Foo> {
134 *          // The single instance of the factory
135 *          private static final FooFactory factory;
136 *          static {
137 *              factory = new FooFactory();
138 *          }
139 *          public static FooFactory instance() {
140 *              return factory;
141 *          }
142 *          ..........
143 *          private FooFactory() {
144 *              super(Foo.class);
145 *          }
146 *          ..........
147 *      }
148 *
149 * </pre>
150 *
151 * <p>There are multiple ways of creating derived classes that have support
152 * for unit testing. A very simple way is to use <code>ThreadLocal</code>s.</p>
153 *
154 * <pre>
155 *
156 *          private static final ThreadLocal ClassName = new ThreadLocal();
157 *          private static String getThreadLocalClassName() {
158 *              return (String) ClassName.get();
159 *          }
160 *          public static void setThreadLocalClassName(String className) {
161 *              ClassName.set(className);
162 *          }
163 *          public static void clearThreadLocalClassName() {
164 *              ClassName.set(null);
165 *          }
166 *          ..........
167 *          protected String getClassName() {
168 *              return getThreadLocalClassName();
169 *          }
170 *
171 * </pre>
172 *
173 * <p>Here, the unit test will call the <code>setThreadLocalClassName</code>
174 * method setting it with the class name of a specialized implementation of
175 * the template interface. In the <code>finally</code> clause of the
176 * unit test, it is very important that there be a call to the
177 * <code>clearThreadLocalClassName</code> method so that other
178 * tests, etc. do not get an instance of the test-specific specialized
179 * implementation.</p>
180 *
181 * <p>The following is an example unit test that uses the factory's
182 * <code>ThreadLocal</code> to override the implementation that is returned.</p>
183 *
184 * <pre>
185 *      interface Boo {
186 *          boolean getValue();
187 *          .......
188 *      }
189 *      class NormalBooImpl implements Boo {
190 *          public boolean getValue() { ... }
191 *          .......
192 *      }
193 *      class MyCode {
194 *          private Boo boo;
195 *          MyCode() {
196 *              boo = BooFactory.instance().getObject();
197 *          }
198 *          .......
199 *          int getValue() {
200 *              if (boo.getValue()) {
201 *                  return 1;
202 *              } else {
203 *                  return 0;
204 *              }
205 *
206 *          }
207 *      }
208 *
209 *      class MyCodeTest {
210 *          private static boolean testValue;
211 *          static class BooTest1 implements Boo {
212 *              public boolean getValue() {
213 *                  return MyTest.testValue;
214 *              }
215 *              .....
216 *          }
217 *          static class BooTest2 implements
218 *                      java.lang.reflect.InvocationHandler {
219 *              private final Boo boo;
220 *              public BooTest2() {
221 *                  // remove test class name
222 *                  BooFactory.clearThreadLocalClassName();
223 *                  // get default Boo implementation
224 *                  this.boo = BooFactory.instance().getObject();
225 *              }
226 *              public Object invoke(Object proxy, Method method, Object[] args)
227 *                  throws Throwable {
228 *                  if (method.getName().equals("getValue")) [
229 *                      return new Boolean(MyTest.testValue);
230 *                  } else {
231 *                      return method.invoke(this.boo, args);
232 *                  }
233 *              }
234 *          }
235 *          public void test1() {
236 *              try {
237 *                  // Factory will creates test class
238 *                  BooFactory.setThreadLocalClassName("MyTest.BooTest1");
239 *
240 *                  MyTest.testValue = true;
241 *                  MyCode myCode = new MyCode();
242 *                  int value = myCode.getValue();
243 *                  assertTrue("Value not 1", (value == 1));
244 *
245 *                  MyTest.testValue = false;
246 *                  myCode = new MyCode();
247 *                  value = myCode.getValue();
248 *                  assertTrue("Value not 0", (value == 0));
249 *              } finally {
250 *                  BooFactory.clearThreadLocalClassName();
251 *              }
252 *          }
253 *          public void test2() {
254 *              try {
255 *                  // Use InvocationHandler and Factory Proxy capability
256 *                  BooFactory.setThreadLocalClassName("MyTest.BooTest2");
257 *
258 *                  MyTest.testValue = true;
259 *                  MyCode myCode = new MyCode();
260 *                  int value = myCode.getValue();
261 *                  assertTrue("Value not 1", (value == 1));
262 *
263 *                  MyTest.testValue = false;
264 *                  myCode = new MyCode();
265 *                  value = myCode.getValue();
266 *                  assertTrue("Value not 0", (value == 0));
267 *              } finally {
268 *                  BooFactory.clearThreadLocalClassName();
269 *              }
270 *          }
271 *      }
272 *
273 * </pre>
274 *
275 * <p>While this is a very simple example, it shows how using such factories
276 * can aid in creating testable code. The MyCode method is a client of
277 * the Boo implementation. How to test the two different code branches the
278 * method can take? Because the Boo object is generated by a factory,
279 * one can override what object the factory returns.</p>
280 *
281 * @author Richard M. Emberson
282 * @since Feb 01 2007
283 */
284public abstract class ObjectFactory<V> {
285
286    private static final Class[] EMPTY_CLASS_ARRAY = new Class[0];
287    private static final Object[] EMPTY_OBJECT_ARRAY = new Object[0];
288
289    /**
290     * The type of the object to be generated.
291     */
292    private final Class<V> interfaceClass;
293
294    /**
295     * Creates a new factory object. The <code>interfaceClass</code> parameter
296     * is used to cast the object generated to type right type.
297     *
298     * @param interfaceClass the class object for the interface implemented
299     * by the objects returned by this factory
300     *
301     */
302    protected ObjectFactory(final Class<V> interfaceClass) {
303        this.interfaceClass = interfaceClass;
304    }
305
306    /**
307     * Constructs an object where the System Properties can be used
308     * to look up a class name.
309     * The constructor for the object takes no parameters.
310     *
311     * @return the newly created object
312     * @throws CreationException if unable to create the object
313     */
314    protected final V getObject() throws CreationException {
315        return getObject(System.getProperties());
316    }
317
318    /**
319     * Constructs an object where the <code>Properties</code> parameter can
320     * be used to look up a class name.
321     * The constructor for the object takes no parameters.
322     *
323     * @param props the property definitions to use to determine the
324     * implementation class
325     *
326     * @return the newly created object
327     * @throws CreationException if unable to create the object
328     */
329    protected final V getObject(final Properties props)
330        throws CreationException
331    {
332        return getObject(props, EMPTY_CLASS_ARRAY, EMPTY_OBJECT_ARRAY);
333    }
334
335    /**
336     * Constructs an object where the <code>parameterTypes</code> and
337     * <code>parameterValues</code> are constructor parameters and
338     * System Properties are used to look up a class name.
339     *
340     * @param parameterTypes  the class parameters that define the signature
341     * of the constructor to use
342     * @param parameterValues  the values to use to construct the current
343     * instance of the object
344     * @return the newly created object
345     * @throws CreationException if unable to create the object
346     */
347    protected final V getObject(
348        final Class[] parameterTypes,
349        final Object[] parameterValues)
350        throws CreationException
351    {
352        return getObject(
353            System.getProperties(), parameterTypes, parameterValues);
354    }
355
356    /**
357     * Constructs an object where the <code>parameterTypes</code> and
358     * <code>parameterValues</code> are constructor parameters and
359     * Properties parameter is used to look up a class name.
360     * <p>
361     * This returns a new instance of the Object each time its
362     * called (assuming that if the method <code>getDefault</code>,
363     * which derived classes implement), if called, creates a new
364     * object each time.
365     *
366     * @param props the property definitions to use to determine the
367     * @param parameterTypes  the class parameters that define the signature
368     * of the constructor to use
369     * @param parameterValues  the values to use to construct the current
370     * instance of the object
371     * @return the newly created object
372     * @throws CreationException if unable to create the object
373     */
374    protected V getObject(
375        final Properties props,
376        final Class[] parameterTypes,
377        final Object[] parameterValues) throws CreationException
378    {
379        // Unit test override
380        final String className = getClassName();
381        if (className != null) {
382            return getObject(className, parameterTypes, parameterValues);
383        }
384
385        final String propClassName = getClassName(props);
386        return (propClassName != null)
387            // User overriding application default
388            ? getObject(propClassName, parameterTypes, parameterValues)
389            // Get application default
390            : getDefault(parameterTypes, parameterValues);
391    }
392
393    /**
394     * Creates an instance with the given <code>className</code>,
395     * <code>parameterTypes</code> and <code>parameterValues</code> or
396     * throw a <code>CreationException</code>. There are two different
397     * mechanims available. The first is to uses reflection
398     * to create the instance typing the generated Object based upon
399     * the <code>interfaceClass</code> factory instance object.
400     * With the second the <code>className</code> is an class that implements
401     * the <code>InvocationHandler</code> interface and in this case
402     * the <code>java.lang.reflect.Proxy</code> class is used to
403     * generate a proxy.
404     *
405     * @param className the class name used to create Object instance
406     * @param parameterTypes  the class parameters that define the signature
407     * of the constructor to use
408     * @param parameterValues  the values to use to construct the current
409     * instance of the object
410     * @return the newly created object
411     * @throws CreationException if unable to create the object
412     */
413    protected V getObject(
414        final String className,
415        final Class[] parameterTypes,
416        final Object[] parameterValues) throws CreationException
417    {
418        try {
419            // As a place to begin google:
420            //   org.apache.cxf.BusFactoryHelper.java
421            final Class<?> genericClass =
422                ClassResolver.INSTANCE.forName(className, true);
423
424            // Are we creating a Proxy or an instance?
425            if (InvocationHandler.class.isAssignableFrom(genericClass)) {
426                final Constructor constructor =
427                    genericClass.getConstructor(parameterTypes);
428                InvocationHandler handler = (InvocationHandler)
429                    constructor.newInstance(parameterValues);
430                //noinspection unchecked
431                return (V) Proxy.newProxyInstance(
432                    genericClass.getClassLoader(),
433                    new Class[] { this.interfaceClass },
434                    handler);
435            } else {
436                final Class<? extends V> specificClass =
437                    genericClass.asSubclass(interfaceClass);
438                final Constructor<? extends V> constructor =
439                    specificClass.getConstructor(parameterTypes);
440
441                return constructor.newInstance(parameterValues);
442            }
443        } catch (Exception exc) {
444            throw new CreationException(
445                "Error creating object of type \""
446                    + this.interfaceClass.getName() + "\"",
447                exc);
448        }
449    }
450
451    /**
452     * Returns the name of a class to use to create an object.
453     * The default implementation returns null but derived
454     * classes can return a class name.
455     * <p>
456     * This method is the primary mechanism for supporting Unit testing.
457     * A derived class can have, as an example, this method return
458     * the value of a <code>ThreadLocal</code>. For testing it
459     * return a class name while for normal use it returns <code>null</code>.
460     *
461     * @return <code>null</code> or a class name
462     */
463    protected String getClassName() {
464        return null;
465    }
466
467    /**
468     * Returns the name of a class to use to create an object.
469     * The factory's <code>StringProperty</code> is gotten and
470     * if it has a non-null value, then that is returned. Otherwise,
471     * the <code>StringProperty</code>'s name (path) is used as the
472     * name to probe the <code>Properties</code> object for a value.
473     * This method is allowed to return null.
474     *
475     * @return <code>null</code> or a class name
476     */
477    protected String getClassName(final Properties props) {
478        final StringProperty stringProp = getStringProperty();
479        final String className = stringProp.get();
480        return (className != null)
481            ? className
482            : (props == null)
483            ? null : props.getProperty(stringProp.getPath());
484    }
485
486    /**
487     * Return the <code>StringProperty</code> associated with this factory.
488     *
489     * @return the  <code>StringProperty</code>
490     */
491    protected abstract StringProperty getStringProperty();
492
493    /**
494     * For most uses (other than testing) this is the method that derived
495     * classes implement that return the desired object.
496     *
497     * @param parameterTypes  the class parameters that define the signature
498     * of the constructor to use
499     * @param parameterValues  the values to use to construct the current
500     * instance of the object
501     * @return the newly created object
502     * @throws CreationException if unable to create the object
503     */
504    protected abstract V getDefault(
505        Class[] parameterTypes,
506        Object[] parameterValues)
507        throws CreationException;
508
509    /**
510     * Gets the current override values in the opaque context object and
511     * clears those values within the Factory.
512     *
513     * <p>This is used in testing.
514     *
515     * @return the test <code>Context</code> object.
516     */
517    public Object removeContext() {
518        return null;
519    }
520
521    /**
522     * Restores the context object resetting override values.
523     *
524     * <p>This is used in testing.
525     *
526     * @param context the context object to be restored.
527     */
528    public void restoreContext(final Object context) {
529        // empty
530    }
531
532
533    /**
534     * Implementation of ObjectFactory
535     * that returns only a single instance of the Object.
536     */
537    public static abstract class Singleton<T> extends ObjectFactory<T> {
538
539        /**
540         * The single instance of the object created by the factory.
541         */
542        protected T singleInstance;
543
544        /**
545         * The test single instance of the object created by the factory.
546         * Creating this <code>testSingleInstance</code> does not change the
547         * current value of the <code>singleInstance</code> variable.
548         */
549        protected T testSingleInstance;
550
551        /**
552         * Creates a new singleton factory object. The
553         * <code>interfaceClass</code> parameter
554         * is used to cast the object generated to type right type.
555         *
556         * @param interfaceClass the class object for the interface implemented
557         * by the objects returned by this factory
558         */
559        protected Singleton(final Class<T> interfaceClass) {
560            super(interfaceClass);
561        }
562
563        /**
564         * Returns the singleton Object.
565         * The first time this is called, an object is created where
566         * the <code>parameterTypes</code> and
567         * <code>parameterValues</code> are constructor parameters and
568         * Properties parameter is used to look up a class name.
569         * <p>
570         * This returns a same instance of the Object each time its
571         * called except if the <code>getClassName</code> method
572         * returns a non-null class name which should only
573         * happen as needed for unit testing.
574         *
575         * @param props the property definitions to use to determine the
576         * @param parameterTypes  the class parameters that define the signature
577         * of the constructor to use
578         * @param parameterValues  the values to use to construct the current
579         * instance of the object
580         * @return the newly created object
581         * @throws CreationException if unable to create the object
582         */
583        protected T getObject(
584            final Properties props,
585            final Class[] parameterTypes,
586            final Object[] parameterValues) throws CreationException
587        {
588            // Unit test override, do not use application instance.
589            final String className = getClassName();
590            if (className != null) {
591                if (this.testSingleInstance == null) {
592                    this.testSingleInstance =
593                        getTestObject(
594                            className,
595                            parameterTypes,
596                            parameterValues);
597                }
598                return this.testSingleInstance;
599            }
600
601            // NOTE: Should we distinguish between any Properties Object
602            // and that returned by System? When its the System's
603            // Properties Object (which is not a final instance variable
604            // within the System class), then its for sure the user
605            // providing a global override. If its not the System
606            // Properties object, then it may or may not be a global
607            // override so we may not want to set the singleInstance
608            // to it. For now I am ignoring the issue.
609            if (this.singleInstance == null) {
610                final String propClassName = getClassName(props);
611
612                this.singleInstance = (propClassName != null)
613                    // The user overriding application default
614                    ? getObject(propClassName, parameterTypes, parameterValues)
615                    // Get application default
616                    : getDefault(parameterTypes, parameterValues);
617            }
618            return this.singleInstance;
619        }
620
621        /**
622         * Create an instance for test purposes.
623         *
624         * @param className the class name used to create Object instance
625         * @param parameterTypes  the class parameters that define the signature
626         * of the constructor to use
627         * @param parameterValues  the values to use to construct the current
628         * instance of the object
629         * @return the newly created object
630         * @throws CreationException if unable to create the object
631         */
632        protected T getTestObject(
633            final String className,
634            final Class[] parameterTypes,
635            final Object[] parameterValues) throws CreationException
636        {
637            return getObject(className, parameterTypes, parameterValues);
638        }
639    }
640
641    /**
642     * This is for testing only.
643     * <p>
644     * <code>Context</code> contain the Factory implementation specific
645     * non-default values and mechanism for overriding the default
646     * instance type returned by the Factory.
647     * Factory implementation can extend the <code>Context</code> interface
648     * to capture its specific override values.
649     * If, for example, a Factory implementation uses a <code>ThreadLocal</code>
650     * to override the default instance type for unit tests, then the
651     * <code>Context</code>
652     * will hold the current value of the <code>ThreadLocal</code>.
653     * Getting the Context, clears the <code>ThreadLocal</code> value.
654     * This allows the tester who wishes to create code that will provide
655     * a wrapper around the default instance type to register their
656     * wrapper class name with the <code>ThreadLocal</code>, and, within
657     * the wrapper constructor, get the <code>Context</code>, get
658     * a default instance, and then restore the <code>Context</code>.
659     */
660    public interface Context {
661    }
662}
663
664// End ObjectFactory.java