001/* 002 * jDTAUS Core API 003 * Copyright (C) 2005 Christian Schulte 004 * <cs@schulte.it> 005 * 006 * This library is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU Lesser General Public 008 * License as published by the Free Software Foundation; either 009 * version 2.1 of the License, or any later version. 010 * 011 * This library is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * Lesser General Public License for more details. 015 * 016 * You should have received a copy of the GNU Lesser General Public 017 * License along with this library; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 019 * 020 */ 021package org.jdtaus.core.container; 022 023import java.lang.reflect.Constructor; 024import java.lang.reflect.InvocationTargetException; 025import java.lang.reflect.Method; 026 027/** 028 * Factory for the {@code Context} singleton. 029 * 030 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 031 * @version $JDTAUS: ContextFactory.java 8743 2012-10-07 03:06:20Z schulte $ 032 */ 033public abstract class ContextFactory 034{ 035 //--Constants--------------------------------------------------------------- 036 037 /** Default {@code Context} implementation. */ 038 private static final String DEFAULT_CONTEXT = 039 "org.jdtaus.core.container.ri.client.DefaultContext"; 040 041 /** Empty array. */ 042 private static final Class[] EMPTY = 043 { 044 }; 045 046 //---------------------------------------------------------------Constants-- 047 //--ContextFactory---------------------------------------------------------- 048 049 /** Default singleton instance. */ 050 private static Context instance; 051 052 /** 053 * Gets the {@code Context} singleton. 054 * <p>By default this class will instantiate a new context and hold it in a 055 * static class variable as the singleton to return for other calls. This 056 * behaviour can be changed by setting a system property with key 057 * {@code org.jdtaus.core.container.ContextFactory} to the name of a 058 * class defining a {@code public static Context getContext()} method 059 * returning the singleton instance of {@code Context}.</p> 060 * 061 * @return the singleton {@code Context} instance. 062 * 063 * @throws ContextError for unrecoverable context errors. 064 * 065 * @see ContextFactory#newContext() 066 */ 067 public static Context getContext() 068 { 069 Object ret = null; 070 final String factory = System.getProperty( 071 ContextFactory.class.getName() ); 072 073 try 074 { 075 if ( factory != null ) 076 { 077 // Call getContext() on that class. 078 final Class clazz = ClassLoaderFactory.loadClass( 079 ContextFactory.class, factory ); 080 081 final Method meth = clazz.getDeclaredMethod( "getContext", 082 EMPTY ); 083 084 ret = meth.invoke( null, EMPTY ); 085 } 086 else 087 { 088 if ( instance == null ) 089 { 090 instance = newContext(); 091 } 092 093 ret = instance; 094 } 095 096 return (Context) ret; 097 } 098 catch ( final SecurityException e ) 099 { 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}