2
Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
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.
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.
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
18
package com.mysql.clusterj;
20
import java.io.BufferedReader;
21
import java.io.IOException;
22
import java.io.InputStream;
23
import java.io.InputStreamReader;
27
import java.util.ArrayList;
28
import java.util.Enumeration;
29
import java.util.List;
33
* ClusterJHelper provides helper methods to bridge between the API and
36
public class ClusterJHelper {
38
/** Locate a SessionFactory implementation by services lookup. The class loader
39
* used is the thread's context class loader.
41
* @param props properties of the session factory
42
* @return the session factory
43
* @throws ClusterFatalUserException if the connection to the cluster cannot be made
45
public static SessionFactory getSessionFactory(Map props) {
46
return getSessionFactory(props, Thread.currentThread().getContextClassLoader());
49
/** Locate a SessionFactory implementation by services lookup of
50
* a specific class loader. The properties are a Map that might contain
51
* implementation-specific properties plus standard properties.
53
* @param props the properties for the factory
54
* @param loader the class loader for the factory implementation
55
* @return the session factory
56
* @throws ClusterFatalUserException if the connection to the cluster cannot be made
58
public static SessionFactory getSessionFactory(Map props, ClassLoader loader) {
59
SessionFactoryService service =
60
getServiceInstance(SessionFactoryService.class, loader);
61
SessionFactory factory = service.getSessionFactory(props);
65
/** Locate a service implementation by services lookup of
66
* the context class loader.
68
* @param cls the class of the factory
69
* @return the service instance
71
public static <T> T getServiceInstance(Class<T> cls) {
72
return getServiceInstance(cls, Thread.currentThread().getContextClassLoader());
75
/** Locate all service implementations by services lookup of
76
* a specific class loader. Implementations in the services file
77
* are instantiated and returned. Failed instantiations are remembered
78
* in the errorMessages buffer.
80
* @param cls the class of the factory
81
* @param loader the class loader for the factory implementation
82
* @param errorMessages a buffer used to hold the error messages
83
* @return the service instance
85
@SuppressWarnings("unchecked") // Class.forName
86
public static <T> List<T> getServiceInstances(Class<T> cls, ClassLoader loader,
87
StringBuffer errorMessages) {
88
// find all service implementations of the class in the class loader.
89
List<T> result = new ArrayList<T>();
90
String factoryName = cls.getName();
91
String serviceName = "META-INF/services/" + factoryName;
92
Enumeration<URL> urls = null;
94
urls = loader.getResources(serviceName);
95
} catch (IOException ex) {
96
throw new ClusterJFatalUserException(ex);
98
while (urls.hasMoreElements()) {
99
InputStream inputStream = null;
100
InputStreamReader inputStreamReader = null;
101
BufferedReader bufferedReader = null;
103
URL url = urls.nextElement();
104
inputStream = url.openStream();
105
inputStreamReader = new InputStreamReader(inputStream);
106
bufferedReader = new BufferedReader(inputStreamReader);
107
factoryName = bufferedReader.readLine();
108
Class<T> serviceClass = (Class<T>)Class.forName(factoryName, true, loader);
109
T service = serviceClass.newInstance();
110
if (service != null) {
113
} catch (IOException ex) {
114
errorMessages.append(ex.toString());
115
} catch (ClassNotFoundException ex) {
116
errorMessages.append(ex.toString());
117
} catch (InstantiationException ex) {
118
errorMessages.append(ex.toString());
119
} catch (IllegalAccessException ex) {
120
errorMessages.append(ex.toString());
123
if (inputStream != null) {
126
} catch (IOException ioex) {
127
// nothing to do here
134
/** Locate a service implementation for a service by services lookup of
135
* a specific class loader. The first service instance found is returned.
137
* @param cls the class of the factory
138
* @param loader the class loader for the factory implementation
139
* @return the service instance
141
public static <T> T getServiceInstance(Class<T> cls, ClassLoader loader) {
142
StringBuffer errorMessages = new StringBuffer();
143
List<T> services = getServiceInstances(cls, loader, errorMessages);
144
if (services.size() != 0) {
145
return services.get(0);
147
String factoryName = cls.getName();
148
String serviceName = "META-INF/services/" + factoryName;
149
throw new ClusterJFatalUserException(
150
"No instance for service " + factoryName +
151
" could be found. " +
152
"Make sure that there is a file " + serviceName +
153
" in your class path naming the factory class." +
158
/** Locate a service implementation for a service.
159
* If the implementation name is not null, use it instead of
160
* looking up. If the implementation class is not loadable or does not
161
* implement the interface, throw an exception.
163
* @param implementationClassName
164
* @return the implementation instance for a service
166
@SuppressWarnings("unchecked") // (Class<T>)clazz
167
public static <T> T getServiceInstance(Class<T> cls, String implementationClassName) {
168
if (implementationClassName == null) {
169
return getServiceInstance(cls);
172
ClassLoader loader = Thread.currentThread().getContextClassLoader();
173
Class<?> clazz = Class.forName(implementationClassName, true, loader);
174
Class<T> serviceClass = null;
175
if (!(cls.isAssignableFrom(clazz))) {
176
throw new ClassCastException(cls.getName() + " " + implementationClassName);
178
serviceClass = (Class<T>)clazz;
179
T service = serviceClass.newInstance();
181
} catch (ClassNotFoundException e) {
182
throw new ClusterJFatalUserException(implementationClassName, e);
183
} catch (ClassCastException e) {
184
throw new ClusterJFatalUserException(implementationClassName, e);
185
} catch (InstantiationException e) {
186
throw new ClusterJFatalUserException(implementationClassName, e);
187
} catch (IllegalAccessException e) {
188
throw new ClusterJFatalUserException(implementationClassName, e);