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 Container} singleton.
29   *
30   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
31   * @version $JDTAUS: ContainerFactory.java 8743 2012-10-07 03:06:20Z schulte $
32   */
33  public abstract class ContainerFactory
34  {
35      //--Constants---------------------------------------------------------------
36  
37      /** Default {@code Container} implementation. */
38      private static final String DEFAULT_CONTAINER =
39          "org.jdtaus.core.container.ri.client.DefaultContainer";
40  
41      /** Empty array. */
42      private static final Class[] EMPTY =
43      {
44      };
45  
46      //---------------------------------------------------------------Constants--
47      //--ContainerFactory--------------------------------------------------------
48  
49      /** Default singleton instance. */
50      private static Container instance;
51  
52      /**
53       * Gets the {@code Container} singleton.
54       * <p>By default this class will instantiate a new container and hold it in
55       * a 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.ContainerFactory} to the name of a
58       * class defining a {@code public static Container getContainer()} method
59       * returning the singleton instance of {@code Container}.</p>
60       *
61       * @return the singleton {@code Container} instance.
62       *
63       * @throws ContainerError for unrecoverable container errors.
64       *
65       * @see ContainerFactory#newContainer()
66       */
67      public static Container getContainer()
68      {
69          Object ret = null;
70          final String factory = System.getProperty(
71              ContainerFactory.class.getName() );
72  
73          try
74          {
75              if ( factory != null )
76              {
77                  // Call getContainer() on that class.
78                  final Class clazz = ClassLoaderFactory.loadClass(
79                      ContainerFactory.class, factory );
80  
81                  final Method meth = clazz.getDeclaredMethod( "getContainer",
82                                                               EMPTY );
83  
84                  ret = meth.invoke( null, EMPTY );
85              }
86              else
87              {
88                  if ( instance == null )
89                  {
90                      instance = newContainer();
91                  }
92  
93                  ret = instance;
94              }
95  
96              return (Container) ret;
97          }
98          catch ( final SecurityException e )
99          {
100             throw new ContainerError( e );
101         }
102         catch ( final NoSuchMethodException e )
103         {
104             throw new ContainerError( e );
105         }
106         catch ( final IllegalAccessException e )
107         {
108             throw new ContainerError( 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 ContainerError( targetException == null
125                                           ? e
126                                           : targetException );
127             }
128         }
129         catch ( final ClassCastException e )
130         {
131             throw new ContainerError( e );
132         }
133         catch ( final ClassNotFoundException e )
134         {
135             throw new ContainerError( e );
136         }
137     }
138 
139     /**
140      * Creates a new instance of the {@code Container} singleton implementation.
141      * <p>The container implementation to be used can be controlled via a system
142      * property with key {@code org.jdtaus.core.container.Container} set to a
143      * class name to be loaded as the container implementation.</p>
144      * <p>This method should be used by {@code getContainer()} implementors to
145      * retrieve a new {@code Container} instance.</p>
146      *
147      * @return a new instance of the configured {@code Container}
148      * implementation.
149      *
150      * @throws ContainerError for unrecoverable container errors.
151      */
152     public static Container newContainer()
153     {
154         final String impl = System.getProperty( Container.class.getName(),
155                                                 DEFAULT_CONTAINER );
156 
157         Constructor ctor = null;
158 
159         try
160         {
161             final Class clazz = ClassLoaderFactory.loadClass(
162                 ContainerFactory.class, impl );
163 
164             ctor = clazz.getDeclaredConstructor( EMPTY );
165             ctor.setAccessible( true );
166             return (Container) ctor.newInstance( EMPTY );
167         }
168         catch ( final SecurityException e )
169         {
170             throw new ContainerError( e );
171         }
172         catch ( final NoSuchMethodException e )
173         {
174             throw new ContainerError( e );
175         }
176         catch ( final IllegalAccessException e )
177         {
178             throw new ContainerError( e );
179         }
180         catch ( final java.lang.InstantiationException e )
181         {
182             throw new ContainerError( e );
183         }
184         catch ( final InvocationTargetException e )
185         {
186             final Throwable targetException = e.getTargetException();
187 
188             if ( targetException instanceof Error )
189             {
190                 throw (Error) targetException;
191             }
192             else if ( targetException instanceof RuntimeException )
193             {
194                 throw (RuntimeException) targetException;
195             }
196             else
197             {
198                 throw new ContainerError( targetException == null
199                                           ? e
200                                           : targetException );
201 
202             }
203         }
204         catch ( final ClassCastException e )
205         {
206             throw new ContainerError( e );
207         }
208         catch ( final ClassNotFoundException e )
209         {
210             throw new ContainerError( e );
211         }
212         finally
213         {
214             if ( ctor != null )
215             {
216                 ctor.setAccessible( false );
217             }
218         }
219     }
220 
221     //--------------------------------------------------------ContainerFactory--
222 }