Statistics
| Revision:

svn-gvsig-desktop / branches / Fmap_GisPlanet / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / VectorialDisconnectedDBAdapter.java @ 1848

History | View | Annotate | Download (9.33 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
                    {
137
                            Statement s = ((VectorialDatabaseDriver)driver).getConnection().createStatement();                    
138
                            ResultSet r = s.executeQuery("SELECT COUNT(*) AS NUMREG FROM " + getTableName());
139
                            r.next();
140
                            numReg = r.getInt(1);
141
                            System.err.println("numReg = " + numReg);
142
                    }
143
                        catch (SQLException e)
144
                        {
145
                            throw new DriverIOException(e);
146
                        }
147
                    }
148
                    
149
            return numReg;
150
                }
151
        }
152

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

    
160

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

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

    
194
            private Rectangle2D extent = new Rectangle2D.Double();
195

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

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