Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / edition / writers / dbf / DbfWriter.java @ 6212

History | View | Annotate | Download (7.91 KB)

1
package com.iver.cit.gvsig.fmap.edition.writers.dbf;
2

    
3
import java.io.File;
4
import java.io.IOException;
5
import java.io.RandomAccessFile;
6
import java.nio.channels.FileChannel;
7
import java.nio.channels.WritableByteChannel;
8
import java.sql.Types;
9
import java.util.ArrayList;
10

    
11
import com.iver.cit.gvsig.fmap.core.IRow;
12
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
13
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
14
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileHeaderNIO;
15
import com.iver.cit.gvsig.fmap.drivers.shp.DbaseFileWriterNIO;
16
import com.iver.cit.gvsig.fmap.edition.EditionException;
17
import com.iver.cit.gvsig.fmap.edition.IFieldManager;
18
import com.iver.cit.gvsig.fmap.edition.IRowEdited;
19
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.AddFieldCommand;
20
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.FieldCommand;
21
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.RemoveFieldCommand;
22
import com.iver.cit.gvsig.fmap.edition.fieldmanagers.RenameFieldCommand;
23
import com.iver.cit.gvsig.fmap.edition.writers.AbstractWriter;
24
import com.iver.cit.gvsig.fmap.layers.FBitSet;
25

    
26
public class DbfWriter extends AbstractWriter implements IFieldManager {
27
        private String dbfPath = null;
28

    
29
        private DbaseFileWriterNIO dbfWrite;
30

    
31
        private DbaseFileHeaderNIO myHeader;
32

    
33
        private int numRows;
34

    
35
        private Object[] record;
36

    
37
        private ArrayList fieldCommands = new ArrayList();
38

    
39
        // private FLyrVect lyrVect;
40
        private FBitSet selection = null;
41

    
42
        private FieldDescription[] originalFields;
43

    
44
        public void setFile(File f) {
45
                String strFichDbf = f.getAbsolutePath().replaceAll("\\.shp", ".dbf");
46
                dbfPath = strFichDbf.replaceAll("\\.SHP", ".DBF");
47
        }
48

    
49
        private WritableByteChannel getWriteChannel(String path) throws IOException {
50
                WritableByteChannel channel;
51

    
52
                File f = new File(path);
53

    
54
                if (!f.exists()) {
55
                        System.out.println("Creando fichero " + f.getAbsolutePath());
56

    
57
                        if (!f.createNewFile()) {
58
                                System.err.print("Error al crear el fichero "
59
                                                + f.getAbsolutePath());
60
                                throw new IOException("Cannot create file " + f);
61
                        }
62
                }
63

    
64
                RandomAccessFile raf = new RandomAccessFile(f, "rw");
65
                channel = raf.getChannel();
66

    
67
                return channel;
68
        }
69

    
70
        public void preProcess() throws EditionException {
71
                // Por ahora solo escribimos los primeros bytes
72
                // de las cabeceras. Luego en el postprocess los escribiremos
73
                // correctamente, con el fullExtent y el numero de
74
                // registros que tocan.
75
                alterTable();
76
                if (selection == null) {
77

    
78
                        try {
79
                                myHeader.setNumRecords(0);
80
                                dbfWrite = new DbaseFileWriterNIO(myHeader,
81
                                                (FileChannel) getWriteChannel(dbfPath));
82
                                record = new Object[myHeader.getNumFields()];
83
                                numRows = 0;
84

    
85
                        } catch (IOException e) {
86
                                e.printStackTrace();
87
                                throw new EditionException(e);
88
                        }
89
                }
90

    
91
        }
92

    
93
        public void process(IRowEdited row) throws EditionException {
94
                IRow rowEdit = (IRow) row.getLinkedRow();
95
                System.err.println("DBFWriter: " + row.getStatus() + " numRows = "
96
                                + numRows);
97
                switch (row.getStatus()) {
98
                case IRowEdited.STATUS_ADDED:
99
                case IRowEdited.STATUS_ORIGINAL:
100
                case IRowEdited.STATUS_MODIFIED:
101
                        try {
102

    
103
                                for (int i = 0; i < record.length; i++)
104
                                        record[i] = rowEdit.getAttribute(i);
105
                                dbfWrite.write(record);
106
                                numRows++;
107

    
108
                        } catch (IOException e) {
109
                                e.printStackTrace();
110
                                throw new EditionException(e);
111
                        }
112

    
113
                }
114

    
115
        }
116

    
117
        public void postProcess() throws EditionException {
118
                try {
119
                        myHeader.setNumRecords(numRows);
120
                        dbfWrite = new DbaseFileWriterNIO(myHeader,
121
                                        (FileChannel) getWriteChannel(dbfPath));
122

    
123
                } catch (IOException e) {
124
                        e.printStackTrace();
125
                        throw new EditionException(e);
126
                }
127

    
128
        }
129

    
130
        public String getName() {
131
                return "DBF Writer";
132
        }
133

    
134
        public boolean canWriteAttribute(int sqlType) {
135
                switch (sqlType) {
136
                case Types.DOUBLE:
137
                case Types.FLOAT:
138
                case Types.INTEGER:
139
                case Types.BIGINT:
140
                        return true;
141
                case Types.DATE:
142
                        return true;
143
                case Types.BIT:
144
                case Types.BOOLEAN:
145
                        return true;
146
                case Types.VARCHAR:
147
                case Types.CHAR:
148
                case Types.LONGVARCHAR:
149
                        return true; // TODO: Revisar esto, porque no creo que admita
150
                // campos muy grandes
151

    
152
                }
153

    
154
                return false;
155
        }
156

    
157
        public void initialize(ITableDefinition tableDefinition)
158
                        throws EditionException {
159
                originalFields = tableDefinition.getFieldsDesc();
160
                myHeader = DbaseFileHeaderNIO.createDbaseHeader(tableDefinition
161
                                .getFieldsDesc());
162
                if (dbfPath == null) {
163
                        throw new EditionException(
164
                                        "DBFWriter: You need to use setFile before initialize.");
165
                }
166

    
167
        }
168

    
169
        public FieldDescription[] getOriginalFields() {
170
                return originalFields;
171
        }
172

    
173
        public boolean alterTable() throws EditionException {
174
                ArrayList fields = new ArrayList();
175
                boolean bNeedRewrite = false;
176
                for (int i = 0; i < fieldCommands.size(); i++) {
177
                        FieldCommand fc = (FieldCommand) fieldCommands.get(i);
178
                        if (fc instanceof AddFieldCommand) {
179
                                AddFieldCommand addFC = (AddFieldCommand) fc;
180
                                bNeedRewrite = true;
181
                                fields.add(addFC.getFieldDesc());
182
                        }
183
                        if (fc instanceof RemoveFieldCommand) {
184
                                bNeedRewrite = true;
185
                                RemoveFieldCommand deleteFC = (RemoveFieldCommand) fc;
186
                                // for (int j=0; j < myHeader.getNumFields(); j++)
187
                                // {
188
                                // if
189
                                // (myHeader.getFieldName(j).compareTo(deleteFC.getFieldName())
190
                                // == 0)
191
                                // {
192
                                myHeader.removeColumn(deleteFC.getFieldName());
193
                                // break;
194
                                // }
195
                                // }
196

    
197
                        }
198
                        if (fc instanceof RenameFieldCommand) {
199
                                RenameFieldCommand renFC = (RenameFieldCommand) fc;
200
                                for (int j = 0; j < myHeader.getNumFields(); j++) {
201
                                        if (myHeader.getFieldName(j).compareTo(renFC.getAntName()) == 0) {
202
                                                myHeader.setFieldName(j, renFC.getNewName());
203
                                                break;
204
                                        }
205
                                }
206
                        }
207

    
208
                }
209
                FieldDescription[] fieldsDesc = (FieldDescription[]) fields
210
                                .toArray(new FieldDescription[0]);
211

    
212
                myHeader = DbaseFileHeaderNIO.createDbaseHeader(fieldsDesc);
213
                try {
214
                        dbfWrite = new DbaseFileWriterNIO(myHeader,
215
                                        (FileChannel) getWriteChannel(dbfPath));
216
//                        if (bNeedRewrite) {
217
//                                int aux = (int) (Math.random() * 1000);
218
//                                File fTemp = new File(System.getProperty("java.io.tmpdir")
219
//                                                + "/tmpDbf" + aux + ".dbf");
220
//
221
//                                // TODO: TERMINAR!!
222
//
223
//                        }
224
                } catch (IOException e) {
225
                        throw new EditionException(e);
226
                }
227
                return bNeedRewrite;
228
        }
229

    
230
        public void addField(FieldDescription fieldDesc) {
231
                AddFieldCommand c = new AddFieldCommand(fieldDesc);
232
                fieldCommands.add(c);
233
        }
234

    
235
        public FieldDescription removeField(String fieldName) {
236
                RemoveFieldCommand c = new RemoveFieldCommand(fieldName);
237
                FieldDescription[] act = getFields();
238
                FieldDescription found = null;
239
                for (int i=0; i < act.length; i++)
240
                {
241
                        if (act[i].getFieldAlias().compareToIgnoreCase(fieldName) == 0)
242
                        {
243
                                found = act[i];
244
                                break;
245
                        }
246
                }
247
                fieldCommands.add(c);
248
                return found;
249
        }
250

    
251
        public void renameField(String antName, String newName) {
252
                RenameFieldCommand c = new RenameFieldCommand(antName, newName);
253
                fieldCommands.add(c);
254
                
255
        }
256

    
257
        public FieldDescription[] getFields() {
258
                ArrayList aux = new ArrayList();
259
                for (int i=0; i < aux.size(); i++)
260
                {
261
                        aux.add(getOriginalFields()[i]);
262
                }
263
                // procesamos comandos para devolver los campos reales.
264
                for (int j=0; j < fieldCommands.size(); j++)
265
                {
266
                        FieldCommand fc = (FieldCommand) fieldCommands.get(j);
267
                        if (fc instanceof AddFieldCommand)
268
                        {
269
                                AddFieldCommand ac = (AddFieldCommand) fc;
270
                                aux.add(ac.getFieldDesc());
271
                        }
272
                        if (fc instanceof RemoveFieldCommand)
273
                        {
274
                                RemoveFieldCommand rc = (RemoveFieldCommand) fc;
275
                                for (int k = 0; k < aux.size(); k++) {
276
                                        FieldDescription fAux = (FieldDescription) aux.get(k);
277
                                        if (fAux.getFieldAlias().compareTo(rc.getFieldName()) == 0) {
278
                                                aux.remove(k);
279
                                                break;
280
                                        }
281
                                }
282
                        }
283
                        if (fc instanceof RenameFieldCommand)
284
                        {
285
                                RenameFieldCommand renc = (RenameFieldCommand) fc;
286
                                for (int k = 0; k < aux.size(); k++) {
287
                                        FieldDescription fAux = (FieldDescription) aux.get(k);
288
                                        if (fAux.getFieldAlias().compareTo(renc.getAntName()) == 0) {
289
                                                fAux.setFieldAlias(renc.getNewName());
290
                                                break;
291
                                        }
292
                                }
293

    
294
                        }                        
295
                        
296
                }
297
                return (FieldDescription[]) aux.toArray(new FieldDescription[0]);
298
        }
299

    
300
}