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 Context} singleton.
028     *
029     * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
030     * @version $Id: ContextFactory.java 2756 2007-04-14 02:01:15Z schulte2005 $
031     */
032    public abstract class ContextFactory
033    {
034    
035        //--Constants---------------------------------------------------------------
036    
037        /** Default {@code Context} implementation. */
038        private static final String DEFAULT_CONTEXT =
039            "org.jdtaus.core.container.ri.client.DefaultContext";
040    
041        //---------------------------------------------------------------Constants--
042        //--ContextFactory----------------------------------------------------------
043    
044        /** Default singleton instance. */
045        private static Context instance;
046    
047        /**
048         * Gets the {@code Context} singleton.
049         * <p>By default this class will instantiate a new context and hold it in a
050         * static class variable as the singleton to return for other calls. This
051         * behaviour can be changed by setting a system property with key
052         * {@code org.jdtaus.core.container.ContextFactory} to the name of a
053         * class defining a {@code public static Context getContext()} method
054         * returning the singleton instance of {@code Context}.</p>
055         *
056         * @return the singleton {@code Context} instance.
057         *
058         * @throws ContextError for unrecoverable context errors.
059         *
060         * @see ContextFactory#newContext()
061         */
062        public static Context getContext()
063        {
064            Object ret = null;
065            final String factory =
066                System.getProperty(ContextFactory.class.getName());
067    
068            try
069            {
070                if(factory != null)
071                {
072                    final Class clazz;
073                    final Method meth;
074    
075                    // Call getContext() on that class.
076                    clazz = ContainerFactory.loadClass(factory);
077                    meth = clazz.getDeclaredMethod("getContext",
078                        ContainerFactory.EMPTY);
079    
080                    ret = meth.invoke(null, (Object[]) ContainerFactory.EMPTY);
081                }
082                else
083                {
084                    if(ContextFactory.instance == null)
085                    {
086                        ContextFactory.instance =
087                            ContextFactory.newContext();
088    
089                    }
090    
091                    ret = ContextFactory.instance;
092                }
093    
094                return (Context) ret;
095            }
096            catch (SecurityException e)
097            {
098                throw new ContextError(e);
099            }
100            catch (NoSuchMethodException e)
101            {
102                throw new ContextError(e);
103            }
104            catch (IllegalAccessException e)
105            {
106                throw new ContextError(e);
107            }
108            catch (InvocationTargetException e)
109            {
110                throw new ContextError(e.getTargetException() == null ?
111                    e : e.getTargetException());
112    
113            }
114            catch(ClassCastException e)
115            {
116                throw new ContextError(e);
117            }
118        }
119    
120        /**
121         * Creates a new instance of the configured {@code Context} implementation.
122         * <p>The context implementation to be used can be controlled via a system
123         * property with key {@code org.jdtaus.core.container.Context} set
124         * to a class name to be loaded as the context implementation.</p>
125         * <p>This method should be used by {@code getContext()} implementors to
126         * retrieve a new {@code Context} instance.</p>
127         *
128         * @return a new instance of the configured {@code Context}
129         * implementation.
130         *
131         * @throws ContextError for unrecoverable context errors.
132         */
133        public static Context newContext()
134        {
135            Object instance = null;
136            String impl = System.getProperty(Context.class.getName(),
137                ContextFactory.DEFAULT_CONTEXT);
138    
139            try
140            {
141                final Constructor ctor;
142                final Class clazz = ContainerFactory.loadClass(impl);
143    
144                ctor = clazz.getDeclaredConstructor(ContainerFactory.EMPTY);
145                ctor.setAccessible(true);
146                instance = ctor.newInstance((Object[]) ContainerFactory.EMPTY);
147    
148                return (Context) instance;
149            }
150            catch (SecurityException e)
151            {
152                throw new ContextError(e);
153            }
154            catch (NoSuchMethodException e)
155            {
156                throw new ContextError(e);
157            }
158            catch (IllegalAccessException e)
159            {
160                throw new ContextError(e);
161            }
162            catch (java.lang.InstantiationException e)
163            {
164                throw new ContextError(e);
165            }
166            catch (InvocationTargetException e)
167            {
168                throw new ContextError(e.getTargetException() == null ?
169                    e : e.getTargetException());
170    
171            }
172            catch(ClassCastException e)
173            {
174                throw new ContextError(e);
175            }
176        }
177    
178        //----------------------------------------------------------ContextFactory--
179    
180    }