Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1014 / libraries / libDriverManager / src / com / hardcode / driverManager / WriterManager.java @ 13593

History | View | Annotate | Download (7.29 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 writer manager, el writer viene determinado por un directorio dentro
16
 * del cual se encuentran uno o m?s jar's. La clase Writer ha de implementar
17
 * la interfaz Writer y su nombre debe terminar en "Writer" 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 writers y de la
22
 * obtenci?n de los mismo apartir de un tipo
23
 * </p>
24
 *
25
 * @author Vicente Caballero Navarro
26
 */
27
public class WriterManager {
28
        private DriverValidation validation;
29
        private HashMap nombreWriterClass = new HashMap();
30
        private ArrayList failures = new ArrayList();
31

    
32
        /**
33
         * Devuelve un array con los directorios de los plugins
34
         *
35
         * @param dirExt Directorio a partir del que se cuelgan los directorios de
36
         *                   los drivers
37
         *
38
         * @return Array de los subdirectorios
39
         */
40
        private File[] getPluginDirs(File dirExt) {
41
                if (!dirExt.exists()) {
42
                        return new File[0];
43
                }
44

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

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

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

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

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

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

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

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

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

    
103
                                //Se crea el classloader
104
                                DriverClassLoader cl = new DriverClassLoader(jars,
105
                                                dirs[i].getAbsolutePath(),
106
                                                this.getClass().getClassLoader());
107

    
108
                                //Se obtienen los drivers
109
                                Class[] writers = cl.getWriters();
110

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

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

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

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

    
189
        /**
190
         * Obtiene los tipos de todos los writers del sistema
191
         *
192
         * @return DOCUMENT ME!
193
         */
194
        public String[] getWriterNames() {
195
                ArrayList names = new ArrayList(nombreWriterClass.size());
196

    
197
                Iterator iterator = nombreWriterClass.keySet().iterator();
198

    
199
                while (iterator.hasNext()) {
200
                        names.add((String) iterator.next());
201
                }
202

    
203
                return (String[]) names.toArray(new String[0]);
204
        }
205

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

    
218
        /**
219
         * DOCUMENT ME!
220
         *
221
         * @param writerName DOCUMENT ME!
222
         * @param superClass DOCUMENT ME!
223
         *
224
         * @return DOCUMENT ME!
225
         *
226
         * @throws RuntimeException DOCUMENT ME!
227
         */
228
        public boolean isA(String writerName, Class superClass) {
229
                Class writerClass = (Class) nombreWriterClass.get(writerName);
230

    
231
                if (writerClass == null) {
232
                        throw new RuntimeException("No such driver");
233
                }
234

    
235
                Class[] interfaces = writerClass.getInterfaces();
236

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

    
249
                Class class_ = writerClass.getSuperclass();
250

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

    
261
                return false;
262
        }
263

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

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

    
287
                Class class_ = interface_.getSuperclass();
288

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

    
299
                return false;
300
        }
301
}