001 /*
002 * jDTAUS Core API
003 * Copyright (c) 2005 Christian Schulte
004 *
005 * Christian Schulte, Haldener Strasse 72, 58095 Hagen, Germany
006 * <schulte2005@users.sourceforge.net> (+49 2331 3543887)
007 *
008 * This library is free software; you can redistribute it and/or
009 * modify it under the terms of the GNU Lesser General Public
010 * License as published by the Free Software Foundation; either
011 * version 2.1 of the License, or any later version.
012 *
013 * This library is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016 * Lesser General Public License for more details.
017 *
018 * You should have received a copy of the GNU Lesser General Public
019 * License along with this library; if not, write to the Free Software
020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
021 *
022 */
023 package org.jdtaus.core.container;
024
025 import java.lang.reflect.Constructor;
026 import java.lang.reflect.InvocationTargetException;
027 import java.lang.reflect.Method;
028
029 /**
030 * Factory for the {@code Container} singleton.
031 *
032 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
033 * @version $Id: ContainerFactory.java 8044 2009-07-02 01:29:05Z schulte2005 $
034 */
035 public abstract class ContainerFactory
036 {
037 //--Constants---------------------------------------------------------------
038
039 /** Default {@code Container} implementation. */
040 private static final String DEFAULT_CONTAINER =
041 "org.jdtaus.core.container.ri.client.DefaultContainer";
042
043 /** Empty array. */
044 private static final Class[] EMPTY =
045 {
046 };
047
048 //---------------------------------------------------------------Constants--
049 //--ContainerFactory--------------------------------------------------------
050
051 /** Default singleton instance. */
052 private static Container instance;
053
054 /**
055 * Gets the {@code Container} singleton.
056 * <p>By default this class will instantiate a new container and hold it in
057 * a static class variable as the singleton to return for other calls. This
058 * behaviour can be changed by setting a system property with key
059 * {@code org.jdtaus.core.container.ContainerFactory} to the name of a
060 * class defining a {@code public static Container getContainer()} method
061 * returning the singleton instance of {@code Container}.</p>
062 *
063 * @return the singleton {@code Container} instance.
064 *
065 * @throws ContainerError for unrecoverable container errors.
066 *
067 * @see ContainerFactory#newContainer()
068 */
069 public static Container getContainer()
070 {
071 Object ret = null;
072 final String factory = System.getProperty(
073 ContainerFactory.class.getName() );
074
075 try
076 {
077 if ( factory != null )
078 {
079 // Call getContainer() on that class.
080 final Class clazz = ClassLoaderFactory.loadClass(
081 ContainerFactory.class, factory );
082
083 final Method meth = clazz.getDeclaredMethod( "getContainer",
084 EMPTY );
085
086 ret = meth.invoke( null, EMPTY );
087 }
088 else
089 {
090 if ( instance == null )
091 {
092 instance = newContainer();
093 }
094
095 ret = instance;
096 }
097
098 return (Container) ret;
099 }
100 catch ( SecurityException e )
101 {
102 throw new ContainerError( e );
103 }
104 catch ( NoSuchMethodException e )
105 {
106 throw new ContainerError( e );
107 }
108 catch ( IllegalAccessException e )
109 {
110 throw new ContainerError( e );
111 }
112 catch ( InvocationTargetException e )
113 {
114 final Throwable targetException = e.getTargetException();
115
116 if ( targetException instanceof Error )
117 {
118 throw (Error) targetException;
119 }
120 else if ( targetException instanceof RuntimeException )
121 {
122 throw (RuntimeException) targetException;
123 }
124 else
125 {
126 throw new ContainerError( targetException == null
127 ? e
128 : targetException );
129 }
130 }
131 catch ( ClassCastException e )
132 {
133 throw new ContainerError( e );
134 }
135 catch ( ClassNotFoundException e )
136 {
137 throw new ContainerError( e );
138 }
139 }
140
141 /**
142 * Creates a new instance of the {@code Container} singleton implementation.
143 * <p>The container implementation to be used can be controlled via a system
144 * property with key {@code org.jdtaus.core.container.Container} set to a
145 * class name to be loaded as the container implementation.</p>
146 * <p>This method should be used by {@code getContainer()} implementors to
147 * retrieve a new {@code Container} instance.</p>
148 *
149 * @return a new instance of the configured {@code Container}
150 * implementation.
151 *
152 * @throws ContainerError for unrecoverable container errors.
153 */
154 public static Container newContainer()
155 {
156 final String impl = System.getProperty( Container.class.getName(),
157 DEFAULT_CONTAINER );
158
159 Constructor ctor = null;
160
161 try
162 {
163 final Class clazz = ClassLoaderFactory.loadClass(
164 ContainerFactory.class, impl );
165
166 ctor = clazz.getDeclaredConstructor( EMPTY );
167 ctor.setAccessible( true );
168 return (Container) ctor.newInstance( EMPTY );
169 }
170 catch ( SecurityException e )
171 {
172 throw new ContainerError( e );
173 }
174 catch ( NoSuchMethodException e )
175 {
176 throw new ContainerError( e );
177 }
178 catch ( IllegalAccessException e )
179 {
180 throw new ContainerError( e );
181 }
182 catch ( java.lang.InstantiationException e )
183 {
184 throw new ContainerError( e );
185 }
186 catch ( InvocationTargetException e )
187 {
188 final Throwable targetException = e.getTargetException();
189
190 if ( targetException instanceof Error )
191 {
192 throw (Error) targetException;
193 }
194 else if ( targetException instanceof RuntimeException )
195 {
196 throw (RuntimeException) targetException;
197 }
198 else
199 {
200 throw new ContainerError( targetException == null
201 ? e
202 : targetException );
203
204 }
205 }
206 catch ( ClassCastException e )
207 {
208 throw new ContainerError( e );
209 }
210 catch ( ClassNotFoundException e )
211 {
212 throw new ContainerError( e );
213 }
214 finally
215 {
216 if ( ctor != null )
217 {
218 ctor.setAccessible( false );
219 }
220 }
221 }
222
223 //--------------------------------------------------------ContainerFactory--
224 }