Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.dal / org.gvsig.fmap.dal.file / org.gvsig.fmap.dal.file.csv / src / main / java / org / gvsig / fmap / dal / store / gml / virtualrows / XMLFileAsList.java @ 47652

History | View | Annotate | Download (30.1 KB)

1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.fmap.dal.store.gml.virtualrows;
7

    
8
import java.io.BufferedReader;
9
import java.io.Closeable;
10
import java.io.File;
11
import java.io.IOException;
12
import java.io.Reader;
13
import java.nio.ByteBuffer;
14
import java.nio.CharBuffer;
15
import java.nio.charset.Charset;
16
import java.nio.charset.StandardCharsets;
17
import java.util.AbstractList;
18
import java.util.ArrayList;
19
import java.util.HashMap;
20
import java.util.List;
21
import java.util.Map;
22
import java.util.Objects;
23
import javax.xml.parsers.SAXParser;
24
import javax.xml.parsers.SAXParserFactory;
25
import org.apache.commons.collections4.CollectionUtils;
26
import org.apache.commons.io.FilenameUtils;
27
import org.apache.commons.io.IOUtils;
28
import org.apache.commons.io.input.CloseShieldReader;
29
import org.apache.commons.lang3.StringUtils;
30
import org.gvsig.fmap.dal.store.simplereader.virtualrows.LimitedReader;
31
import org.gvsig.fmap.dal.store.simplereader.virtualrows.RandomAccessFileReader;
32
import org.gvsig.fmap.dal.store.simplereader.virtualrows.RecordsFile;
33
import org.gvsig.fmap.dal.store.simplereader.virtualrows.RecordsFile.Record;
34
import org.gvsig.fmap.dal.store.simplereader.virtualrows.RecordsFile.RecordType;
35
import static org.gvsig.fmap.dal.store.simplereader.virtualrows.RecordsFile.RecordTypeBuilder.recordTypeBuilder;
36
import org.gvsig.fmap.dal.store.simplereader.virtualrows.RecordsFileImpl;
37
import org.gvsig.fmap.geom.Geometry;
38
import org.gvsig.fmap.geom.GeometryLocator;
39
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
40
import org.gvsig.tools.util.GetItemWithSize64;
41
import org.xml.sax.Attributes;
42
import org.xml.sax.InputSource;
43
import org.xml.sax.Locator;
44
import org.xml.sax.SAXException;
45
import org.xml.sax.helpers.DefaultHandler;
46

    
47
/**
48
 *
49
 * @author jjdelcerro
50
 */
51
@SuppressWarnings("UseSpecificCatch")
52
public class XMLFileAsList
53
        extends AbstractList<List<String>>
