Statistics
| Revision:

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

History | View | Annotate | Download (8.07 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

    
52
import com.hardcode.driverManager.DriverLoadException;
53
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
54
import com.hardcode.gdbms.engine.data.DataSourceFactory;
55
import com.hardcode.gdbms.engine.data.NoSuchTableException;
56
import com.hardcode.gdbms.engine.data.driver.ObjectDriver;
57
import com.hardcode.gdbms.engine.values.Value;
58
import com.iver.cit.gvsig.fmap.core.FShape;
59
import com.iver.cit.gvsig.fmap.core.IGeometry;
60
import com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver;
61

    
62

    
63

    
64
/**
65
 * Adapta un driver de base de datos vectorial a la interfaz vectorial,
66
 * manteniendo adem?s el estado necesario por una capa vectorial de base de
67
 * datos (par?metros de la conexi?n)
68
 */
69
public class VectorialDisconnectedDBAdapter extends VectorialAdapter {
70
        private static final int REFRESH = 0;
71
        private static final int RECEIVING = 1;
72
        private static final int LOCAL = 2;
73

    
74
    private int numReg=-1;
75
    private SelectableDataSource ds = null;
76
    private int status = REFRESH;
77
    private VectorialDBAdapter connectedAdapter;
78

    
79
    private File dataFile;
80
    private File indexFile;
81

    
82
        /**
83
         * incrementa el contador de las veces que se ha abierto el fichero.
84
         * Solamente cuando el contador est? a cero pide al driver que conecte con
85
         * la base de datos
86
         */
87
        public void start() throws ReadDriverException {
88
                switch (status){
89
                        case REFRESH:
90
                                Thread t = new Thread(new Receiver());
91
                                t.run();
92
                                break;
93
                        case RECEIVING:
94
                        case LOCAL:
95

    
96
                                break;
97
                }
98

    
99
        }
100

    
101
        /**
102
         * decrementa el contador de n?mero de aperturas y cuando llega a cero pide
103
         * al driver que cierre la conexion con el servidor de base de datos
104
         */
105
        public void stop() throws ReadDriverException {
106
            ((VectorialDatabaseDriver)driver).close();
107
        }
108

    
109
        /**
110
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShape(int)
111
         */
112
        public IGeometry getShape(int index) throws ReadDriverException {
113
            return ((VectorialDatabaseDriver)driver).getShape(index);
114
    }
115

    
116
        private String getTableName(){
117
            return ((VectorialDatabaseDriver)driver).getTableName();
118
        }
119

    
120
        /**
121
         * @see com.iver.cit.gvsig.fmap.layers.ReadableVectorial#getShapeType()
122
         */
123
        public int getShapeType() throws ReadDriverException {
124
                return FShape.MULTI;
125
        }
126

    
127
        /**
128
         * @throws ReadDriverException
129
         * @see com.iver.cit.gvsig.fmap.layers.VectorialAdapter#getRecordset()
130
         */
131
        public SelectableDataSource getRecordset() throws ReadDriverException {
132
            if (driver instanceof ObjectDriver)
133
            {
134
                        String name = LayerFactory.getDataSourceFactory().addDataSource((ObjectDriver)driver);
135
                        try {
136
                ds = new SelectableDataSource(LayerFactory.getDataSourceFactory().createRandomDataSource(name, DataSourceFactory.AUTOMATIC_OPENING));
137
            } catch (NoSuchTableException e) {
138
                throw new RuntimeException(e);
139
                        } catch (DriverLoadException e) {
140
                                throw new ReadDriverException(name,e);
141
                        }
142
            }
143
                return ds;
144
        }
145

    
146
        public class Receiver implements Runnable{
147
                private ByteBuffer bb;
148
                private int currentCapacity = 0;
149
                private FileChannel channel;
150

    
151
                private ByteBuffer indexBuffer = ByteBuffer.allocate(4);
152
                private FileChannel indexChannel;
153

    
154
            private Rectangle2D extent = new Rectangle2D.Double();
155

    
156
                public ByteBuffer getBuffer(int capacity){
157
                        if (capacity > currentCapacity){
158
                                bb = ByteBuffer.allocate(capacity);
159
                                currentCapacity = capacity;
160
                        }
161

    
162
                        return bb;
163
                }
164

    
165
                private void writeObject(byte[] bytes) throws IOException{
166
                        //Se escribe al fichero de datos
167
                        bb = getBuffer(bytes.length + 4);
168
                        bb.clear();
169
                        bb.putInt(bytes.length);
170
                        bb.put(bytes);
171
                        bb.flip();
172
                        channel.write(bb);
173

    
174
                        //Se actualiza el fichero de ?ndice
175
                        indexBuffer.clear();
176
                        indexBuffer.putInt((int) channel.position());
177
                        indexBuffer.flip();
178
                        indexChannel.write(indexBuffer);
179
                }
180

    
181
                /**
182
                 * @see java.lang.Runnable#run()
183
                 */
184
                public void run() {
185
                        try {
186
                                //Abrimos el fichero de datos
187
                                dataFile = new File("/root/tirar/gvSIGtmp.gvs");
188
                                FileOutputStream fs = new FileOutputStream(dataFile);
189
                                channel = fs.getChannel();
190

    
191
                                //Abrimos el fichero de indice
192
                                indexFile = new File("/root/tirar/gvSIGindex.gvi");
193
                                FileOutputStream indexfs = new FileOutputStream(indexFile);
194
                                indexChannel = indexfs.getChannel();
195

    
196
                                //Creamos un adaptador conectado para bajarnos los datos
197
                                VectorialDatabaseDriver d = (VectorialDatabaseDriver) VectorialDisconnectedDBAdapter.this.driver;
198
                                connectedAdapter = new VectorialDBAdapter();
199
                                connectedAdapter.setDriver(d);
200

    
201
                                //Escribimos el n?mero de campos
202
                                indexBuffer.clear();
203
                                indexBuffer.putInt(connectedAdapter.getRecordset().getFieldCount());
204
                                indexBuffer.flip();
205
                                indexChannel.write(indexBuffer);
206
                                indexChannel.position(indexChannel.position() + 4);
207

    
208
                                //Reservamos espacio para el n?mero de campos
209
                                indexChannel.position(indexChannel.position() + 4 * 8);
210

    
211
                                connectedAdapter.start();
212

    
213
                                ByteArrayOutputStream bytes = new ByteArrayOutputStream();
214
                                ObjectOutputStream oos = new ObjectOutputStream(bytes);
215
                                int geom = 0;
216
                                for (int i = 0; i < connectedAdapter.getShapeCount(); i++) {
217
                                        geom++;
218
                                        IGeometry g = connectedAdapter.getShape(i);
219
                                        extent.add(g.getBounds2D());
220

    
221
                                        //Se obtienen los bytes del objeto a serializar
222
                                        bytes = new ByteArrayOutputStream();
223
                                        oos = new ObjectOutputStream(bytes);
224
                                        oos.writeObject(g);
225
                                        oos.close();
226

    
227
                                        //Se escribe al fichero
228
                                        writeObject(bytes.toByteArray());
229

    
230
                                        for (int j = 0; j < connectedAdapter.getRecordset().getFieldCount(); j++) {
231
                                                Value v = connectedAdapter.getRecordset().getFieldValue(i, j);
232

    
233
                                                //Se obtienen los bytes del objeto a serializar
234
                                                bytes = new ByteArrayOutputStream();
235
                                                oos = new ObjectOutputStream(bytes);
236
                                                oos.writeObject(v);
237
                                                oos.close();
238

    
239
                                                //Se escribe al fichero
240
                                                writeObject(bytes.toByteArray());
241
                                        }
242
                                }
243

    
244
                                //Escribimos el n?mero de geometr?as en el fichero de ?ndice
245
                                indexBuffer.clear();
246
                                indexBuffer.putInt(geom);
247
                                indexBuffer.flip();
248
                                indexChannel.position(4);
249
                                indexChannel.write(indexBuffer);
250
                                indexChannel.position(indexChannel.position() + 4);
251

    
252
                                //Escribimos el extent
253
                                ByteBuffer extentBuffer = ByteBuffer.allocate(4*8);
254
                                extentBuffer.putDouble(extent.getMinX());
255
                                extentBuffer.putDouble(extent.getMinY());
256
                                extentBuffer.putDouble(extent.getMaxX());
257
                                extentBuffer.putDouble(extent.getMaxY());
258
                                extentBuffer.flip();
259
                                indexChannel.position(8);
260
                                indexChannel.write(extentBuffer);
261

    
262
                                //Cerramos
263
                                channel.close();
264
                                indexChannel.close();
265

    
266
                                connectedAdapter.stop();
267

    
268
                                status = LOCAL;
269
                        } catch (IOException e) {
270
                                throw new RuntimeException(e);
271
                        } catch (ReadDriverException e) {
272
                                throw new RuntimeException(e);
273
                        }
274
                }
275

    
276
        }
277
}