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