54
        implements Closeable, GetItemWithSize64<List<String>> {
55
    
56
    public static final int COMBINE_NONE = 0;
57
    public static final int COMBINE_FIRST_NOT_NULL = 1;
58

    
59
    private static final int IDXFIELD_BEGINLINE = 0; //INTEGER
60
    private static final int IDXFIELD_BEGINCOLUMN = 1; //INTEGER
61
    private static final int IDXFIELD_BEGINRECORDPOS = 2; //LONG
62
    private static final int IDXFIELD_ENDLINE = 3; //INTEGER
63
    private static final int IDXFIELD_ENDCOLUMN = 4; //INTEGER
64
    
65
    private static final int IDXFIELD_BEGINGEOMLINE = 5; //INTEGER
66
    private static final int IDXFIELD_BEGINGEOMCOLUMN = 6; //INTEGER
67
    private static final int IDXFIELD_BEGINGEOMPOS = 7; //LONG
68
    private static final int IDXFIELD_ENDGEOMLINE = 8; //INTEGER
69
    private static final int IDXFIELD_ENDGEOMCOLUMN = 9; //INTEGER
70
    private static final int IDXFIELD_ENDGEOMPOS = 10; //LONG
71

    
72
            
73
    private final RandomAccessFileReader reader;
74
    private final String recordPath;
75
    private RecordsFile index;
76
    private List<String> fieldPaths;
77
    private final List<String> geomPaths;
78
    private int combineMode;
79

    
80
    
81
    //                                                         ruta   recordnum                       ruta   recordnum
82
 // public XMLFileAsList(File text, Charset charset, List<Pair<String,Integer>> recordPath, List<Pair<String,Integer>> fieldPaths) throws IOException {
83
    public XMLFileAsList(File text, Charset charset, String recordPath, List<String> geomPath, List<String> fieldPaths) throws IOException {
84
        this.reader = new RandomAccessFileReader(text, charset);
85
        this.index = null;
86
        this.recordPath = recordPath;
87
        this.geomPaths = geomPath;
88
    }
89

    
90
    public XMLFileAsList(File text, File index, Charset charset, String recordPath, List<String> geomPath, List<String> fieldPaths) throws IOException {
91
        this.reader = new RandomAccessFileReader(text, charset);
92
        this.recordPath = recordPath;
93
        this.geomPaths = geomPath;
94
        this.fieldPaths = fieldPaths;
95
        if (index.exists()) {
96
            // TODO: Force to create index if text newer than index
97
            this.index = new RecordsFileImpl(index);
98
        } else {
99
            this.createIndex(index);
100
        }
101
    }
102

    
103
    public XMLFileAsList(RandomAccessFileReader reader, RecordsFile index, String recordPath, List<String> geomPath, List<String> fieldPaths) throws IOException {
104
        this.reader = reader;
105
        this.index = index;
106
        this.recordPath = recordPath;
107
        this.geomPaths = geomPath;
108
    }
109

    
110
    @Override
111
    public void close() {
112
        IOUtils.closeQuietly(this.reader);
113
        IOUtils.closeQuietly(this.index);
114
    }
115

    
116
    private List<String> getRecord(long position, List<String> fieldPaths) {
117
        class StopParserSAXException extends SAXException {
118
        }
119

    
120
        class ParseRecordsHandler extends DefaultHandler {
121

    
122
            Locator locator;
123
            List<String> path = new ArrayList<>();
124
            Map<String, String> record = new HashMap<>();
125
            StringBuilder value = new StringBuilder();
126
            List<String> values = new ArrayList<>();
127
            private int endLineNumber;
128
            private int endColumnNumber;
129

    
130
            @Override
131
            public void setDocumentLocator(Locator locator) {
132
                this.locator = locator;
133
            }
134

    
135
            @Override
136
            public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
137
                localName = removeNamespace(qName);
138
                path.add(localName);
139
                String path_s = StringUtils.join(path, "/");
140
                if (StringUtils.equalsIgnoreCase(path_s, recordPath)) {
141
                    return;
142
                }
143
                this.value.setLength(0);
144
                for (int i = 0; i < attributes.getLength(); i++) {
145
                    String attrPath = path_s+"/"+removeNamespace(attributes.getQName(i));
146
                    for (String fieldPath : fieldPaths) {
147
                        if (StringUtils.equalsIgnoreCase(attrPath, fieldPath)) {
148
                            record.put(fieldPath, attributes.getValue(i));
149
                            // No break to handle repeated columns
150
                        }
151
                    }
152
                }
153
            }
154

    
155
            @Override
156
            public void characters(char[] ch, int start, int length) throws SAXException {
157
                value.append(new String(ch, start, length));
158
            }
159

    
160
            private String removeNamespace(String s){
161
                if(s.indexOf(':') < 0){
162
                    return s;
163
                }
164
                String[] ss = s.split(":");
165
                return ss[1];
166
            }
167
            
168
            @Override
169
            public void endElement(String uri, String localName, String qName) throws SAXException {
170
                localName = removeNamespace(qName);
171
                String path_s = StringUtils.join(path, "/");
172

    
173
                for (String fieldPath : fieldPaths) {
174
                    if (StringUtils.equalsIgnoreCase(path_s, fieldPath)) {
175
                        record.put(fieldPath, this.value.toString());
176
                        // No break to handle repeated columns
177
                    }
178
                }
179

    
180
                if (this.locator.getLineNumber() >= this.endLineNumber
181
                        && this.locator.getColumnNumber() >= this.endColumnNumber) {
182
                    for (String fieldPath : fieldPaths) {
183
                        values.add(record.get(fieldPath));
184
                    }
185
                    throw new StopParserSAXException();
186
                }
187

    
188
                path.remove(path.size() - 1);
189
            }
190
        }
191

    
192
//        System.out.println("RECORD "+position);
193
        ParseRecordsHandler handler = null;
194
        Record record = this.index.get64(position);
195
        try {
196
            long recordPosition = record.getLong(IDXFIELD_BEGINRECORDPOS);
197
            this.reader.seek(recordPosition);
198
            // TODO: guardarse el tama?o del registro en el indice y en funcion de eso usar un buffersize mas peque?o aqui si procede
199
            int bufferSize = 1024*8; 
200
            BufferedReader breader = new BufferedReader(this.reader, bufferSize);
201

    
202
            InputSource is = new InputSource(CloseShieldReader.wrap(breader));
203
            SAXParserFactory spf = SAXParserFactory.newInstance();
204
            spf.setNamespaceAware(false);
205
            SAXParser saxParser = spf.newSAXParser();
206
            handler = new ParseRecordsHandler();
207
            handler.endLineNumber=(int) (record.getInt(IDXFIELD_ENDLINE)-record.getInt(IDXFIELD_BEGINLINE)+1);
208
            handler.endColumnNumber=(int) record.getInt(IDXFIELD_ENDCOLUMN);
209

    
210
            saxParser.parse(is, handler);
211
        } catch (StopParserSAXException ex) {
212
            //Do nothing
213
        } catch (Exception ex) {
214
            throw new RuntimeException("Can't parse record " + position, ex);
215
        }
216
        if (handler == null) {
217
            return null;
218
        }
219
        try {
220
            Geometry geom = null;
221
            if(CollectionUtils.isNotEmpty(this.geomPaths)) {
222
                for (int i = 0; i < this.geomPaths.size(); i++) {
223
                    long geomPosition = record.getLong(IDXFIELD_BEGINGEOMPOS+i*6);
224
                    long endGeomPosition = record.getLong(IDXFIELD_ENDGEOMPOS+i*6);
225
                    if(geomPosition == 0 || endGeomPosition == 0){
226
                        if(this.combineMode != COMBINE_FIRST_NOT_NULL){
227
                            handler.values.add(null);
228
                        }
229
                        continue;
230
                    }
231
                    this.reader.seek(geomPosition);
232
                    if(position == 0){
233
                        char[] cbuff = new char[(int)(endGeomPosition-geomPosition)];
234
                        this.reader.read(cbuff);
235
//                        System.out.println("["+new String(cbuff)+"]");
236
                        this.reader.seek(geomPosition);
237
                    }
238
                    Reader limitedReader = new LimitedReader(reader, (int)(endGeomPosition-geomPosition));
239
                    // TODO: calcular el buffersize como el min(8k,endGeomPosition-geomPosition+1)
240
                    int bufferSize = 1024*8; 
241
                    BufferedReader breader = new BufferedReader(limitedReader, bufferSize);
242
                    geom = GeometryLocator.getGeometryManager().createFrom(breader, null);
243
                    if(this.combineMode == COMBINE_FIRST_NOT_NULL){
244
                        if(geom != null){
245
                            handler.values.add(geom.convertToHexWKB());
246
                            break;
247
                        }
248
                    } else {
249
                        handler.values.add(geom.convertToHexWKB());
250
                    }
251
                }
252
                if(this.combineMode == COMBINE_FIRST_NOT_NULL && geom == null){
253
                    handler.values.add(null);
254
                }
255
            }
256
            
257
        } catch (Exception ex) {
258
            throw new RuntimeException("Can't parse record " + position, ex);
259
        }
260
        return handler.values;
261
    }
