Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / VectorialDisconnectedDBAdapter.java @ 2183

History | View | Annotate | Download (9.14 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
            return ((VectorialDatabaseDriver)driver).getShape(index);
119
        }
120
        
121
        private String getTableName(){
122
            return ((VectorialDatabaseDriver)driver).getTableName();
123
        }
124

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

    
147
        /**
148
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getFullExtent()
149
         */
150
        public Rectangle2D getFullExtent() {
151
            return ((VectorialDatabaseDriver)driver).getFullExtent();
152
        }
153

    
154

    
155
        /**
156
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
157
         */
158
        public int getShapeType() throws DriverIOException {
159
                return FShape.MULTI;
160
        }
161

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

    
188
            private Rectangle2D extent = new Rectangle2D.Double();
189

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

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