Statistics
| Revision:

root / trunk / libraries / libDriverManager / src / com / hardcode / driverManager / DriverManager.java @ 10627

History | View | Annotate | Download (7.5 KB)

1
package com.hardcode.driverManager;
2

    
3
import java.io.File;
4
import java.io.IOException;
5

    
6
import java.net.MalformedURLException;
7
import java.net.URL;
8

    
9
import java.util.ArrayList;
10
import java.util.HashMap;
11
import java.util.Iterator;
12

    
13

    
14
/**
15
 * Para el driver manager, el driver viene determinado por un directorio dentro
16
 * del cual se encuentran uno o m?s jar's. La clase Driver ha de implementar
17
 * la interfaz Driver y su nombre debe terminar en "Driver" y tener un
18
 * constructor sin par?metros.
19
 *
20
 * <p>
21
 * Esta clase es la encargada de la carga y validaci?n de los drivers y de la
22
 * obtenci?n de los mismo apartir de un tipo
23
 * </p>
24
 *
25
 * @author Fernando Gonz?lez Cort?s
26
 */
27
public class DriverManager {
28
        private File extDir;
29
        private DriverValidation validation;
30
        private HashMap nombreDriverClass = new HashMap();
31
        private ArrayList failures = new ArrayList();
32
        private ArrayList driversClassLoaders = new ArrayList();
33
        /**
34
         * Devuelve un array con los directorios de los plugins
35
         *
36
         * @param dirExt Directorio a partir del que se cuelgan los directorios de
37
         *                   los drivers
38
         *
39
         * @return Array de los subdirectorios
40
         */
41
        private File[] getPluginDirs(File dirExt) {
42
                if (!dirExt.exists()) {
43
                        return new File[0];
44
                }
45

    
46
                ArrayList ret = new ArrayList();
47
                File[] files = dirExt.listFiles();
48

    
49
                for (int i = 0; i < files.length; i++) {
50
                        if (files[i].isDirectory()) {
51
                                ret.add(files[i]);
52
                        }
53
                }
54

    
55
                return (File[]) ret.toArray(new File[0]);
56
        }
57

    
58
        /**
59
         * Obtiene los jar's de un directorio y los devuelve en un array
60
         *
61
         * @param dir Directorio del que se quieren obtener los jars
62
         *
63
         * @return Array de jars
64
         */
65
        private URL[] getJars(File dir) {
66
                ArrayList ret = new ArrayList();
67
                File[] dirContent = dir.listFiles();
68

    
69
                for (int i = 0; i < dirContent.length; i++) {
70
                        if (dirContent[i].getName().toLowerCase().endsWith(".jar")) {
71
                                try {
72
                                        ret.add(new URL("file:" + dirContent[i].getAbsolutePath()));
73
                                } catch (MalformedURLException e) {
74
                                        //No se puede dar
75
                                }
76
                        }
77
                }
78

    
79
                return (URL[]) ret.toArray(new URL[0]);
80
        }
81

    
82
        /**
83
         * Carga los drivers y asocia con el tipo del driver.
84
         *
85
         * @param dir Directorio ra?z de los drivers
86
         */
87
        public void loadDrivers(File dir) {
88
                try {
89
                        if (validation == null) {
90
                                validation = new DriverValidation() {
91
                                                        public boolean validate(Driver d) {
92
                                                                return true;
93
                                                        }
94
                                                };
95
                        }
96

    
97
                        //Se obtiene la lista de directorios
98
                        File[] dirs = getPluginDirs(dir);
99

    
100
                        //Para cada directorio se obtienen todos sus jars
101
                        for (int i = 0; i < dirs.length; i++) {
102
                                URL[] jars = getJars(dirs[i]);
103

    
104
                                //Se crea el classloader
105
                                DriverClassLoader cl = new DriverClassLoader(jars,
106
                                                dirs[i].getAbsolutePath(),
107
                                                this.getClass().getClassLoader());
108
                                driversClassLoaders.add(cl);
109
                                //Se obtienen los drivers
110
                                Class[] drivers = cl.getDrivers();
111

    
112
                                //Se asocian los drivers con su tipo si superan la validaci?n
113
                                for (int j = 0; j < drivers.length; j++) {
114
                                        try {
115
                                                Driver driver = (Driver) drivers[j].newInstance();
116

    
117
                                                if (validation.validate(driver)) {
118
                                                        if (nombreDriverClass.put(driver.getName(),
119
                                                                                drivers[j]) != null) {
120
                                                                throw new IllegalStateException(
121
                                                                        "Two drivers with the same name:" + driver.getName());
122
                                                        }
123
                                                }
124
                                        } catch (ClassCastException e) {
125
                                                /*
126
                                                 * No todos los que terminan en Driver son drivers
127
                                                 * de los nuestros, los ignoramos
128
                                                 */
129
                                        } catch (Throwable t) {
130
                                                /*
131
                                                 * A?n a riesgo de capturar algo que no debemos, ignoramos cualquier driver que pueda
132
                                                 * dar cualquier tipo de problema, pero continuamos
133
                                                 */
134
                                                failures.add(t);
135
                                        }
136
                                }
137
                        }
138
                } catch (ClassNotFoundException e) {
139
                        failures.add((Throwable) e);
140
                } catch (IOException e) {
141
                        failures.add((Throwable) e);
142
                }
143
        }
144

    
145
        /**
146
         * DOCUMENT ME!
147
         *
148
         * @return DOCUMENT ME!
149
         */
150
        public Throwable[] getLoadFailures() {
151
                return (Throwable[]) failures.toArray(new Throwable[0]);
152
        }
153

    
154
        /**
155
         * Obtiene el Driver asociado al tipo que se le pasa como par?metro
156
         *
157
         * @param name Objeto que devolvi? alguno de los drivers en su m?todo
158
         *                   getType
159
         *
160
         * @return El driver asociado o null si no se encuentra el driver
161
         *
162
         * @throws DriverLoadException if this Class represents an abstract class,
163
         *                    an interface, an array class, a primitive type, or void; or if
164
         *                    the class has no nullary constructor; or if the instantiation
165
         *                    fails for some other reason
166
         */
167
        public Driver getDriver(String name) throws DriverLoadException {
168
                try {
169
                        Class driverClass = (Class) nombreDriverClass.get(name);
170
                        if (driverClass == null) throw new DriverLoadException("No se encontr? el driver: " + name);
171
                        return (Driver) driverClass.newInstance();
172
                } catch (InstantiationException e) {
173
                        throw new DriverLoadException();
174
                } catch (IllegalAccessException e) {
175
                        throw new DriverLoadException();
176
                }
177
        }
178

    
179
        /**
180
         * Establece el objeto validador de los drivers. En la carga se comprobar?
181
         * si cada driver es v?lido mediante el m?todo validate del objeto
182
         * validation establecido con este m?todo. Pro defecto se validan todos
183
         * los drivers
184
         *
185
         * @param validation objeto validador
186
         */
187
        public void setValidation(DriverValidation validation) {
188
                this.validation = validation;
189
        }
190

    
191
        /**
192
         * Obtiene los tipos de todos los drivers del sistema
193
         *
194
         * @return DOCUMENT ME!
195
         */
196
        public String[] getDriverNames() {
197
                ArrayList names = new ArrayList(nombreDriverClass.size());
198

    
199
                Iterator iterator = nombreDriverClass.keySet().iterator();
200

    
201
                while (iterator.hasNext()) {
202
                        names.add((String) iterator.next());
203
                }
204

    
205
                return (String[]) names.toArray(new String[0]);
206
        }
207

    
208
        /**
209
         * Obtiene la clase del driver relacionado con el tipo que se pasa como
210
         * par?metro
211
         *
212
         * @param driverName DOCUMENT ME!
213
         *
214
         * @return DOCUMENT ME!
215
         */
216
        public Class getDriverClassByName(String driverName) {
217
                return (Class) nombreDriverClass.get(driverName);
218
        }
219

    
220
        /**
221
         * DOCUMENT ME!
222
         *
223
         * @param driverName DOCUMENT ME!
224
         * @param superClass DOCUMENT ME!
225
         *
226
         * @return DOCUMENT ME!
227
         *
228
         * @throws RuntimeException DOCUMENT ME!
229
         */
230
        public boolean isA(String driverName, Class superClass) {
231
                Class driverClass = (Class) nombreDriverClass.get(driverName);
232

    
233
                if (driverClass == null) {
234
                        throw new RuntimeException("No such driver");
235
                }
236

    
237
                Class[] interfaces = driverClass.getInterfaces();
238

    
239
                if (interfaces != null) {
240
                        for (int i = 0; i < interfaces.length; i++) {
241
                                if (interfaces[i] == superClass) {
242
                                        return true;
243
                                } else {
244
                                        if (recursiveIsA(interfaces[i], superClass)) {
245
                                                return true;
246
                                        }
247
                                }
248
                        }
249
                }
250

    
251
                Class class_ = driverClass.getSuperclass();
252

    
253
                if (class_ != null) {
254
                        if (class_ == superClass) {
255
                                return true;
256
                        } else {
257
                                if (recursiveIsA(class_, superClass)) {
258
                                        return true;
259
                                }
260
                        }
261
                }
262

    
263
                return false;
264
        }
265

    
266
        /**
267
         * DOCUMENT ME!
268
         *
269
         * @param interface_ DOCUMENT ME!
270
         * @param superInterface DOCUMENT ME!
271
         *
272
         * @return DOCUMENT ME!
273
         */
274
        private boolean recursiveIsA(Class interface_, Class superInterface) {
275
                Class[] interfaces = interface_.getInterfaces();
276

    
277
                if (interfaces != null) {
278
                        for (int i = 0; i < interfaces.length; i++) {
279
                                if (interfaces[i] == superInterface) {
280
                                        return true;
281
                                } else {
282
                                        if (recursiveIsA(interfaces[i], superInterface)) {
283
                                                return true;
284
                                        }
285
                                }
286
                        }
287
                }
288

    
289
                Class class_ = interface_.getSuperclass();
290

    
291
                if (class_ != null) {
292
                        if (class_ == superInterface) {
293
                                return true;
294
                        } else {
295
                                if (recursiveIsA(class_, superInterface)) {
296
                                        return true;
297
                                }
298
                        }
299
                }
300

    
301
                return false;
302
        }
303
        public ArrayList getDriverClassLoaders() {
304
                return driversClassLoaders;
305
        }
306
}