262

    
263
    @Override
264
    public List<String> get(int index) {
265
        return this.getRecord(index, fieldPaths);
266
    }
267

    
268
    @Override
269
    public List<String> get64(long position) {
270
        return this.getRecord(position, fieldPaths);
271
    }
272

    
273
    @Override
274
    public int size() {
275
        return this.index.size();
276
    }
277

    
278
    @Override
279
    public long size64() {
280
        return this.index.size64();
281
    }
282

    
283
    public int getCombineMode() {
284
        return combineMode;
285
    }
286
    
287
    public void setCombineMode(int combineMode) {
288
        this.combineMode = combineMode;
289
    }
290

    
291
    final public void createIndex(File indexFile) throws IOException {
292
        try {
293
            // 1. Creamos el indice vacio
294
            RecordsFile.RecordTypeBuilder builder = recordTypeBuilder()
295
                    .addInteger()
296
                    .addInteger()
297
                    .addLong()
298
                    .addInteger()
299
                    .addInteger();
300

    
301
            if (CollectionUtils.isNotEmpty(geomPaths)) {
302
                for (int i = 0; i < geomPaths.size(); i++) {
303
                    builder.addInteger()
304
                            .addInteger()
305
                            .addLong()
306
                            .addInteger()
307
                            .addInteger()
308
                            .addLong();
309
                }
310
            }
311
            RecordType recordType = builder.build();
312
            Record record = recordType.createRecord();
313
            final RecordsFile theIndex = new RecordsFileImpl();
314
            theIndex.create(indexFile, recordType);
315

    
316
            // 2. Rellenamos los campos numero de linea y columna de cada registro 
317
            //    en el indice.
318
            // Para ello nos recorremos el XML y vamos escribiendo en el indice.
319
            this.reader.rewind();
320
            InputSource is = new InputSource(CloseShieldReader.wrap(reader));
321
            SAXParserFactory spf = SAXParserFactory.newInstance();
322
            spf.setNamespaceAware(true);
323
            SAXParser saxParser = spf.newSAXParser();
324

    
325
            List<String> path = new ArrayList<>();
326
            // TODO: Aqui habria que quedarse con la primera aparicion de
327
            // los campos solicitados que no pertenezcan al registro principal.
328
            // Probablemente habria que guardar esos valores en disco junto al
329
            // fichero de indice.
330
            saxParser.parse(is, new DefaultHandler() {
331
                Locator locator;
332
                private int beginLineNumber;
333
                private int beginColumnNumber;
334
                private int lastTagLineNumber;
335
                private int lastTagColumnNumber;
336

    
337
                @Override
338
                public void setDocumentLocator(Locator locator) {
339
                    this.locator = locator;
340
                }
341

    
342
                @Override
343
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
344
                    path.add(localName);
345
                    String path_s = StringUtils.join(path, "/");
346
                    
347
                    
348
                    if (StringUtils.equalsIgnoreCase(path_s, recordPath)) {
349
                        record.setInt(IDXFIELD_BEGINLINE, locator.getLineNumber());
350
                        record.setInt(IDXFIELD_BEGINCOLUMN, locator.getColumnNumber());
351
                        record.setInt(IDXFIELD_ENDLINE, 0);
352
                        record.setInt(IDXFIELD_ENDCOLUMN, 0);
353
                        if(CollectionUtils.isNotEmpty(geomPaths)) {
354
                            for (int i = 0; i < geomPaths.size(); i++) {
355
                                record.setInt(IDXFIELD_BEGINGEOMLINE+6*i, 0);
356
                                record.setInt(IDXFIELD_BEGINGEOMCOLUMN+6*i, 0);
357
                                record.setLong(IDXFIELD_BEGINGEOMPOS+6*i, 0);
358
                                record.setInt(IDXFIELD_ENDGEOMLINE+6*i, 0);
359
                                record.setInt(IDXFIELD_ENDGEOMCOLUMN+6*i, 0);
360
                                record.setLong(IDXFIELD_ENDGEOMPOS+6*i, 0);
361
                            }
362
                        }
363
                        this.beginLineNumber = locator.getLineNumber();
364
                        this.beginColumnNumber = locator.getColumnNumber();
365
                    }
366
                    if(CollectionUtils.isNotEmpty(geomPaths)) {
367
                        for (int i = 0; i < geomPaths.size(); i++) {
368
                            String geomPath = geomPaths.get(i);
369
                            if (StringUtils.equalsIgnoreCase(path_s, recordPath+"/"+geomPath)) {
370
                                record.setInt(IDXFIELD_BEGINGEOMLINE+6*i, locator.getLineNumber());
371
                                record.setInt(IDXFIELD_BEGINGEOMCOLUMN+6*i, locator.getColumnNumber());
372
                                record.setLong(IDXFIELD_BEGINGEOMPOS+6*i, 0);
373
                                break;
374
                            }
375
                        }
376
                    }
377

    
378
                }
379

    
380
                @Override
381
                public void endElement(String uri, String localName, String qName) throws SAXException {
382
                    String path_s = StringUtils.join(path, "/");
383
                    
384
                    if (StringUtils.equalsIgnoreCase(path_s, recordPath)) {
385
                        int line = lastTagLineNumber;//-this.beginLineNumber;
386
                        int column = this.lastTagColumnNumber;
387
                        if(line==0){
388
                            column = column - this.beginColumnNumber;
389
                        }
390
                        record.setInt(IDXFIELD_ENDLINE, line);
391
                        record.setInt(IDXFIELD_ENDCOLUMN, column);
392
                        theIndex.add(record);
393
                    }
394
                    if(CollectionUtils.isNotEmpty(geomPaths)) {
395
                        for (int i = 0; i < geomPaths.size(); i++) {
396
                            String geomPath = geomPaths.get(i);
397
                            if (StringUtils.equalsIgnoreCase(path_s, recordPath+"/"+geomPath)) {
398
                                record.setInt(IDXFIELD_ENDGEOMLINE+6*i, this.lastTagLineNumber);
399
                                record.setInt(IDXFIELD_ENDGEOMCOLUMN+6*i, this.lastTagColumnNumber);
400
                                break;
401
                            }
402
                        }
403
                    }
404
                    this.lastTagLineNumber = locator.getLineNumber();
405
                    this.lastTagColumnNumber = locator.getColumnNumber();
406
                    path.remove(path.size() - 1);
407
                }
408
            });
409

    
410
            // 3. Nos recorremos el indice y calculamos la posicion de la linea
411
            //    para cada registro.
412
            this.reader.rewind();
413
            PositionCalculator positionCalculator = new PositionCalculator(reader);
414

    
415
            for (int j = 0; j < theIndex.size(); j++) {
416
                Record r = theIndex.get(j);
417
//                if(i==0){
418
//                    System.out.println("RECO BEGIN: "+r.getLong(IDXFIELD_BEGINLINE) + " " + r.getLong(IDXFIELD_BEGINCOLUMN));
419
//                    if(CollectionUtils.isNotEmpty(geomPaths)) {
420
//                        for (int i = 0; i < geomPaths.size(); i++) {
421
//                            System.out.println("GEOM"+i+"BEGIN: "+r.getLong(IDXFIELD_BEGINGEOMLINE+i*6) + " " + r.getLong(IDXFIELD_BEGINGEOMCOLUMN+i*6));
422
//                            System.out.println("GEOM"+i+"END  : "+r.getLong(IDXFIELD_ENDGEOMLINE+i*6) + " " +  r.getLong(IDXFIELD_ENDGEOMCOLUMN+i*6));
423
//                        }
424
//                    }
425
//                    System.out.println("RECO END  : "+r.getLong(IDXFIELD_ENDLINE) + " " +  r.getLong(IDXFIELD_ENDCOLUMN));
426
//                }
427
                positionCalculator.next(r.getInt(IDXFIELD_BEGINLINE), r.getInt(IDXFIELD_BEGINCOLUMN));
428
                r.setLong(IDXFIELD_BEGINRECORDPOS, positionCalculator.getColumnPosition());
429
//                System.out.println("RPOS      : " + r.getLong(IDXFIELD_BEGINRECORDPOS));
430
                if(CollectionUtils.isNotEmpty(geomPaths)) {
431
                    for (int i = 0; i < geomPaths.size(); i++) {
432
                        long beginGeomLine = r.getInt(IDXFIELD_BEGINGEOMLINE + i * 6);
433
                        long endGeomLine = r.getInt(IDXFIELD_ENDGEOMLINE + i * 6);
434
                        if (beginGeomLine == 0 || endGeomLine == 0) {
435
                            continue;
436
                        }
437
                        positionCalculator.next(beginGeomLine, r.getInt(IDXFIELD_BEGINGEOMCOLUMN + i * 6));
438
                        r.setLong(IDXFIELD_BEGINGEOMPOS + i * 6, positionCalculator.getColumnPosition());
439
                        positionCalculator.next(endGeomLine, r.getInt(IDXFIELD_ENDGEOMCOLUMN + i * 6));
440
                        r.setLong(IDXFIELD_ENDGEOMPOS + i * 6, positionCalculator.getColumnPosition());
441
//                        System.out.println("GPOS" + i + "     : " + r.getLong(IDXFIELD_BEGINGEOMPOS + i * 6) + " " + r.getLong(IDXFIELD_ENDGEOMPOS + i * 6));
442
                    }
443
                }
444
                theIndex.set(j, r);
445
            }
446
            this.index = new RecordsFileImpl(indexFile);
447
        } catch (Exception ex) {
448
            throw new IOException("Can't create index " + Objects.toString(indexFile), ex);
449
        }
