Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / VectorialDisconnectedDBAdapter.java @ 3481

History | View | Annotate | Download (9.24 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.awt.geom.Rectangle2D;
44
import java.io.ByteArrayOutputStream;
45
import java.io.File;
46
import java.io.FileOutputStream;
47
import java.io.IOException;
48
import java.io.ObjectOutputStream;
49
import java.nio.ByteBuffer;
50
import java.nio.channels.FileChannel;
51
import java.sql.ResultSet;
52
import java.sql.SQLException;
53
import java.sql.Statement;
54

    
55
import com.hardcode.driverManager.DriverLoadException;
56
import com.hardcode.gdbms.engine.data.DataSource;
57
import com.hardcode.gdbms.engine.data.DataSourceFactory;
58
import com.hardcode.gdbms.engine.data.NoSuchTableException;
59
import com.hardcode.gdbms.engine.data.driver.ObjectDriver;
60
import com.hardcode.gdbms.engine.values.Value;
61
import com.iver.cit.gvsig.fmap.DriverException;
62
import com.iver.cit.gvsig.fmap.core.FShape;
63
import com.iver.cit.gvsig.fmap.core.IGeometry;
64
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
65
import com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver;
66

    
67

    
68

    
69
/**
70
 * Adapta un driver de base de datos vectorial a la interfaz vectorial,
71
 * manteniendo adem?s el estado necesario por una capa vectorial de base de
72
 * datos (par?metros de la conexi?n)
73
 */
74
public class VectorialDisconnectedDBAdapter extends VectorialAdapter {
75
        private static final int REFRESH = 0;
76
        private static final int RECEIVING = 1;
77
        private static final int LOCAL = 2;
78
        
79
    private int numReg=-1;
80
    private DataSource ds = null;
81
    private int status = REFRESH;
82
    private VectorialDBAdapter connectedAdapter;
83
    
84
    private File dataFile;
85
    private File indexFile;
86
    
87
        /**
88
         * incrementa el contador de las veces que se ha abierto el fichero.
89
         * Solamente cuando el contador est? a cero pide al driver que conecte con
90
         * la base de datos
91
         */
92
        public void start() {
93
                switch (status){
94
                        case REFRESH:
95
                                Thread t = new Thread(new Receiver());
96
                                t.run();
97
                                break;
98
                        case RECEIVING:
99
                        case LOCAL:
100
                                
101
                                break;
102
                }
103
                
104
        }
105

    
106
        /**
107
         * decrementa el contador de n?mero de aperturas y cuando llega a cero pide
108
         * al driver que cierre la conexion con el servidor de base de datos
109
         */
110
        public void stop() {
111
            ((VectorialDatabaseDriver)driver).close();
112
        }
113

    
114
        /**
115
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
116
         */
117
        public IGeometry getShape(int index) throws DriverIOException {
118
            try {
119
            return ((VectorialDatabaseDriver)driver).getShape(index);
120
        } catch (IOException e) {
121
            throw new DriverIOException(e);
122
        }
123
        }
124
        
125
        private String getTableName(){
126
            return ((VectorialDatabaseDriver)driver).getTableName();
127
        }
128

    
129
        /**
130
         * @throws DriverException
131
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeCount()
132
         */
133
        public int getShapeCount() throws DriverIOException {
134
                if (status == LOCAL){
135
                        return 10;
136
                }else{
137
                    if (numReg == -1)
138
                    {
139
                try {
140
                    numReg = ((VectorialDatabaseDriver)driver).getShapeCount();
141
                } catch (IOException e) {
142
                    e.printStackTrace();
143
                    throw new DriverIOException(e.getMessage());
144
                }
145
                    }
146
                    
147
            return numReg;
148
                }
149
        }
150

    
151
        /**
152
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
153
         */
154
        public Rectangle2D getFullExtent() {
155
            return ((VectorialDatabaseDriver)driver).getFullExtent();
156
        }
157

    
158

    
159
        /**
160
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
161
         */
162
        public int getShapeType() throws DriverIOException {
163
                return FShape.MULTI;
164
        }
165

    
166
        /**
167
         * @see com.iver.cit.gvsig.fmap.layers.VectorialAdapter#getRecordset()
168
         */
169
        public DataSource getRecordset() throws DriverLoadException {
170
            if (driver instanceof ObjectDriver)
171
            {
172
                        String name = LayerFactory.getDataSourceFactory().addDataSource((ObjectDriver)driver);
173
                        try {
174
                ds = LayerFactory.getDataSourceFactory().createRandomDataSource(name, DataSourceFactory.AUTOMATIC_OPENING);
175
            } catch (NoSuchTableException e) {
176
                throw new RuntimeException(e);
177
                        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
178
                                throw new RuntimeException(e);
179
                        }
180
            }
181
                return ds;
182
        }
183
        
184
        public class Receiver implements Runnable{
185
                private ByteBuffer bb;
186
                private int currentCapacity = 0;
187
                private FileChannel channel;
188
                
189
                private ByteBuffer indexBuffer = ByteBuffer.allocate(4);
190
                private FileChannel indexChannel;
191

    
192
            private Rectangle2D extent = new Rectangle2D.Double();
193

    
194
                public ByteBuffer getBuffer(int capacity){
195
                        if (capacity > currentCapacity){
196
                                bb = ByteBuffer.allocate(capacity);
197
                                currentCapacity = capacity;
198
                        }
199
                        
200
                        return bb;
201
                }
202
                
203
                private void writeObject(byte[] bytes) throws IOException{
204
                        //Se escribe al fichero de datos
205
                        bb = getBuffer(bytes.length + 4);
206
                        bb.clear();
207
                        bb.putInt(bytes.length);
208
                        bb.put(bytes);
209
                        bb.flip();
210
                        channel.write(bb);
211
                        
212
                        //Se actualiza el fichero de ?ndice
213
                        indexBuffer.clear();
214
                        indexBuffer.putInt((int) channel.position());
215
                        indexBuffer.flip();
216
                        indexChannel.write(indexBuffer);
217
                }
218
                
219
                /**
220
                 * @see java.lang.Runnable#run()
221
                 */
222
                public void run() {
223
                        try {
224
                                //Abrimos el fichero de datos
225
                                dataFile = new File("/root/tirar/gvSIGtmp.gvs");
226
                                FileOutputStream fs = new FileOutputStream(dataFile);
227
                                channel = fs.getChannel();
228
                                
229
                                //Abrimos el fichero de indice
230
                                indexFile = new File("/root/tirar/gvSIGindex.gvi");
231
                                FileOutputStream indexfs = new FileOutputStream(indexFile);
232
                                indexChannel = indexfs.getChannel();
233
                        
234
                                //Creamos un adaptador conectado para bajarnos los datos
235
                                VectorialDatabaseDriver d = (VectorialDatabaseDriver) VectorialDisconnectedDBAdapter.this.driver;
236
                                connectedAdapter = new VectorialDBAdapter();
237
                                connectedAdapter.setDriver(d);
238
                                
239
                                //Escribimos el n?mero de campos
240
                                indexBuffer.clear();
241
                                indexBuffer.putInt(connectedAdapter.getRecordset().getFieldCount());
242
                                indexBuffer.flip();
243
                                indexChannel.write(indexBuffer);
244
                                indexChannel.position(indexChannel.position() + 4);
245

    
246
                                //Reservamos espacio para el n?mero de campos
247
                                indexChannel.position(indexChannel.position() + 4 * 8);
248
                                
249
                                connectedAdapter.start();
250
        
251
                                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
252
                                ObjectOutputStream oos = new ObjectOutputStream(bytes);
253
                                int geom = 0;
254
                                for (int i = 0; i < connectedAdapter.getShapeCount(); i++) {
255
                                        geom++;
256
                                        IGeometry g = connectedAdapter.getShape(i);
257
                                        extent.add(g.getBounds2D());
258
                                        
259
                                        //Se obtienen los bytes del objeto a serializar
260
                                        bytes = new ByteArrayOutputStream();
261
                                        oos = new ObjectOutputStream(bytes);
262
                                        oos.writeObject(g);
263
                                        oos.close();
264
                                        
265
                                        //Se escribe al fichero
266
                                        writeObject(bytes.toByteArray());
267
                                        
268
                                        for (int j = 0; j < connectedAdapter.getRecordset().getFieldCount(); j++) {
269
                                                Value v = connectedAdapter.getRecordset().getFieldValue(i, j);
270
                                                
271
                                                //Se obtienen los bytes del objeto a serializar
272
                                                bytes = new ByteArrayOutputStream();
273
                                                oos = new ObjectOutputStream(bytes);
274
                                                oos.writeObject(v);
275
                                                oos.close();
276
                                                
277
                                                //Se escribe al fichero
278
                                                writeObject(bytes.toByteArray());
279
                                        }
280
                                }
281
                                
282
                                //Escribimos el n?mero de geometr?as en el fichero de ?ndice
283
                                indexBuffer.clear();
284
                                indexBuffer.putInt(geom);
285
                                indexBuffer.flip();
286
                                indexChannel.position(4);
287
                                indexChannel.write(indexBuffer);
288
                                indexChannel.position(indexChannel.position() + 4);
289
                                
290
                                //Escribimos el extent
291
                                ByteBuffer extentBuffer = ByteBuffer.allocate(4*8);
292
                                extentBuffer.putDouble(extent.getMinX());
293
                                extentBuffer.putDouble(extent.getMinY());
294
                                extentBuffer.putDouble(extent.getMaxX());
295
                                extentBuffer.putDouble(extent.getMaxY());
296
                                extentBuffer.flip();
297
                                indexChannel.position(8);
298
                                indexChannel.write(extentBuffer);
299
                                
300
                                //Cerramos
301
                                channel.close();
302
                                indexChannel.close();
303
                                
304
                                connectedAdapter.stop();
305
                                
306
                                status = LOCAL;
307
                        } catch (DriverIOException e) {
308
                                throw new RuntimeException(e);
309
                        } catch (IOException e) {
310
                                throw new RuntimeException(e);
311
                        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
312
                                throw new RuntimeException(e);
313
                        } catch (DriverLoadException e) {
314
                                throw new RuntimeException(e);
315
                        }
316
                }
317
                
318
        }
319
}