]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
81c1dcf8c97aac2c45d7944c5dc17be3e2e38dd7
[packages/trusty/mysql-wsrep-5.6.git] /
1 /*
2    Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; version 2 of the License.
7
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
16 */
17
18 package com.mysql.clusterj.openjpa;
19
20 import com.mysql.clusterj.ClusterJFatalInternalException;
21 import com.mysql.clusterj.ClusterJHelper;
22 import com.mysql.clusterj.SessionFactory;
23
24 import com.mysql.clusterj.core.SessionFactoryImpl;
25
26 import com.mysql.clusterj.core.spi.DomainTypeHandler;
27 import com.mysql.clusterj.core.spi.DomainTypeHandlerFactory;
28 import com.mysql.clusterj.core.store.Dictionary;
29 import com.mysql.clusterj.core.util.I18NHelper;
30 import com.mysql.clusterj.core.util.Logger;
31 import com.mysql.clusterj.core.util.LoggerFactoryService;
32
33 import java.lang.reflect.InvocationTargetException;
34 import java.lang.reflect.Method;
35 import java.util.HashMap;
36 import java.util.Map;
37 import java.util.Properties;
38
39 import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
40 import org.apache.openjpa.jdbc.meta.ClassMapping;
41 import org.apache.openjpa.lib.conf.BooleanValue;
42 import org.apache.openjpa.lib.conf.IntValue;
43 import org.apache.openjpa.lib.conf.ProductDerivations;
44 import org.apache.openjpa.lib.conf.StringValue;
45
46 /**
47  * Default implementation of the {@link NdbOpenJPAConfiguration} interface.
48  * This implementation extends the JDBCConfiguration so both access
49  * to MySQLd via JDBC and access to Ndb via ClusterJ are supported.
50  * Type safety: The return type Map for getCacheMarshallerInstances()
51  * from the type OpenJPAConfigurationImpl needs unchecked conversion
52  * to conform to Map<String,CacheMarshaller> from the type OpenJPAConfiguration
53  */
54 @SuppressWarnings("unchecked")
55 public class NdbOpenJPAConfigurationImpl extends JDBCConfigurationImpl
56     implements NdbOpenJPAConfiguration, com.mysql.clusterj.Constants, DomainTypeHandlerFactory {
57
58     /** My message translator */
59     static final I18NHelper local = I18NHelper.getInstance(NdbOpenJPAConfigurationImpl.class);
60
61     /** My logger */
62     static final Logger logger = LoggerFactoryService.getFactory().getInstance(NdbOpenJPAConfigurationImpl.class);
63
64     public StringValue connectString;
65     public IntValue connectRetries;
66     public IntValue connectDelay;
67     public IntValue connectVerbose;
68     public IntValue connectTimeoutBefore;
69     public IntValue connectTimeoutAfter;
70     public StringValue username;
71     public StringValue password;
72     public StringValue database;
73     public IntValue maxTransactions;
74     public BooleanValue failOnJDBCPath;
75     public SessionFactoryImpl sessionFactory;
76     private final Map<Class<?>, NdbOpenJPADomainTypeHandlerImpl<?>> domainTypeHandlerMap =
77             new HashMap<Class<?>, NdbOpenJPADomainTypeHandlerImpl<?>>();
78
79     /**
80      * These are to bridge an incompatibility between OpenJPA 1.x and 2.x in the handling of configuration
81      * values. In 1.x, the IntValue.get() method returns int and in 2.x it returns Integer.
82      * Similarly, in 1.x BooleanValue.get() returns boolean and in 2.x it returns Boolean.
83      */
84     static private Method intValueMethod;
85     static private Method booleanValueMethod;
86     static {
87         try {
88             intValueMethod = IntValue.class.getMethod("get", (Class[])null);
89             booleanValueMethod = BooleanValue.class.getMethod("get", (Class[])null);
90         } catch (SecurityException e) {
91             throw new ClusterJFatalInternalException(e);
92         } catch (NoSuchMethodException e) {
93             throw new ClusterJFatalInternalException(e);
94         }
95     }
96
97     /** Return the int value from a configuration IntValue.
98      * 
99      */
100     int getIntValue(IntValue value) {
101         try {
102             return (Integer)intValueMethod.invoke(value);
103         } catch (IllegalArgumentException e) {
104             throw new ClusterJFatalInternalException(e);
105         } catch (IllegalAccessException e) {
106             throw new ClusterJFatalInternalException(e);
107         } catch (InvocationTargetException e) {
108             throw new ClusterJFatalInternalException(e);
109         }
110     }
111     /** Return the boolean value from a configuration BooleanValue.
112      * 
113      */
114     boolean getBooleanValue(BooleanValue value) {
115         try {
116             return (Boolean) booleanValueMethod.invoke(value);
117         } catch (IllegalArgumentException e) {
118             throw new ClusterJFatalInternalException(e);
119         } catch (IllegalAccessException e) {
120             throw new ClusterJFatalInternalException(e);
121         } catch (InvocationTargetException e) {
122             throw new ClusterJFatalInternalException(e);
123         }
124     }
125     /**
126      * Default constructor. Attempts to load default properties.
127      */
128     public NdbOpenJPAConfigurationImpl() {
129         this(true);
130     }
131
132     /**
133      * Constructor.
134      *
135      * @param loadGlobals whether to attempt to load the global properties
136      */
137     public NdbOpenJPAConfigurationImpl(boolean loadGlobals) {
138         this(true, loadGlobals);
139     }
140
141     /**
142      * Constructor.
143      *
144      * @param derivations whether to apply product derivations
145      * @param loadGlobals whether to attempt to load the global properties
146      */
147     public NdbOpenJPAConfigurationImpl(boolean derivations, boolean loadGlobals) {
148         super(false, false);
149
150         connectString = addString("ndb.connectString");
151         connectRetries = addInt("ndb.connectRetries");
152         connectRetries.set(4);
153         connectDelay = addInt("ndb.connectDelay");
154         connectDelay.set(5);
155         connectVerbose = addInt("ndb.connectVerbose");
156         connectVerbose.set(0);
157         connectTimeoutBefore = addInt("ndb.connectTimeoutBefore");
158         connectTimeoutBefore.set(30);
159         connectTimeoutAfter = addInt("ndb.connectTimeoutAfter");
160         connectTimeoutAfter.set(20);
161         username = addString("ndb.username");
162         password = addString("ndb.password");
163         database = addString("ndb.database");
164         database.set("test");
165         maxTransactions = addInt("ndb.maxTransactions");
166         maxTransactions.set(1024);
167         failOnJDBCPath = addBoolean("ndb.failOnJDBCPath");
168         failOnJDBCPath.set(false);
169
170         sessionFactory = null;
171
172         if (derivations)
173             ProductDerivations.beforeConfigurationLoad(this);
174         if (loadGlobals)
175             loadGlobals();
176     }
177
178     /**
179      * Copy constructor
180      */
181     public NdbOpenJPAConfigurationImpl(NdbOpenJPAConfiguration conf) {
182         this(true, false);
183         if (conf != null)
184             fromProperties(conf.toProperties(false));
185     }
186
187     public String getConnectString() {
188         return connectString.get();
189     }
190
191     public void setConnectString(String value) {
192         connectString.set(value);
193     }
194
195     public int getConnectRetries() {
196         return getIntValue(connectRetries);
197     }
198
199     public void setConnectRetries(int value) {
200         connectRetries.set(value);
201     }
202
203     public int getConnectDelay() {
204         return getIntValue(connectDelay);
205     }
206
207     public void setConnectDelay(int value) {
208         connectDelay.set(value);
209     }
210
211     public int getConnectVerbose() {
212         return getIntValue(connectVerbose);
213     }
214
215     public void setConnectVerbose(int value) {
216         connectVerbose.set(value);
217     }
218
219     public int getConnectTimeoutBefore() {
220         return getIntValue(connectTimeoutBefore);
221     }
222
223     public void setConnectTimeoutBefore(int value) {
224         connectTimeoutBefore.set(value);
225     }
226
227     public int getConnectTimeoutAfter() {
228         return getIntValue(connectTimeoutAfter);
229     }
230
231     public void setConnectTimeoutAfter(int value) {
232         connectTimeoutAfter.set(value);
233     }
234
235     public String getUsername() {
236         return username.getString();
237     }
238
239     public void setUsername(String value) {
240         username.setString(value);
241     }
242
243     public String getPassword() {
244         return password.getString();
245     }
246
247     public void setPassword(String value) {
248         password.setString(value);
249     }
250
251     public String getDatabase() {
252         return database.getString();
253     }
254
255     public void setDatabase(String value) {
256         database.setString(value);
257     }
258
259     public int getMaxTransactions() {
260         return getIntValue(maxTransactions);
261     }
262
263     public void setMaxTransactions(int value) {
264         maxTransactions.set(value);
265     }
266
267     public boolean getFailOnJDBCPath() {
268         return getBooleanValue(failOnJDBCPath);
269     }
270
271     public void setFailOnJDBCPath(boolean value) {
272         failOnJDBCPath.set(value);
273     }
274
275     public SessionFactoryImpl getSessionFactory() {
276         if (sessionFactory == null) {
277             sessionFactory = createSessionFactory();
278         }
279         return (SessionFactoryImpl) sessionFactory;
280     }
281
282     public void setSessionFactory(SessionFactory value) {
283         sessionFactory = (SessionFactoryImpl) value;
284     }
285
286     public SessionFactoryImpl createSessionFactory() {
287         // require connectString to be specified
288         if (connectString.get() == null) {
289             throw new IllegalStateException(
290                     local.message("ERR_Missing_Connect_String"));
291         }
292         // map OpenJPA properties to ClusterJ properties
293         Properties props = new Properties();
294         props.put(PROPERTY_CLUSTER_CONNECTSTRING,
295                 connectString.get());
296         props.put(PROPERTY_CLUSTER_CONNECT_RETRIES,
297                 connectRetries.getString());
298         props.put(PROPERTY_CLUSTER_CONNECT_DELAY,
299                 connectDelay.getString());
300         props.put(PROPERTY_CLUSTER_CONNECT_VERBOSE,
301                 connectVerbose.getString());
302         props.put(PROPERTY_CLUSTER_CONNECT_TIMEOUT_BEFORE,
303                 connectTimeoutBefore.getString());
304         props.put(PROPERTY_CLUSTER_CONNECT_TIMEOUT_AFTER,
305                 connectTimeoutAfter.getString());
306         props.put(PROPERTY_CLUSTER_DATABASE,
307                 database.getString());
308         props.put(PROPERTY_CLUSTER_MAX_TRANSACTIONS,
309                 maxTransactions.getString());
310         SessionFactoryImpl factory = (SessionFactoryImpl)
311                 ClusterJHelper.getSessionFactory(props);
312         factory.setDomainTypeHandlerFactory(this);
313         return factory;
314     }
315
316     /** Get the domain type handler for this class mapping. A cached handler is
317      * returned if possible. Synchronize on the class-to-handler map.
318      * @param cmd the openjpa class mapping
319      * @return the domain type handler
320      */
321     public NdbOpenJPADomainTypeHandlerImpl<?> getDomainTypeHandler(
322             ClassMapping cmd, Dictionary dictionary) {
323         NdbOpenJPADomainTypeHandlerImpl<?> result;
324         Class<?> domainClass = cmd.getDescribedType();
325         synchronized(domainTypeHandlerMap) {
326             result = domainTypeHandlerMap.get(domainClass);
327             if (result == null) {
328                 if (logger.isDebugEnabled()) logger.debug("domain class: " + domainClass.getName());
329                 result = createDomainTypeHandler(cmd, dictionary);
330                 domainTypeHandlerMap.put(domainClass, result);
331                 result.initializeRelations();
332                 logger.info("New domain type " + result.getName()
333                         + (result.isSupportedType()?" is supported.":
334                             " is not known to be supported because " + result.getReasons()));
335             }
336         }
337         return result;
338     }
339
340     /** Create a new domain type handler for the class mapping.
341      * 
342      * @param classMapping the openjpa class mapping
343      * @return the domain type handler
344      */
345     private NdbOpenJPADomainTypeHandlerImpl<?> createDomainTypeHandler(
346             ClassMapping classMapping, Dictionary dictionary) {
347         return new NdbOpenJPADomainTypeHandlerImpl<Object>(dictionary, classMapping, this);
348     }
349
350     /**
351      * Free the data sources.
352      */
353     @Override
354     protected void preClose() {
355         if (sessionFactory != null) {
356             sessionFactory.close();
357         }
358         super.preClose();
359     }
360
361     @Override
362     protected boolean isInvalidProperty(String propName) {
363         if (super.isInvalidProperty(propName))
364             return true;
365
366         // handle openjpa.ndb.SomeMisspelledProperty, but not
367         // openjpa.someotherimplementation.SomeProperty
368         String lowerCasePropName = propName.toLowerCase();
369         String[] prefixes = ProductDerivations.getConfigurationPrefixes();
370         for (int i = 0; i < prefixes.length; i++)
371             if (lowerCasePropName.startsWith(prefixes[i] + ".ndb"))
372                 return true; 
373         return false;
374     }
375
376     /** Get the domain type handler for the class. This method is called by the query
377      * handler when performing a clusterj query for an openjpa entity. The class
378      * must have already been registered via the openjpa clusterj path.
379      */
380     public <T> DomainTypeHandler<T> createDomainTypeHandler(
381             Class<T> domainClass, Dictionary dictionary) {
382         DomainTypeHandler<T> result = (DomainTypeHandler<T>) domainTypeHandlerMap.get(domainClass);
383         if (result == null) {
384             throw new ClusterJFatalInternalException(
385                     local.message("ERR_Create_Domain_Type_Handler_First", domainClass.getName()));
386         }
387         return result;
388     }
389
390 }