450
    }
451
    
452

    
453
    private static class CharacterSize {
454

    
455
        private final Charset charset;
456
        private final CharBuffer charBuffer;
457

    
458
        public CharacterSize(Charset charset) {
459
            this.charset = charset;
460
            this.charBuffer = CharBuffer.allocate(1);
461
        }
462

    
463
        public int size(char ch) {
464
            this.charBuffer.put(0, ch);
465
            this.charBuffer.position(0);
466
            ByteBuffer buffer = this.charset.encode(this.charBuffer);
467
            return buffer.limit();
468
        }
469

    
470
        public int size(char[] cbuf, int off, int len) {
471
            CharBuffer cb = CharBuffer.wrap(cbuf, off, len);
472
            ByteBuffer byteBuffer = this.charset.encode(cb);
473
            return byteBuffer.limit();
474
        }
475

    
476
        public int size(char[] cbuf) {
477
            CharBuffer cb = CharBuffer.wrap(cbuf, 0, cbuf.length);
478
            ByteBuffer byteBuffer = this.charset.encode(cb);
479
            return byteBuffer.limit();
480
        }
481

    
482
        public int size(String s) {
483
            CharBuffer cb = CharBuffer.wrap(s);
484
            ByteBuffer byteBuffer = this.charset.encode(cb);
485
            return byteBuffer.limit();
486
        }
487
    }
