View Javadoc

1   /*
2    *  jDTAUS Core API
3    *  Copyright (C) 2005 Christian Schulte
4    *  <cs@schulte.it>
5    *
6    *  This library is free software; you can redistribute it and/or
7    *  modify it under the terms of the GNU Lesser General Public
8    *  License as published by the Free Software Foundation; either
9    *  version 2.1 of the License, or any later version.
10   *
11   *  This library is distributed in the hope that it will be useful,
12   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   *  Lesser General Public License for more details.
15   *
16   *  You should have received a copy of the GNU Lesser General Public
17   *  License along with this library; if not, write to the Free Software
18   *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19   *
20   */
21  package org.jdtaus.core.container;
22  
23  import java.lang.reflect.Constructor;
24  import java.lang.reflect.InvocationTargetException;
25  import java.lang.reflect.Method;
26  
27  /**
28   * Factory for the {@code Model} singleton.
29   *
30   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
31   * @version $JDTAUS: ModelFactory.java 8743 2012-10-07 03:06:20Z schulte $
32   */
33  public abstract class ModelFactory
34  {
35      //--Constants---------------------------------------------------------------
36  
37      /** Default {@code Model} implementation. */
38      private static final String DEFAULT_MODEL =
39          "org.jdtaus.core.container.ri.client.DefaultModel";
40  
41      /** Empty array. */
42      private static final Class[] EMPTY =
43      {
44      };
45  
46      //---------------------------------------------------------------Constants--
47      //--ModelFactory------------------------------------------------------------
48  
49      /** Default singleton instance. */
50      private static Model instance;
51  
52      /**
53       * Gets the {@code Model} singleton.
54       * <p>By default this class will instantiate a new instance and hold it in
55       * a static class variable as the singleton to return for other calls. This
56       * behaviour can be changed by setting a system property with key
57       * {@code org.jdtaus.core.container.ModelFactory} to the name of a
58       * class defining a {@code public static Model getModel()} method
59       * returning the singleton instance of the model.</p>
60       *
61       * @return the singleton {@code Model} instance.
62       *
63       * @throws ModelError for unrecoverable model errors.
64       *
65       * @see ModelFactory#newModel()
66       */
67      public static Model getModel()
68      {
69          Object ret = null;
70          final String factory = System.getProperty(
71              ModelFactory.class.getName() );
72  
73          try
74          {
75              if ( factory != null )
76              {
77                  // Call getModel() on that class.
78                  final Class clazz = ClassLoaderFactory.loadClass(
79                      ModelFactory.class, factory );
80  
81                  final Method meth = clazz.getDeclaredMethod( "getModel",
82                                                               EMPTY );
83  
84                  ret = meth.invoke( null, EMPTY );
85              }
86              else
87              {
88                  if ( instance == null )
89                  {
90                      instance = newModel();
91                  }
92  
93                  ret = instance;
94              }
95  
96              return (Model) ret;
97          }
98          catch ( final SecurityException e )
99          {
100             throw new ModelError( e );
101         }
102         catch ( final NoSuchMethodException e )
103         {
104             throw new ModelError( e );
105         }
106         catch ( final IllegalAccessException e )
107         {
108             throw new ModelError( 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 ModelError( targetException == null
125                                       ? e
126                                       : targetException );
127 
128             }
129         }
130         catch ( final ClassCastException e )
131         {
132             throw new ModelError( e );
133         }
134         catch ( final ClassNotFoundException e )
135         {
136             throw new ModelError( e );
137         }
138     }
139 
140     /**
141      * Creates a new instance of the configured {@code Model} implementation.
142      * <p>The implementation to be used can be controlled via a system property
143      * with key {@code org.jdtaus.core.container.Model} set to a class
144      * name to be loaded as the {@code Model} implementation.</p>
145      * <p>This method should be used by {@code getModel()} implementors to
146      * retrieve a new {@code Model} instance.</p>
147      *
148      * @return a new instance of the configured {@code Model} implementation.
149      *
150      * @throws ModelError for unrecoverable model errors.
151      */
152     public static Model newModel()
153     {
154         Constructor ctor = null;
155 
156         try
157         {
158             final String className = System.getProperty( Model.class.getName(),
159                                                          DEFAULT_MODEL );
160 
161             final Class clazz = ClassLoaderFactory.loadClass(
162                 ModelFactory.class, className );
163 
164             ctor = clazz.getDeclaredConstructor( EMPTY );
165             ctor.setAccessible( true );
166             return (Model) ctor.newInstance( EMPTY );
167         }
168         catch ( final SecurityException e )
169         {
170             throw new ModelError( e );
171         }
172         catch ( final NoSuchMethodException e )
173         {
174             throw new ModelError( e );
175         }
176         catch ( final IllegalArgumentException e )
177         {
178             throw new ModelError( e );
179         }
180         catch ( final IllegalAccessException e )
181         {
182             throw new ModelError( e );
183         }
184         catch ( final java.lang.InstantiationException e )
185         {
186             throw new ModelError( e );
187         }
188         catch ( final InvocationTargetException e )
189         {
190             final Throwable targetException = e.getTargetException();
191 
192             if ( targetException instanceof Error )
193             {
194                 throw (Error) targetException;
195             }
196             else if ( targetException instanceof RuntimeException )
197             {
198                 throw (RuntimeException) targetException;
199             }
200             else
201             {
202                 throw new ModelError( targetException == null
203                                       ? e
204                                       : targetException );
205 
206             }
207         }
208         catch ( final ClassCastException e )
209         {
210             throw new ModelError( e );
211         }
212         catch ( final ClassNotFoundException e )
213         {
214             throw new ModelError( e );
215         }
216         finally
217         {
218             if ( ctor != null )
219             {
220                 ctor.setAccessible( false );
221             }
222         }
223     }
224 
225     //------------------------------------------------------------ModelFactory--
226 }