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 Context} singleton.
031 *
032 * @author <a href="mailto:schulte2005@users.sourceforge.net">Christian Schulte</a>
033 * @version $Id: ContextFactory.java 8044 2009-07-02 01:29:05Z schulte2005 $
034 */
035 public abstract class ContextFactory
036 {
037 //--Constants---------------------------------------------------------------
038
039 /** Default {@code Context} implementation. */
040 private static final String DEFAULT_CONTEXT =
041 "org.jdtaus.core.container.ri.client.DefaultContext";
042
043 /** Empty array. */
044 private static final Class[] EMPTY =
045 {
046 };
047
048 //---------------------------------------------------------------Constants--
049 //--ContextFactory----------------------------------------------------------
050
051 /** Default singleton instance. */
052 private static Context instance;
053
054 /**
055 * Gets the {@code Context} singleton.
056 * <p>By default this class will instantiate a new context and hold it in a
057 * 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.ContextFactory} to the name of a
060 * class defining a {@code public static Context getContext()} method
061 * returning the singleton instance of {@code Context}.</p>
062 *
063 * @return the singleton {@code Context} instance.
064 *
065 * @throws ContextError for unrecoverable context errors.
066 *
067 * @see ContextFactory#newContext()
068 */
069 public static Context getContext()
070 {
071 Object ret = null;
072 final String factory = System.getProperty(
073 ContextFactory.class.getName() );
074
075 try
076 {
077 if ( factory != null )
078 {
079 // Call getContext() on that class.
080 final Class clazz = ClassLoaderFactory.loadClass(
081 ContextFactory.class, factory );
082
083 final Method meth = clazz.getDeclaredMethod( "getContext",
084 EMPTY );
085
086 ret = meth.invoke( null, EMPTY );
087 }
088 else
089 {
090 if ( instance == null )
091 {
092 instance = newContext();
093 }
094
095 ret = instance;
096 }
097
098 return (Context) ret;
099 }
100 catch ( SecurityException e )
101 {
102 throw new ContextError( e );
103 }
104 catch ( NoSuchMethodException e )
105 {
106 throw new ContextError( e );
107 }
108 catch ( IllegalAccessException e )
109 {
110 throw new ContextError( 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 ContextError( targetException == null
127 ? e
128 : targetException );
129
130 }
131 }
132 catch ( ClassCastException e )
133 {
134 throw new ContextError( e );
135 }
136 catch ( ClassNotFoundException e )
137 {
138 throw new ContextError( e );
139 }
140 }
141
142 /**
143 * Creates a new instance of the configured {@code Context} implementation.
144 * <p>The context implementation to be used can be controlled via a system
145 * property with key {@code org.jdtaus.core.container.Context} set
146 * to a class name to be loaded as the context implementation.</p>
147 * <p>This method should be used by {@code getContext()} implementors to
148 * retrieve a new {@code Context} instance.</p>
149 *
150 * @return a new instance of the configured {@code Context}
151 * implementation.
152 *
153 * @throws ContextError for unrecoverable context errors.
154 */
155 public static Context newContext()
156 {
157 final String impl = System.getProperty( Context.class.getName(),
158 DEFAULT_CONTEXT );
159
160 Constructor ctor = null;
161
162 try
163 {
164 final Class clazz = ClassLoaderFactory.loadClass(
165 ContextFactory.class, impl );
166
167 ctor = clazz.getDeclaredConstructor( EMPTY );
168 ctor.setAccessible( true );
169 return (Context) ctor.newInstance( EMPTY );
170 }
171 catch ( SecurityException e )
172 {
173 throw new ContextError( e );
174 }
175 catch ( NoSuchMethodException e )
176 {
177 throw new ContextError( e );
178 }
179 catch ( IllegalAccessException e )
180 {
181 throw new ContextError( e );
182 }
183 catch ( java.lang.InstantiationException e )
184 {
185 throw new ContextError( e );
186 }
187 catch ( InvocationTargetException e )
188 {
189 final Throwable targetException = e.getTargetException();
190
191 if ( targetException instanceof Error )
192 {
193 throw (Error) targetException;
194 }
195 else if ( targetException instanceof RuntimeException )
196 {
197 throw (RuntimeException) targetException;
198 }
199 else
200 {
201 throw new ContextError( targetException == null
202 ? e
203 : targetException );
204
205 }
206 }
207 catch ( ClassCastException e )
208 {
209 throw new ContextError( e );
210 }
211 catch ( ClassNotFoundException e )
212 {
213 throw new ContextError( e );
214 }
215 finally
216 {
217 if ( ctor != null )
218 {
219 ctor.setAccessible( false );
220 }
221 }
222 }
223
224 //----------------------------------------------------------ContextFactory--
225 }