488

    
489
    private static class PositionCalculator {
490

    
491
        private final RandomAccessFileReader reader;
492
        private final BufferedReader breader;
493
        private long currentPosition;
494
        private long currentColumn;
495
        private long currentLine;
496
        private long currentColumnPosition;
497
        private long currentLinePosition;
498

    
499
        private final char[] ch;
500
        private final CharacterSize characterSize;
501

    
502
        public PositionCalculator(RandomAccessFileReader reader) {
503
            this.reader = reader;
504
            this.breader = new BufferedReader(this.reader, 1024 * 8);
505
            this.currentPosition = this.reader.getCurrentPosition();
506
            this.currentLine = 1;
507
            this.currentColumn = 1;
508
            this.ch = new char[1];
509
            this.characterSize = new CharacterSize(this.reader.getCharset());
510
        }
511

    
512
        public boolean next(long line, long column) throws IOException {
513
//            System.out.println();
514
//            System.out.println("----"+line+" "+column);
515
            if(this.currentLine>line){
516
                throw new IOException("Illegal column number " + column + " ("+this.currentColumn+") for line " + line+ " ("+this.currentLine+")");
517
            }
518
            if(this.currentLine==line && this.currentColumn > column){
519
                throw new IOException("Illegal column number " + column + " ("+this.currentColumn+") for line " + line);
520
            }
521
//            System.out.print(this.currentLine+":");
522
            while (this.currentLine < line) {
523
                if (breader.read(this.ch, 0, 1) < 1) {
524
                    return false;
525
                }
526
                char c = ch[0];
527
//                System.out.print(String.valueOf(c));
528
                this.currentPosition += characterSize.size(c);
529
                if (c == '\n') {
530
                    this.currentLine++;
531
                    this.currentColumn = 1;
532
//                    System.out.print(this.currentLine+":");
533
                }
534
            }
535
            this.currentLinePosition = this.currentPosition;
536
            while (true) {
537
                if (breader.read(this.ch, 0, 1) < 1) {
538
                    return false;
539
                }
540
                char c = ch[0];
541
//                System.out.print(String.valueOf(c));
542
                this.currentColumn++;
543
                this.currentPosition += characterSize.size(c);
544
                if(this.currentColumn >= column){
545
                    break;
546
                }
547
                if (c == '\n') {
548
                    throw new IOException("Illegal column number " + column + " ("+this.currentColumn+") for line " + line+ " ("+this.currentLine+")");
549
                }
550
            }
551
            this.currentColumnPosition = this.currentPosition;
552
//            System.out.println();
553
            return true;
554
        }
555

    
556
        public long getLinePosition() {
557
            return this.currentLinePosition;
558
        }
559

    
560
        public long getColumnPosition() {
561
            return this.currentColumnPosition;
562
        }
563

    
564
    }
