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