View Javadoc

1   /*
2    *  jDTAUS Core API
3    *  Copyright (C) 2005 Christian Schulte
4    *  <cs@schulte.it>
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19   *
20   */
21  package org.jdtaus.core.container;
22  
23  import java.lang.reflect.Constructor;
24  import java.lang.reflect.InvocationTargetException;
25  import java.lang.reflect.Method;
26  
27  /**
28   * Factory for the {@code Context} singleton.
29   *
30   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
31   * @version $JDTAUS: ContextFactory.java 8743 2012-10-07 03:06:20Z schulte $
32   */
33  public abstract class ContextFactory
34  {
35      //--Constants---------------------------------------------------------------
36  
37      /** Default {@code Context} implementation. */
38      private static final String DEFAULT_CONTEXT =
39          "org.jdtaus.core.container.ri.client.DefaultContext";
40  
41      /** Empty array. */
42      private static final Class[] EMPTY =
43      {
44      };
45  
46      //---------------------------------------------------------------Constants--
47      //--ContextFactory----------------------------------------------------------
48  
49      /** Default singleton instance. */
50      private static Context instance;
51  
52      /**
53       * Gets the {@code Context} singleton.
54       * <p>By default this class will instantiate a new context and hold it in a
55       * static class variable as the singleton to return for other calls. This
56       * behaviour can be changed by setting a system property with key
57       * {@code org.jdtaus.core.container.ContextFactory} to the name of a
58       * class defining a {@code public static Context getContext()} method
59       * returning the singleton instance of {@code Context}.</p>
60       *
61       * @return the singleton {@code Context} instance.
62       *
63       * @throws ContextError for unrecoverable context errors.
64       *
65       * @see ContextFactory#newContext()
66       */
67      public static Context getContext()
68      {
69          Object ret = null;
70          final String factory = System.getProperty(
71              ContextFactory.class.getName() );
72  
73          try
74          {
75              if ( factory != null )
76              {
77                  // Call getContext() on that class.
78                  final Class clazz = ClassLoaderFactory.loadClass(
79                      ContextFactory.class, factory );
80  
81                  final Method meth = clazz.getDeclaredMethod( "getContext",
82                                                               EMPTY );
83  
84                  ret = meth.invoke( null, EMPTY );
85              }
86              else
87              {
88                  if ( instance == null )
89                  {
90                      instance = newContext();
91                  }
92  
93                  ret = instance;
94              }
95  
96              return (Context) ret;
97          }
98          catch ( final SecurityException e )
99          {
100             throw new ContextError( e );
101         }
102         catch ( final NoSuchMethodException e )
103         {
104             throw new ContextError( e );
105         }
106         catch ( final IllegalAccessException e )
107         {
108             throw new ContextError( e );
109         }
110         catch ( final InvocationTargetException e )
111         {
112             final Throwable targetException = e.getTargetException();
113 
114             if ( targetException instanceof Error )
115             {
116                 throw (Error) targetException;
117             }
118             else if ( targetException instanceof RuntimeException )
119             {
120                 throw (RuntimeException) targetException;
121             }
122             else
123             {
124                 throw new ContextError( targetException == null
125                                         ? e
126                                         : targetException );
127 
128             }
129         }
130         catch ( final ClassCastException e )
131         {
132             throw new ContextError( e );
133         }
134         catch ( final ClassNotFoundException e )
135         {
136             throw new ContextError( e );
137         }
138     }
139 
140     /**
141      * Creates a new instance of the configured {@code Context} implementation.
142      * <p>The context implementation to be used can be controlled via a system
143      * property with key {@code org.jdtaus.core.container.Context} set
144      * to a class name to be loaded as the context implementation.</p>
145      * <p>This method should be used by {@code getContext()} implementors to
146      * retrieve a new {@code Context} instance.</p>
147      *
148      * @return a new instance of the configured {@code Context}
149      * implementation.
150      *
151      * @throws ContextError for unrecoverable context errors.
152      */
153     public static Context newContext()
154     {
155         final String impl = System.getProperty( Context.class.getName(),
156                                                 DEFAULT_CONTEXT );
157 
158         Constructor ctor = null;
159 
160         try
161         {
162             final Class clazz = ClassLoaderFactory.loadClass(
163                 ContextFactory.class, impl );
164 
165             ctor = clazz.getDeclaredConstructor( EMPTY );
166             ctor.setAccessible( true );
167             return (Context) ctor.newInstance( EMPTY );
168         }
169         catch ( final SecurityException e )
170         {
171             throw new ContextError( e );
172         }
173         catch ( final NoSuchMethodException e )
174         {
175             throw new ContextError( e );
176         }
177         catch ( final IllegalAccessException e )
178         {
179             throw new ContextError( e );
180         }
181         catch ( final java.lang.InstantiationException e )
182         {
183             throw new ContextError( e );
184         }
185         catch ( final InvocationTargetException e )
186         {
187             final Throwable targetException = e.getTargetException();
188 
189             if ( targetException instanceof Error )
190             {
191                 throw (Error) targetException;
192             }
193             else if ( targetException instanceof RuntimeException )
194             {
195                 throw (RuntimeException) targetException;
196             }
197             else
198             {
199                 throw new ContextError( targetException == null
200                                         ? e
201                                         : targetException );
202 
203             }
204         }
205         catch ( final ClassCastException e )
206         {
207             throw new ContextError( e );
208         }
209         catch ( final ClassNotFoundException e )
210         {
211             throw new ContextError( e );
212         }
213         finally
214         {
215             if ( ctor != null )
216             {
217                 ctor.setAccessible( false );
218             }
219         }
220     }
221 
222     //----------------------------------------------------------ContextFactory--
223 }