565

    
566
    public static void main(String[] args) throws Exception {
567
        new DefaultLibrariesInitializer().fullInitialize();
568

    
569
//        final String XMLFILE1 = "/home/jjdelcerro/datos/geodata/vector/gml/navarra.gml";
570
//        final String XMLFILE2 = "/home/jjdelcerro/datos/geodata/vector/gml/Municipis/Municipis.gml";
571
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/1075305YJ2717N.gml";
572
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/Recinto.gml";
573
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/FG-GML-543863-AdmBdry-20190101-0001.gml";
574
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/Municipis.gml";
575
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/navarra.gml";
576
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/Falls.gml";
577
        
578
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/AerodromeArea.gml";
579
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/AerodromeType.gml"; //No tiene geometr?as
580
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/CablewayLink.gml";
581
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/CrossingS.gml";
582
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/CrossingP.gml";
583
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/EmbankmentL.gml";
584
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/EmbankmentS.gml";
585
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/FordP.gml";
586
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/DamOrWeirL.gml";
587
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RunwayArea.gml";
588
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RailwayStationArea.gml";
589
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/DamOrWeirS.gml";
590
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/NominalTrackGauge.gml"; //No tiene geometr?as
591
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/NumberOfTracks.gml"; //No tiene geometr?as
592
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/Road.gml"; //No tiene geometr?as
593
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RoadServiceType.gml"; //No tiene geometr?as
594
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RailwayArea.gml";
595
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RailwayElectrification.gml"; //No tiene geometr?as
596
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RailwayType.gml"; //No tiene geometr?as
597
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RailwayLink.gml"; //Added Multicurve Strategy (ojo, en los registros, tras la geometr?a aparece otro atributo a null
598
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RailwayYardArea.gml";
599
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RoadServiceArea.gml";
600
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/ShorelineConstructionL.gml";
601
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/StandingWater.gml";
602
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/SurfaceComposition.gml";
603
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/WatercourseLinkSequence.gml"; //No tiene geometr?as
604
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/Wetland.gml";
605

    
606
        
607
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/BuildingP.gml";
608
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/INSPIRE_GN.gml";
609

    
610
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/INSPIRE_AU.gml"; //Hay 3 geometr?as, LineString, Surface y MultiSurface
611

    
612
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/WatercourseLink.gml";
613
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/Watercourse.gml"; //Hay 2 geometr?as, Curve y Multicurve
614
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/FormOfWay.gml";
615
        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RoadArea.gml"; //NO VA
616
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RoadArea (copia).gml"; //NO VA
617
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RoadSurfaceCategory.gml"; //No tiene geometr?as
618
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/FunctionalRoadClass.gml"; //No tiene geometr?as
619
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/ConditionOfFacility.gml"; //No tiene geometr?as
620
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RoadWidth.gml"; //No tiene geometr?as
621
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/VerticalPosition.gml"; //No tiene geometr?as
622
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/sk/RoadLink.gml"; //Hay 2 geometr?as, Curve y Multicurve
623

    
624

    
625

    
626
        String gmlfile = XMLFILE1;
627
        File idxFile = new File(FilenameUtils.removeExtension(gmlfile)+".gmlidx");
628
        if(idxFile.exists()){
629
            idxFile.delete();
630
        }
631
        File gfsFile = new File(FilenameUtils.removeExtension(gmlfile)+".gfs");
632
        if(gfsFile.exists()){
633
            gfsFile.delete();
634
        }
635
        GfsFile gfs = new GfsFile();
636
        gfs.fetch(new File(gmlfile));
637
        gfs.save(gfsFile);
638
//        return;
639
        XMLFileAsList gml = new XMLFileAsList(
640
                new File(gmlfile), 
641
                new File(FilenameUtils.removeExtension(gmlfile)+".gmlidx"), 
642
//                StandardCharsets.ISO_8859_1, 
643
                StandardCharsets.UTF_8, 
644
                gfs.getBaseElementPath(),
645
                gfs.getGeometryElementPaths(),
646
                gfs.getPropertiesPaths()
647
        );
648
        System.out.println("File: "+gmlfile);
649
        for (int i = 0; i < gml.size(); i++) {
650
            List<String> item = gml.get(i);
651
            System.out.println("RECORD "+i+":"+item);
652
        }
653
        System.out.println(StringUtils.join(gfs.getPropertiesPaths(), "\n"));
654
        System.out.println("Geometries:\n"+StringUtils.join(gfs.getGeometryElementPaths(), "\n"));
655
    }
656
}