KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opensubsystems > core > persist > DataFactoryManager


1 /*
2  * Copyright (c) 2003 - 2007 OpenSubsystems s.r.o. Slovak Republic. All rights reserved.
3  *
4  * Project: OpenSubsystems
5  *
6  * $Id: DataFactoryManager.java,v 1.10 2007/01/07 06:15:05 bastafidli Exp $
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; version 2 of the License.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */

21
22 package org.opensubsystems.core.persist;
23
24 import java.util.HashMap JavaDoc;
25 import java.util.Map JavaDoc;
26 import java.util.logging.Logger JavaDoc;
27
28 import org.opensubsystems.core.error.OSSException;
29 import org.opensubsystems.core.persist.db.DatabaseFactoryClassFactory;
30 import org.opensubsystems.core.util.ClassFactory;
31 import org.opensubsystems.core.util.GlobalConstants;
32 import org.opensubsystems.core.util.Log;
33
34 /**
35  * Class responsible for instantiation of data factories. This class determines
36  * what data factory should be used based on currently used persistence mechanism,
37  * creates the factory instance if it wasn't created yet and caches created
38  * instances. This of course assumes that the data factories are implemented to
39  * be stateless and reentrant.
40  *
41  * @version $Id: DataFactoryManager.java,v 1.10 2007/01/07 06:15:05 bastafidli Exp $
42  * @author Miro Halas
43  * @code.reviewer Miro Halas
44  * @code.reviewed 1.7 2006/04/05 04:58:26 bastafidli
45  */

46 public class DataFactoryManager
47 {
48    // Constants ////////////////////////////////////////////////////////////////
49

50    /**
51     * Lock used in synchronized sections.
52     */

53    private static final String JavaDoc IMPL_LOCK = "IMPL_LOCK";
54
55    // Attributes ///////////////////////////////////////////////////////////////
56

57    /**
58     * Class factory used to instantiate data factorys.
59     */

60    protected ClassFactory m_factoryClassFactory;
61    
62    /**
63     * Cache where already instantiated data factories will be cached. We can
64     * cache them since data factories should be reentrant.
65     */

66    private Map JavaDoc m_mpFactoryCache;
67    
68    // Cached values ////////////////////////////////////////////////////////////
69

70    /**
71     * Logger for this class
72     */

73    private static Logger JavaDoc s_logger = Log.getInstance(DataFactoryManager.class);
74    
75    /**
76     * Reference to the instance actually in use.
77     */

78    private static DataFactoryManager s_defaultInstance;
79
80    // Constructors /////////////////////////////////////////////////////////////
81

82    /**
83     * Default constructor.
84     */

85    public DataFactoryManager(
86    )
87    {
88       m_factoryClassFactory = new DatabaseFactoryClassFactory();
89       m_mpFactoryCache = new HashMap JavaDoc();
90    }
91    
92    /**
93     * Create data factory for specified class.
94     *
95     * @param dataFactory - the data factory interface for which we want
96     * applicable factory. This is usually persistence
97     * independent class and we will try to create
98     * dependent class, such as one which can persist
99     * data in database.
100     * @return DataFactory - the data factory to use for given interface
101     * @throws OSSException - an error has occured
102     */

103    public static DataFactory getInstance(
104       Class JavaDoc dataFactory
105    ) throws OSSException
106    {
107       return getManagerInstance().getFactoryInstance(dataFactory);
108    }
109    
110    /**
111     * Get the default instance. This method is here to make the factory manager
112     * configurable. Once can specify in configuration file derived class to used
113     * instead of this one [DataFactoryManager.class]=new class to use.
114     *
115     * @return DatabaseFactoryManager
116     * @throws OSSException - cannot get current database
117     */

118    public static DataFactoryManager getManagerInstance(
119    ) throws OSSException
120    {
121       if (s_defaultInstance == null)
122       {
123          // Only if the default instance wasn't set by other means create a new one
124
// Synchronize just for the creation
125
synchronized (IMPL_LOCK)
126          {
127             setManagerInstance((DataFactoryManager)
128                ClassFactory.getInstance().createInstance(
129                   DataFactoryManager.class, DataFactoryManager.class));
130          }
131       }
132       
133       return s_defaultInstance;
134    }
135    
136    /**
137     * Set default instance. This instance will be returned by getInstance
138     * method until it is changed.
139     *
140     * @param defaultInstance - new default instance
141     * @see #getInstance
142     */

143    public static void setManagerInstance(
144       DataFactoryManager defaultInstance
145    )
146    {
147       if (GlobalConstants.ERROR_CHECKING)
148       {
149          assert defaultInstance != null : "Default instance cannot be null";
150       }
151       
152       synchronized (IMPL_LOCK)
153       {
154          s_defaultInstance = defaultInstance;
155          s_logger.fine("Default data factory manager is "
156                        + s_defaultInstance.getClass().getName());
157       }
158    }
159
160    /**
161     * Method to create actual factory based on specified class. This method can
162     * be overriden and new manager can be setup either through setManagerInstance
163     * or through configuration file if different strategy is desired.
164     *
165     * @param dataFactory - the data factory interface for which we want
166     * applicable factory. This is usually persistence
167     * independent class and we will try to create
168     * dependent class, such as one which can persist
169     * data in database.
170     * @return DataFactory - the data factory to use for given interface
171     * @throws OSSException - an error has occured
172     */

173    public DataFactory getFactoryInstance(
174       Class JavaDoc dataFactory
175    ) throws OSSException
176    {
177       Object JavaDoc factory;
178       
179       factory = m_mpFactoryCache.get(dataFactory.getName());
180       if (factory == null)
181       {
182          synchronized (m_mpFactoryCache)
183          {
184             factory = m_factoryClassFactory.createInstance(dataFactory);
185             // Use name and not the instance as a key since if the class is loaded
186
// through different class loader, it wouldn't match
187
m_mpFactoryCache.put(dataFactory.getName(), factory);
188          }
189       }
190       
191       return (DataFactory)factory;
192    }
193 }
194
Popular Tags