Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1006 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / LayerFactory.java @ 12458

History | View | Annotate | Download (27.4 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.layers;
42

    
43
import java.io.File;
44
import java.io.IOException;
45
import java.sql.SQLException;
46
import java.sql.Types;
47
import java.util.Hashtable;
48
import java.util.TreeMap;
49

    
50
import org.apache.log4j.Logger;
51
import org.cresques.cts.IProjection;
52
import org.cresques.io.data.RasterBuf;
53
import org.cresques.px.Extent;
54
import org.geotools.geometry.coordinatesequence.InPlaceCoordinateSequenceTransformer;
55

    
56
import com.hardcode.driverManager.Driver;
57
import com.hardcode.driverManager.DriverLoadException;
58
import com.hardcode.driverManager.DriverManager;
59
import com.hardcode.driverManager.IDelayedDriver;
60
import com.hardcode.driverManager.WriterManager;
61
import com.hardcode.gdbms.engine.customQuery.QueryManager;
62
import com.hardcode.gdbms.engine.data.DataSource;
63
import com.hardcode.gdbms.engine.data.DataSourceFactory;
64
import com.hardcode.gdbms.engine.data.NoSuchTableException;
65
import com.hardcode.gdbms.engine.data.edition.DataWare;
66
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
67
import com.hardcode.gdbms.engine.values.Value;
68
import com.hardcode.gdbms.engine.values.ValueFactory;
69
import com.iver.cit.gvsig.fmap.DBDriverExceptionType;
70
import com.iver.cit.gvsig.fmap.DriverException;
71
import com.iver.cit.gvsig.fmap.DriverIOExceptionType;
72
import com.iver.cit.gvsig.fmap.DriverNotLoadedExceptionType;
73
import com.iver.cit.gvsig.fmap.GenericDriverExceptionType;
74
import com.iver.cit.gvsig.fmap.LegendDriverExceptionType;
75
import com.iver.cit.gvsig.fmap.ProgressListener;
76
import com.iver.cit.gvsig.fmap.ViewPort;
77
import com.iver.cit.gvsig.fmap.drivers.ConnectionFactory;
78
import com.iver.cit.gvsig.fmap.drivers.DBException;
79
import com.iver.cit.gvsig.fmap.drivers.DBLayerDefinition;
80
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
81
import com.iver.cit.gvsig.fmap.drivers.IConnection;
82
import com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver;
83
import com.iver.cit.gvsig.fmap.drivers.IVectorialJDBCDriver;
84
import com.iver.cit.gvsig.fmap.drivers.RasterDriver;
85
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
86
import com.iver.cit.gvsig.fmap.drivers.VectorialFileDriver;
87
import com.iver.cit.gvsig.fmap.drivers.WithDefaultLegend;
88
import com.iver.cit.gvsig.fmap.operations.arcview.ArcJoin;
89
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
90
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
91
import com.iver.utiles.ExceptionDescription;
92
import com.sun.media.jai.codec.SeekableOutputStream;
93

    
94
/**
95
 * Crea un adaptador del driver que se le pasa como par?metro en los m?todos
96
 * createLayer. Si hay memoria suficiente se crea un FLyrMemory que pasa todas
97
 * las features del driver a memoria
98
 */
99
public class LayerFactory {
100
        private static Logger logger = Logger.getLogger(LayerFactory.class
101
                        .getName());
102

    
103
        private static String driversPath = "../FMap 03/drivers";
104

    
105
        private static String writersPath = "../FMap 03/drivers";
106

    
107
        private static DriverManager driverManager;
108

    
109
        private static WriterManager writerManager;
110

    
111
        private static DataSourceFactory dataSourceFactory;
112

    
113
        /**
114
         * This Hashtable allows to register an alternative LayerClass for
115
         * an specific LayerClass than is attempting to create this factory
116
         */
117
        private static Hashtable layerClassMapping = new Hashtable();
118

    
119
        /**
120
         * Map en el que se guarda para cada fuente de datos a?adida al sistema, el
121
         * adaptador que la maneja. Ha de ser un TreeMap ya que esta clase define la
122
         * igualdad entre las claves a traves del m?todo equals de las mismas. Los
123
         * objetos FileSource, DBSource y WFSSource tienen definido el m?todo equals
124
         * de forma que devuelven true cuando dos objetos apuntan a la misma fuente
125
         * de datos
126
         */
127
        private static TreeMap sourceAdapter;
128

    
129
        /*
130
         * Crea un RandomVectorialFile con el driver que se le pasa como par?metro y
131
         * guard?ndose el nombre del fichero para realizar los accesos, la capa
132
         * tendr? asociada la proyecci?n que se pasa como parametro tambi?n
133
         *
134
         * @param layerName Nombre de la capa. @param driverName Nombre del driver.
135
         * @param f fichero. @param proj Proyecci?n.
136
         *
137
         * @return FLayer. @throws DriverException
138
         *
139
         * @throws DriverException @throws DriverIOException
140
         */
141
        public static FLayer createLayer(String layerName, String driverName,
142
                        File f, IProjection proj) throws DriverException {
143
                // Se obtiene el driver que lee
144
                DriverManager dm = getDM();
145

    
146
                try {
147
                        Driver d = dm.getDriver(driverName);
148

    
149
                        if (d instanceof VectorialFileDriver) {
150
                                return createLayer(layerName, (VectorialFileDriver) d, f, proj);
151
                        } else if (d instanceof RasterDriver) {
152
                                return createLayer(layerName, (RasterDriver) d, f, proj);
153
                        }
154
                } catch (DriverLoadException e) {
155
                        //hay un poco de lio sobre que excepciones se dejan subir
156
                        //arriba y que excepciones se quedan en LayerFactory
157
                        //(esto se debe a que queremos intentar recuperar ciertas capas)
158
                        //las excepciones de este metodo se dejan subir todas, puesto
159
                        //que las excepciones de los dos otros metodos createLayer si que
160
                        //se atrapan
161
                        DriverNotLoadedExceptionType exceptionType =
162
                                new DriverNotLoadedExceptionType();
163
                        exceptionType.setDriverName(driverName);
164
                        DriverException exception =
165
                                new DriverException(e, exceptionType);
166
                        throw exception;
167
                }
168

    
169
                return null;
170
        }
171

    
172
        /**
173
         * It creates a FLayer (FLyrVect) which reads its data from a file driver,
174
         * projected in the specified projection.
175
         *
176
         * @param layerName
177
         *            name of the layer
178
         * @param d
179
         *            vectorial file driver to read layer's data
180
         * @param f
181
         *            file associated to the driver
182
         * @param proj
183
         *            layer projection
184
         *
185
         * @return FLayer new vectorial layer
186
         *
187
         * @throws DriverException
188
         */
189
        public static FLayer createLayer(String layerName, VectorialFileDriver d,
190
                        File f, IProjection proj)
191

    
192
        /*throws DriverException*/ {
193

    
194
                // TODO Comprobar si hay un adaptador ya
195
                VectorialFileAdapter adapter = new VectorialFileAdapter(f);
196
                adapter.setDriver((VectorialDriver) d);
197

    
198
                FLyrVect capa = new FLyrVect();
199
                capa.setName(layerName);
200

    
201
                // TODO Meter esto dentro de la comprobaci?n de si hay memoria
202
                if (false) {
203
                } else {
204
                        capa.setSource(adapter);
205
                        capa.setProjection(proj);
206
                }
207

    
208
                try {
209
                        // Le asignamos tambi?n una legenda por defecto acorde con
210
                        // el tipo de shape que tenga. Tampoco s? si es aqu? el
211
                        // sitio adecuado, pero en fin....
212
                        if (d instanceof WithDefaultLegend) {
213
                                WithDefaultLegend aux = (WithDefaultLegend) d;
214
                                adapter.start();
215
                                capa.setLegend((VectorialLegend) aux.getDefaultLegend());
216
                                adapter.stop();
217
                        } else {
218
                                capa.setLegend(LegendFactory.createSingleSymbolLegend(capa
219
                                                .getShapeType()));
220
                        }
221

    
222
                } catch (FieldNotFoundException e) {
223
                        //this exception is caused in legend creation
224
                        LegendDriverExceptionType excepType =
225
                                new LegendDriverExceptionType("Error al construir la leyenda");
226
                        //TODO Para hacer esto extensible tiene que usarse puntos
227
                        //de extension, y comparar las clases de leyendas registradas
228
                        VectorialLegend legend = (VectorialLegend)
229
                                ((WithDefaultLegend)d).getDefaultLegend();
230

    
231
                        excepType.setLegendLabelField(legend.getLabelField());
232
                        excepType.setLegendHeightField(legend.getLabelHeightField());
233
                        excepType.setLegendRotationField(legend.getLabelRotationField());
234
                        DriverException exception = new DriverException(e, excepType);
235
                        capa.setAvailable(false);
236
                        capa.addError(exception);
237

    
238
                } catch (DriverIOException e) {
239
                        //this error is caused for file IO problems
240
                        DriverIOExceptionType excepType =
241
                                new DriverIOExceptionType();
242
                        excepType.setFile(f);
243
                        DriverException exception = new DriverException(e, excepType);
244
                        capa.setAvailable(false);
245
                        capa.addError(exception);
246
                }
247

    
248
                /*
249
                 * catch(DriverException e){
250
                 * ESTO HAY QUE CAPTURARLO,DE FORMA QUE CREATELAYER NO LANCE NINGUNA
251
                 * EXCEPCION (A NO SER QUE SEA IRRECUPERABLE)
252
                 * }
253
                 */
254
                catch(Exception e){
255
                        e.printStackTrace();
256
                        GenericDriverExceptionType type = new GenericDriverExceptionType();
257
                        DriverException exception = new DriverException(e, type);
258
                        capa.setAvailable(false);
259
                        capa.addError(exception);
260
                }
261
                return capa;
262
        }
263

    
264
        /**
265
         * Creates a new vectorial layer from a generic layer (by generic whe mean
266
         * that we dont know a priory its origin: file, memory, jdbc database, etc.
267
         *
268
         * @param layerName
269
         * @param d
270
         * @param proj
271
         * @return
272
         * @throws DriverException
273
         */
274
        public static FLayer createLayer(String layerName, VectorialDriver d,
275
                        IProjection proj)
276
        /*
277
        throws DriverException
278
        */{
279
                VectorialAdapter adapter = null;
280
                if (d instanceof VectorialFileDriver) {
281
                        adapter = new VectorialFileAdapter(((VectorialFileDriver) d)
282
                                        .getFile());
283
                } else if (d instanceof IVectorialJDBCDriver) {
284
                        adapter = new VectorialDBAdapter();
285
                } else {
286
                        adapter = new VectorialDefaultAdapter();
287
                }
288
                adapter.setDriver((VectorialDriver) d);
289

    
290
                FLyrVect capa = new FLyrVect();
291
                capa.setName(layerName);
292

    
293
                capa.setSource(adapter);
294
                capa.setProjection(proj);
295

    
296
                try {
297

    
298
                        // Le asignamos tambi?n una legenda por defecto acorde con
299
                        // el tipo de shape que tenga. Tampoco s? si es aqu? el
300
                        // sitio adecuado, pero en fin....
301
                        if (d instanceof WithDefaultLegend) {
302
                                WithDefaultLegend aux = (WithDefaultLegend) d;
303
                                adapter.start();
304
                                capa.setLegend((VectorialLegend) aux.getDefaultLegend());
305
                                adapter.stop();
306
                        } else {
307
                                capa.setLegend(LegendFactory.createSingleSymbolLegend(capa
308
                                                .getShapeType()));
309
                        }
310
                } catch (FieldNotFoundException e) {
311
//                        this exception is caused in legend creation
312
                        LegendDriverExceptionType excepType =
313
                                new LegendDriverExceptionType("error al construir la leyenda, campo no encontrado");
314

    
315
                        //TODO Para hacer esto extensible tiene que usarse puntos
316
                        //de extension, y comparar las clases de leyendas registradas
317
                        VectorialLegend legend = (VectorialLegend)
318
                                ((WithDefaultLegend)d).getDefaultLegend();
319
                        excepType.setDriverName(d.getName());
320
                        excepType.setLegendLabelField(legend.getLabelField());
321
                        excepType.setLegendHeightField(legend.getLabelHeightField());
322
                        excepType.setLegendRotationField(legend.getLabelRotationField());
323

    
324
                        DriverException exception = new DriverException(e, excepType);
325
                        capa.setAvailable(false);
326
                        capa.addError(exception);
327
                } catch (DriverIOException e) {
328
                        //by design, start and stop calls to adapter could
329
                        //cause this exception.
330

    
331
                        //but JDBC implementations catchs all exceptions,
332
                        //and rest of layers (WFSLayer, etc.) dont use LayerFactory
333
                        ExceptionDescription type = null;
334
                        if (d instanceof VectorialFileDriver) {
335
                                File f = ((VectorialFileDriver)adapter).getFile();
336
                                type =
337
                                        new DriverIOExceptionType();
338
                                ((DriverIOExceptionType)type).setFile(f);
339

    
340
                        }else{
341
                                type = new GenericDriverExceptionType();
342
                        }
343
                        DriverException exception = new DriverException(e, type);
344
                        capa.setAvailable(false);
345
                        capa.addError(exception);
346
                }catch(Exception e){
347
                        GenericDriverExceptionType type = new GenericDriverExceptionType();
348
                        DriverException exception = new DriverException(e, type);
349
                        capa.setAvailable(false);
350
                        capa.addError(exception);
351
                }
352

    
353
                return capa;
354
        }
355

    
356
        /**
357
         * Crea una capa Raster a partir del nombre driver, fichero y proyecci?n.
358
         *
359
         * @param layerName
360
         *            Nombre de la capa.
361
         * @param d
362
         *            RasterDriver.
363
         * @param f
364
         *            Fichero.
365
         * @param proj
366
         *            Proyecci?n.
367
         *
368
         * @return Nueva capa de tipo raster.
369
         *
370
         * @throws DriverIOException
371
         */
372
        public static FLyrRaster createLayer(String layerName, RasterDriver d,
373
                        File f, IProjection proj) throws DriverException {
374
                RasterAdapter adapter = new RasterFileAdapter(f);
375
                adapter.setDriver(d);
376

    
377
                Class layerClass;
378
                try {
379
                        layerClass = getLayerClassForLayerClassName(FLyrRaster.class.getName());
380
                } catch (ClassNotFoundException e1) {
381
                        e1.printStackTrace();
382
                        throw new DriverException(e1);
383
                }
384

    
385
                FLyrRaster capa;
386
                try {
387
                        capa = (FLyrRaster)layerClass.newInstance();
388
                } catch (InstantiationException e1) {
389
                        e1.printStackTrace();
390
                        throw new DriverException(e1);
391
                } catch (IllegalAccessException e1) {
392
                        e1.printStackTrace();
393
                        throw new DriverException(e1);
394
                }
395

    
396
                capa.setName(layerName);
397

    
398
                // TODO Meter esto dentro de la comprobaci?n de si hay memoria
399
                if (false) {
400
                } else {
401
                        capa.setSource(adapter);
402
                        capa.setProjection(proj);
403
                        try {
404
                                capa.load();
405
                        } catch (DriverIOException e) {
406
                                throw new DriverException(e);
407
                        }
408
                }
409

    
410
                return capa;
411
        }
412

    
413
        /**
414
         * Crea una capa Raster a partir del nombre driver, fichero y proyecci?n y
415
         * coordenadas de georeferenciaci?n. Esta funci?n es para georeferenciar
416
         * capas raster. Para imagenes que no tienen georeferenciaci?n hay que
417
         * asignarle una temporal, normalmente a partir de la vista activa.
418
         *
419
         * @param layerName
420
         *            Nombre de la capa.
421
         * @param d
422
         *            RasterDriver.
423
         * @param f
424
         *            Fichero.
425
         * @param proj
426
         *            Proyecci?n.
427
         * @param extent
428
         *            Extent de la vista activa
429
         *
430
         * @return Nueva capa de tipo raster.
431
         *
432
         * @throws DriverIOException
433
         */
434
        public static FLyrRaster createLayer(String layerName, RasterDriver d,
435
                        File f, IProjection proj, ViewPort vp) throws DriverException {
436
                RasterAdapter adapter = new RasterFileAdapter(f);
437
                adapter.setDriver(d);
438

    
439
                Class layerClass;
440
                try {
441
                        layerClass = getLayerClassForLayerClassName(FLyrRaster.class.getName());
442
                } catch (ClassNotFoundException e1) {
443
                        e1.printStackTrace();
444
                        throw new DriverException(e1);
445
                }
446

    
447
                FLyrRaster capa;
448
                try {
449
                        capa = (FLyrRaster)layerClass.newInstance();
450
                } catch (InstantiationException e1) {
451
                        e1.printStackTrace();
452
                        throw new DriverException(e1);
453
                } catch (IllegalAccessException e1) {
454
                        e1.printStackTrace();
455
                        throw new DriverException(e1);
456
                }
457

    
458
                capa.setName(layerName);
459

    
460
                // TODO Meter esto dentro de la comprobaci?n de si hay memoria
461
                if (false) {
462
                } else {
463
                        capa.setSource(adapter);
464
                        capa.setProjection(proj);
465
                        // capa.setTempExtent(vp);
466
                        try {
467
                                capa.load();
468
                        } catch (DriverIOException e) {
469
                                throw new DriverException(e);
470
                        }
471
                }
472

    
473
                return capa;
474
        }
475

    
476

    
477
        /**
478
         * Creates a new raster layer in memory. To create this layer type we have to set a data
479
         * buffer and a bounding box instead of a file. Don't use without CMS raster library that
480
         * include MemoryRasterDriver implementation.
481
         * @param layerName Layer name
482
         * @param d raster driver
483
         * @param buf data buffer
484
         * @param ext bounding box
485
         * @param proj projection
486
         * @return raster layer
487
         * @throws DriverException
488
         */
489
        public static FLyrRaster createLayer(String layerName, RasterDriver d,
490
                        RasterBuf buf, Extent ext, IProjection proj) throws DriverException {
491
                RasterAdapter adapter = new RasterFileAdapter(null);
492
                adapter.setDriver(d);
493

    
494

    
495
                Class layerClass;
496
                try {
497
                        layerClass = getLayerClassForLayerClassName(FLyrRaster.class.getName());
498
                } catch (ClassNotFoundException e1) {
499
                        e1.printStackTrace();
500
                        throw new DriverException(e1);
501
                }
502

    
503
                FLyrRaster capa;
504
                try {
505
                        capa = (FLyrRaster)layerClass.newInstance();
506
                } catch (InstantiationException e1) {
507
                        e1.printStackTrace();
508
                        throw new DriverException(e1);
509
                } catch (IllegalAccessException e1) {
510
                        e1.printStackTrace();
511
                        throw new DriverException(e1);
512
                }
513
                capa.setName(layerName);
514

    
515
                // TODO Meter esto dentro de la comprobaci?n de si hay memoria
516
                if (false) {
517
                } else {
518
                        capa.setSource(adapter);
519
                        capa.setProjection(proj);
520
                        capa.setBuffer(buf);
521
                        capa.setExtent(ext);
522
                        try {
523
                                capa.load();
524
                        } catch (DriverIOException e) {
525
                                throw new DriverException(e);
526
                        }
527
                }
528

    
529
                return capa;
530
        }
531

    
532
        /**
533
         * Crea un RandomVectorialWFS con el driver que se le pasa como par?metro y
534
         * guard?ndose la URL del servidor que se pasa como par?metro
535
         *
536
         * @param driver
537
         * @param host
538
         * @param port
539
         * @param user
540
         * @param password
541
         * @param dbName
542
         * @param tableName
543
         * @param proj
544
         *
545
         * @return Capa creada.
546
         *
547
         * @throws UnsupportedOperationException
548
         */
549
        public static FLayer createLayer(IVectorialDatabaseDriver driver,
550
                        String host, int port, String user, String password, String dbName,
551
                        String tableName, IProjection proj) {
552
                throw new UnsupportedOperationException();
553
        }
554

    
555
        public static FLayer createDBLayer(IVectorialDatabaseDriver driver,
556
                        String layerName, IProjection proj) {
557

    
558
                FLyrVect capa = new FLyrVect();
559

    
560
                capa.setName(layerName);
561
                VectorialDBAdapter dbAdapter = new VectorialDBAdapter();
562
                dbAdapter.setDriver(driver);
563

    
564
                capa.setSource(dbAdapter);
565
                capa.setProjection(proj);
566
                try {
567
                        if (driver instanceof WithDefaultLegend) {
568
                                WithDefaultLegend aux = (WithDefaultLegend) driver;
569
                                dbAdapter.start();
570
                                capa.setLegend((VectorialLegend) aux.getDefaultLegend());
571
                                dbAdapter.stop();
572
                        } else {
573
                                capa.setLegend(LegendFactory.createSingleSymbolLegend(capa
574
                                                .getShapeType()));
575
                        }
576
                        if (driver instanceof IDelayedDriver)
577
                        {
578
                                // Por defecto, los drivers est?n listos para entregar
579
                                // features al terminar su initialize. Pero con los drivers
580
                                // que implementan IDelayedDriver, el driver es responsable
581
                                // de avisar cu?ndo est? listo
582
                                capa.getFLayerStatus().setDriverLoaded(false);
583
                                ((IDelayedDriver) driver).addDriverEventListener(new DefaultDelayedDriverListener(capa));
584
                        }
585
                        // PARCHE: Llamamos a getXmlEntity del driver para que se rellenen
586
                        // los valores de host, port, etc, necesarios para un posible reload
587
                        //FIXME: Se vuelve a dejar como estaba... el problema esta en el DefaultDBDriver.getXMLEntiy()
588
                        //       y comentarizemos esto o no, si no arreglamos ese metodo da problemas de persistencia
589
                        driver.setXMLEntity(driver.getXMLEntity());
590

    
591
                } catch (FieldNotFoundException e) {
592
                        LegendDriverExceptionType excepType =
593
                                new LegendDriverExceptionType("Error al construir la leyenda, campo no encontrado");
594
                        //TODO Para hacer esto extensible tiene que usarse puntos
595
                        //de extension, y comparar las clases de leyendas registradas
596
                        VectorialLegend legend = (VectorialLegend)
597
                                ((WithDefaultLegend)driver).getDefaultLegend();
598

    
599
                        excepType.setLegendLabelField(legend.getLabelField());
600
                        excepType.setLegendHeightField(legend.getLabelHeightField());
601
                        excepType.setLegendRotationField(legend.getLabelRotationField());
602
                        DriverException exception = new DriverException(e, excepType);
603
                        capa.setAvailable(false);
604
                        capa.addError(exception);
605
                        return capa;
606
                        // throw new UnsupportedOperationException(e.getMessage());
607
                } catch (DriverException e) {
608
                        DBDriverExceptionType excepType =
609
                                new DBDriverExceptionType();
610
                        excepType.setDriverName(driver.getName());
611
                        excepType.setTableName(driver.getTableName());
612
                        DriverException exception = new DriverException(e, excepType);
613
                        capa.addError(exception);
614
                        capa.setAvailable(false);
615
                        return capa;
616
                        // throw new UnsupportedOperationException(e.getMessage());
617
                } catch (Exception e) {
618
                        ExceptionDescription excepType = new GenericDriverExceptionType();
619
                        DriverException exception = new DriverException(e, excepType);
620
                        capa.addError(exception);
621
                        capa.setAvailable(false);
622
                        return capa;
623
                }
624

    
625
                return capa;
626

    
627
        }
628

    
629
        /**
630
         * @param driver
631
         * @param layerName
632
         * @param object
633
         * @return
634
         * @throws SQLException
635
         * @throws DriverIOException
636
         * @throws IOException
637
         * @throws DriverLoadException
638
         * @throws com.hardcode.gdbms.engine.data.driver.DriverException
639
         * @throws NoSuchTableException
640
         * @throws ClassNotFoundException
641
         * @throws
642
         */
643
        public static FLayer createDisconnectedDBLayer(IVectorialDatabaseDriver driver,
644
                        String layerName, IProjection proj, ProgressListener listener)
645
                        throws DBException, IOException, DriverIOException,
646
                        DriverLoadException, NoSuchTableException,
647
                        com.hardcode.gdbms.engine.data.driver.DriverException,
648
                        ClassNotFoundException {
649
                VectorialDisconnectedDBAdapter dbAdapter = new VectorialDisconnectedDBAdapter();
650
                dbAdapter.setDriver(driver);
651
                DataSource ds = dbAdapter.getRecordset();
652
                ds.start();
653
                String database = dataSourceFactory.getTempFile();
654
                String[] fieldNames = new String[ds.getFieldCount() + 1];
655
                System.arraycopy(ds.getFieldNames(), 0, fieldNames, 1, ds
656
                                .getFieldCount());
657
                fieldNames[0] = "the_geom";
658
                int[] types = new int[fieldNames.length];
659
                types[0] = Types.BINARY;
660
                for (int i = 1; i < types.length; i++) {
661
                        types[i] = ds.getFieldType(i - 1);
662
                }
663
                String dsName=null;
664
                try {
665
                        dsName = dataSourceFactory.createTable(database,
666
                                        ds.getPKNames(), fieldNames, types);
667
                } catch (SQLException e) {
668
                        throw new DBException(e);
669
                }
670

    
671
                DBLayerDefinition lyrDef = new DBLayerDefinition();
672
                lyrDef.setTableName(dsName);
673
                lyrDef.setName(layerName);
674
                lyrDef.setFieldNames(ds.getFieldNames());
675
                lyrDef.setFieldGeometry("the_geom");
676
                lyrDef.setFieldID(ds.getPKNames()[0]);
677
                lyrDef.setClassToInstantiate("org.hsqldb.jdbcDriver");
678

    
679
                dataSourceFactory.addDBDataSourceByTable(dsName, null, 0, "sa", "",
680
                                database, dsName, "GDBMS HSQLDB Transactional driver");
681
                DataSource local = dataSourceFactory.createRandomDataSource(dsName,
682
                                DataSourceFactory.MANUAL_OPENING);
683
                local.start();
684
                DataWare dw = local
685
                                .getDataWare(DataSourceFactory.DATA_WARE_COHERENT_ROW_ORDER);
686
                dw.start();
687
                long t1 = System.currentTimeMillis();
688
                dw.beginTrans();
689

    
690
                if (listener == null) {
691
                        listener = new ProgressListener() {
692
                                /**
693
                                 * @see com.iver.cit.gvsig.fmap.ProgressListener#progress(int)
694
                                 */
695
                                public void progress(int n) {
696
                                        // do nothing
697
                                }
698
                        };
699
                }
700

    
701
                for (int i = 0; i < dbAdapter.getShapeCount(); i++) {
702
                        Value[] row = new Value[ds.getFieldCount() + 1];
703

    
704
                        byte[] bytes = dbAdapter.getShape(i).toWKB();
705
                        row[0] = ValueFactory.createValue(bytes);
706

    
707
                        for (int j = 0; j < ds.getFieldCount(); j++) {
708
                                row[j + 1] = ds.getFieldValue(i, j);
709
                        }
710

    
711
                        dw.insertFilledRow(row);
712
                        listener.progress(100 * i / dbAdapter.getShapeCount());
713
                }
714

    
715
                long t2 = System.currentTimeMillis();
716
                dw.commitTrans();
717
                long t3 = System.currentTimeMillis();
718
                System.out.println((t2 - t1) + " - " + (t3 - t2));
719
                dw.stop();
720
                local.stop();
721
                ds.stop();
722
                IVectorialJDBCDriver cacheDriver = (IVectorialJDBCDriver) LayerFactory
723
                                .getDM().getDriver("HSQLDB Driver");
724
                Class.forName("org.hsqldb.jdbcDriver");
725
                IConnection conn=ConnectionFactory.createConnection("jdbc:hsqldb:file:" + database, "sa", "");
726
                cacheDriver.setData(conn, lyrDef);
727
                cacheDriver.setWorkingArea(driver.getWorkingArea());
728
                return createDBLayer(cacheDriver, layerName, proj);
729
        }
730

    
731
        /**
732
         * Crea una FLyrComplexRaster que ataca al driver que se pasa como
733
         * par?metro.
734
         *
735
         * @param driver
736
         * @param f
737
         * @param proj
738
         *
739
         * @throws IllegalArgumentException
740
         *             Si se pasa un driver que no implementa
741
         *             GeorreferencedRasterDriver o NotGeorreferencedRasterDriver
742
         */
743
        public static void createLayer(RasterDriver driver, File f, IProjection proj)
744
                        throws IllegalArgumentException {
745
        }
746

    
747
        /**
748
         * Devuelve el DriverManager.
749
         *
750
         * @return DriverManager.
751
         */
752
        public static DriverManager getDM() {
753
                initializeDriverManager();
754

    
755
                return driverManager;
756
        }
757

    
758
        /**
759
         * Devuelve el WriterManager.
760
         *
761
         * @return WriterManager.
762
         */
763
        public static WriterManager getWM() {
764
                initializeWriterManager();
765

    
766
                return writerManager;
767
        }
768

    
769
        /**
770
         * Inicializa el DriverManager.
771
         */
772
        private static void initializeDriverManager() {
773
                if (driverManager == null) {
774
                        driverManager = new DriverManager();
775
                        driverManager.loadDrivers(new File(LayerFactory.driversPath));
776

    
777
                        Throwable[] failures = driverManager.getLoadFailures();
778

    
779
                        for (int i = 0; i < failures.length; i++) {
780
                                logger.error("", failures[i]);
781
                        }
782

    
783
                        getDataSourceFactory().setDriverManager(driverManager);
784
                        getDataSourceFactory().initialize();
785
                        QueryManager.registerQuery(new ArcJoin());
786
                }
787
        }
788

    
789
        /**
790
         * Inicializa el DriverManager.
791
         */
792
        private static void initializeWriterManager() {
793
                if (writerManager == null) {
794
                        writerManager = new WriterManager();
795
                        writerManager.loadWriters(new File(LayerFactory.writersPath));
796

    
797
                        Throwable[] failures = writerManager.getLoadFailures();
798

    
799
                        for (int i = 0; i < failures.length; i++) {
800
                                logger.error("", failures[i]);
801
                        }
802

    
803
                        getDataSourceFactory().setWriterManager(writerManager);
804
                        getDataSourceFactory().initialize();
805
                        // QueryManager.registerQuery(new ArcJoin());
806
                }
807
        }
808

    
809
        /**
810
         * sets drivers Directory
811
         *
812
         * @param path
813
         */
814
        public static void setDriversPath(String path) {
815
                LayerFactory.driversPath = path;
816
                initializeDriverManager();
817
        }
818

    
819
        /**
820
         * sets writers Directory
821
         *
822
         * @param path
823
         */
824
        public static void setWritersPath(String path) {
825
                LayerFactory.writersPath = path;
826
                initializeWriterManager();
827
        }
828

    
829
        /**
830
         * @return Returns the dataSourceFactory.
831
         */
832
        public static DataSourceFactory getDataSourceFactory() {
833
                if (dataSourceFactory == null) {
834
                        dataSourceFactory = new DataSourceFactory();
835
                }
836
                return dataSourceFactory;
837
        }
838

    
839

    
840
        /**
841
         * Set a class to use instead of the originalLayerClassName.
842
         *
843
         * @param originalLayerClassName name of class to relpace
844
         * @param layerClassToUse Class than implements FLayer interface to use
845
         *
846
         * @see  getLayerClassForLayerClassName(String,Class)
847
         * @see  unregisterLayerClassForName(String)
848
        */
849
        public static void registerLayerClassForName (String originalLayerClassName, Class layerClassToUse){
850
                boolean isFLayer = false;
851
                Class[] interfaces = layerClassToUse.getInterfaces();
852
                for (int i = 0;i < interfaces.length; i++){
853
                        if (interfaces[i] == FLayer.class){
854
                                isFLayer = true;
855
                                break;
856
                        }
857
                }
858
                if (!isFLayer){
859
                        throw new ClassCastException("The class "+ layerClassToUse.getName() + "must implements FLayer");
860
                }
861

    
862
                layerClassMapping.put(originalLayerClassName,layerClassToUse);
863
        }
864

    
865
        /**
866
         * Unregister the originalLayerClassName class replacement.
867
         *
868
         * @param originalLayerClassName name of class to relpace
869
         * @param layerClassToUse Class than implements FLayer interface to use
870
         * @return true if the class had been registered
871
         *
872
         * @see  getLayerClassForLayerClassName(String,Class)
873
         * @see  unregisterLayerClassForName(String)
874
        */
875
        public static boolean unregisterLayerClassForName (String originalLayerClassName){
876
                return layerClassMapping.remove(originalLayerClassName) != null;
877
        }
878

    
879
        /**
880
         * Gets the class to use for the layerClassName.
881
         * If isn't registered an alternative class for this layerClass
882
         * the this returns 'Class.forName(layerClassName)'
883
         *
884
         * @param layerClassName
885
         * @return Class implements FLayer to use
886
         * @throws ClassNotFoundException
887
         *
888
         * @see  registerLayerClassForName(String,Class)
889
         * @see  unregisterLayerClassForName(String)
890
         */
891
        public static Class getLayerClassForLayerClassName(String layerClassName) throws ClassNotFoundException{
892
                Class layerClass = (Class)layerClassMapping.get(layerClassName);
893
                if (layerClass == null){
894
                        layerClass = Class.forName(layerClassName);
895
                }
896
                return layerClass;
897
        }
898
}