]> review.fuel-infra Code Review - packages/trusty/mysql-wsrep-5.6.git/blob
a659e79e0dd4e9d753168a4e2b13f0ef8bdfae66
[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;
19
20 import java.io.BufferedReader;
21 import java.io.IOException;
22 import java.io.InputStream;
23 import java.io.InputStreamReader;
24
25 import java.net.URL;
26
27 import java.util.ArrayList;
28 import java.util.Enumeration;
29 import java.util.List;
30 import java.util.Map;
31
32 /**
33  * ClusterJHelper provides helper methods to bridge between the API and
34  * the implementation.
35  */
36 public class ClusterJHelper {
37
38     /** Locate a SessionFactory implementation by services lookup. The class loader
39      * used is the thread's context class loader.
40      *
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
44      */
45     public static SessionFactory getSessionFactory(Map props) {
46         return getSessionFactory(props, Thread.currentThread().getContextClassLoader());
47     }
48
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.
52      *
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
57      */
58     public static SessionFactory getSessionFactory(Map props, ClassLoader loader) {
59         SessionFactoryService service =
60                 getServiceInstance(SessionFactoryService.class, loader);
61         SessionFactory factory = service.getSessionFactory(props);
62         return factory;
63     }
64
65     /** Locate a service implementation by services lookup of
66      * the context class loader.
67      *
68      * @param cls the class of the factory
69      * @return the service instance
70      */
71     public static <T> T getServiceInstance(Class<T> cls) {
72         return getServiceInstance(cls, Thread.currentThread().getContextClassLoader());
73     }
74
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.
79      *
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
84      */
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;
93         try {
94             urls = loader.getResources(serviceName);
95         } catch (IOException ex) {
96             throw new ClusterJFatalUserException(ex);
97         }
98         while (urls.hasMoreElements()) {
99             InputStream inputStream = null;
100             InputStreamReader inputStreamReader = null;
101             BufferedReader bufferedReader = null;
102             try {
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) {
111                     result.add(service);
112                 }
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());
121             } finally {
122                 try {
123                     if (inputStream != null) {
124                         inputStream.close();
125                     }
126                 } catch (IOException ioex) {
127                     // nothing to do here
128                 }
129             }
130         }
131         return result;
132     }
133
134     /** Locate a service implementation for a service by services lookup of
135      * a specific class loader. The first service instance found is returned.
136      *
137      * @param cls the class of the factory
138      * @param loader the class loader for the factory implementation
139      * @return the service instance
140      */
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);
146         } else {
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." +
154                     errorMessages);
155         }
156     }
157
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.
162      * @param cls
163      * @param implementationClassName
164      * @return the implementation instance for a service
165      */
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);
170         } else {
171             try {
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);
177                 }
178                 serviceClass = (Class<T>)clazz;
179                 T service = serviceClass.newInstance();
180                 return service;
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);
189             }
190         }
191     }
192
193 }