2 Copyright (c) 2010, 2011, 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);