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 Container} singleton. 029 * 030 * @author <a href="mailto:cs@schulte.it">Christian Schulte</a> 031 * @version $JDTAUS: ContainerFactory.java 8743 2012-10-07 03:06:20Z schulte $ 032 */ 033public abstract class ContainerFactory 034{ 035 //--Constants--------------------------------------------------------------- 036 037 /** Default {@code Container} implementation. */ 038 private static final String DEFAULT_CONTAINER = 039 "org.jdtaus.core.container.ri.client.DefaultContainer"; 040 041 /** Empty array. */ 042 private static final Class[] EMPTY = 043 { 044 }; 045 046 //---------------------------------------------------------------Constants-- 047 //--ContainerFactory-------------------------------------------------------- 048 049 /** Default singleton instance. */ 050 private static Container instance; 051 052 /** 053 * Gets the {@code Container} singleton. 054 * <p>By default this class will instantiate a new container and hold it in 055 * a 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.ContainerFactory} to the name of a 058 * class defining a {@code public static Container getContainer()} method 059 * returning the singleton instance of {@code Container}.</p> 060 * 061 * @return the singleton {@code Container} instance. 062 * 063 * @throws ContainerError for unrecoverable container errors. 064 * 065 * @see ContainerFactory#newContainer() 066 */ 067 public static Container getContainer() 068 { 069 Object ret = null; 070 final String factory = System.getProperty( 071 ContainerFactory.class.getName() ); 072 073 try 074 { 075 if ( factory != null ) 076 { 077 // Call getContainer() on that class. 078 final Class clazz = ClassLoaderFactory.loadClass( 079 ContainerFactory.class, factory ); 080 081 final Method meth = clazz.getDeclaredMethod( "getContainer", 082 EMPTY ); 083 084 ret = meth.invoke( null, EMPTY ); 085 } 086 else 087 { 088 if ( instance == null ) 089 { 090 instance = newContainer(); 091 } 092 093 ret = instance; 094 } 095 096 return (Container) ret; 097 } 098 catch ( final SecurityException e ) 099 { 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}