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