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.gml / src / main / java / org / gvsig / fmap / dal / store / gml / virtualrows / GfsFile.java @ 47678

History | View | Annotate | Download (28.8 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.BufferedWriter;
9
import java.io.File;
10
import java.io.FileWriter;
11
import java.io.IOException;
12
import java.util.ArrayList;
13
import java.util.Collection;
14
import java.util.Iterator;
15
import java.util.LinkedHashMap;
16
import java.util.List;
17
import java.util.Locale;
18
import java.util.Map;
19
import javax.xml.parsers.SAXParser;
20
import javax.xml.parsers.SAXParserFactory;
21
import org.apache.commons.collections4.map.LinkedMap;
22
import org.apache.commons.io.FilenameUtils;
23
import org.apache.commons.io.IOUtils;
24
import org.apache.commons.lang3.StringUtils;
25
import org.gvsig.fmap.dal.store.gml.virtualrows.GfsFile.PropertyDefn;
26
import org.gvsig.fmap.dal.store.gml.virtualrows.xmlinfo.XMLAttributeInfoImpl;
27
import org.gvsig.fmap.dal.store.gml.virtualrows.xmlinfo.XMLInfoImpl;
28
import org.gvsig.fmap.geom.Geometry;
29
import org.gvsig.fmap.geom.GeometryLocator;
30
import org.gvsig.fmap.geom.type.GeometryType;
31
import org.gvsig.tools.ToolsLocator;
32
import org.gvsig.tools.dataTypes.DataTypes;
33
import org.gvsig.tools.dataTypes.DataTypesManager;
34
import org.gvsig.tools.library.impl.DefaultLibrariesInitializer;
35
import org.gvsig.tools.task.SimpleTaskStatus;
36
import org.gvsig.tools.util.IsEmpty;
37
import org.gvsig.tools.util.Size;
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40
import org.xml.sax.Attributes;
41
import org.xml.sax.InputSource;
42
import org.xml.sax.Locator;
43
import org.xml.sax.SAXException;
44
import org.xml.sax.helpers.DefaultHandler;
45

    
46
/**
47
 *
48
 * @author fdiaz
49
 */
50
public class GfsFile implements Iterable<PropertyDefn>, IsEmpty, Size {
51

    
52
    private static final Logger LOGGER = LoggerFactory.getLogger(GfsFile.class);
53

    
54
    private static final String PROPERTY_NAME_SEPARATOR = "_";
55
    private static final String PROPERTY_PATH_SEPARATOR = "|";
56
    private static final String PROPERTY_ATTRIBUTE_SEPARATOR = "@";
57

    
58
    public static class PropertyDefn {
59
        private String name;
60
        private String elementPath;
61
        private int type;
62
        private int width;
63
        private boolean isAttr;
64

    
65
        public PropertyDefn() {
66
        }
67
        
68
        public PropertyDefn(String name, String elementPath, int type, int width, boolean isAttr) {
69
            this.name = name;
70
            this.elementPath = elementPath;
71
            this.type = type;
72
            this.width = width;
73
            this.isAttr = isAttr;
74
        }
75

    
76
        public String getName() {
77
            return name;
78
        }
79

    
80
        public void setName(String name) {
81
            this.name = name;
82
        }
83

    
84
        public String getElementPath() {
85
            return elementPath;
86
        }
87
        
88
        public void setElementPath(String elementPath) {
89
            this.elementPath = elementPath;
90
        }
91

    
92
        public int getType() {
93
            return type;
94
        }
95

    
96
        public void setType(int type) {
97
            this.type = type;
98
        }
99

    
100
        public int getWidth() {
101
            return width;
102
        }
103

    
104
        public void setWidth(int width) {
105
            this.width = width;
106
        }
107

    
108
        public boolean isAttr() {
109
            return isAttr;
110
        }
111
        
112
        public void setIsAttr(boolean b) {
113
            this.isAttr = b;
114
        }
115

    
116
        @Override
117
        public boolean equals(Object obj) {
118
            if(!(obj instanceof PropertyDefn)) {
119
                return false;
120
            }
121
            PropertyDefn other = (PropertyDefn)obj;
122
            if(!StringUtils.equals(this.getName(), other.getName())){
123
                return false;
124
            }
125
            if(!StringUtils.equals(this.getElementPath(), other.getElementPath())){
126
                return false;
127
            }
128
            if(this.getType()!=other.getType()){
129
                return false;
130
            }
131
            if(this.getWidth()!=other.getWidth()){
132
                return false;
133
            }
134
            if(this.isAttr()!=other.isAttr()){
135
                return false;
136
            }
137
            return true;
138
        }
139
    }
140
    public static class GeometryPropertyDefn extends PropertyDefn {
141

    
142
        private String srs;
143
        private String geometryTypeName;
144
        private int dimensions;
145

    
146
        public GeometryPropertyDefn() {
147
            this.dimensions = 2;
148
        }
149
        
150
        public GeometryPropertyDefn(String name, String elementPath, String geometryTypeName, int dimensions, String srs) {
151
            super(name, elementPath, Geometry.TYPES.GEOMETRY, 0, false);
152
            this.srs = srs;
153
            this.geometryTypeName = geometryTypeName;
154
            this.dimensions = dimensions;
155
        }
156

    
157
        public String getSrs() {
158
            return srs;
159
        }
160

    
161
        public void setSrs(String srs) {
162
            this.srs = srs;
163
        }
164

    
165
        public String getGeometryTypeName() {
166
            return geometryTypeName;
167
        }
168

    
169
        public void setGeometryTypeName(String geometryTypeName) {
170
            this.geometryTypeName = geometryTypeName;
171
        }
172
        
173
        public GeometryType getGeometryType() {
174
            
175
            try {
176
                int gtype = Geometry.TYPES.GEOMETRY;
177
                int gsubType = Geometry.SUBTYPES.GEOM2D;
178
                switch(this.geometryTypeName.toUpperCase()){
179
                    case "POINT":
180
                        gtype = Geometry.TYPES.POINT;
181
                        break;
182
                    case "MULTIPOINT":
183
                        gtype = Geometry.TYPES.MULTIPOINT;
184
                        break;
185
                    case "LINESTRING":
186
                        gtype = Geometry.TYPES.LINE;
187
                        break;
188
                    case "POLYGON":
189
                        gtype = Geometry.TYPES.POLYGON;
190
                        break;
191
                    case "MULTIPOLYGON":
192
                        gtype = Geometry.TYPES.MULTIPOLYGON;
193
                        break;
194
                    case "SOLID":
195
                        gtype = Geometry.TYPES.MULTIPOLYGON;
196
                        gsubType = Geometry.SUBTYPES.GEOM3D;
197
                        break;
198
                    case "SURFACE":
199
                        gtype = Geometry.TYPES.POLYGON;
200
                        break;
201
                    case "MULTISURFACE":
202
                        gtype = Geometry.TYPES.MULTIPOLYGON;
203
                        break;
204
                    case "COMPOSITESURFACE":
205
                        gtype = Geometry.TYPES.MULTIPOLYGON;
206
                        break;
207
                    case "CURVE":
208
                        gtype = Geometry.TYPES.LINE;
209
                        break;
210
                    case "MULTICURVE":
211
                        gtype = Geometry.TYPES.MULTILINE;
212
                        break;
213
                }
214
                switch (this.dimensions) {
215
                    case 2:
216
                        gsubType = Geometry.SUBTYPES.GEOM2D;
217
                        break;
218
                    case 3:
219
                        gsubType = Geometry.SUBTYPES.GEOM3D;
220
                        break;
221
                }
222
                return GeometryLocator.getGeometryManager().getGeometryType(gtype, gsubType);
223
            } catch (Throwable t) {
224
                throw new RuntimeException("Can't get geometry type", t);
225
            }
226

    
227
        }
228

    
229
        public int getDimensions() {
230
            return dimensions;
231
        }
232

    
233
        public void setDimensions(int dimensions) {
234
            this.dimensions = dimensions;
235
        }
236
        
237
        
238
        
239
        
240
    }
241
    
242
    private String name;
243
    private String baseElementPath;
244
    private Map<String, PropertyDefn> properties;
245
    private Map<String, GeometryPropertyDefn> geometries;
246
    private int gmlVersion;
247

    
248
    public String getName() {
249
        return name;
250
    }
251

    
252
    public void setName(String name) {
253
        this.name = name;
254
    }
255

    
256
    public List<String> getGeometryElementPaths() {
257
        List<String> result = new ArrayList<>();
258
        for (GeometryPropertyDefn geometry : geometries.values()) {
259
            result.add(geometry.getElementPath().replace(PROPERTY_PATH_SEPARATOR, "/"));
260
        }
261
        return result;
262
    }
263
    
264
    public Collection<GeometryPropertyDefn> getGeometryElements() {
265
        return geometries.values();
266
    }
267

    
268
    private String getGeometryElementName(String path) {
269
        String theName = FilenameUtils.getBaseName(path);
270
        for (int i = 0; i < geometries.size(); i++) {
271
            String geometryElementPath = geometries.get(i).getElementPath();
272
            if(StringUtils.equals(path, geometryElementPath)){
273
                return theName+i;
274
            }
275
        }
276
        return theName;
277
    }
278

    
279
    public String getBaseElementPath() {
280
        return baseElementPath;
281
    }
282

    
283
    public void setBaseElementPath(String baseElementPath) {
284
        this.baseElementPath = baseElementPath;
285
    }
286
    
287
    private String findBaseElementPath(XMLInfoImpl xmlinfo) {
288
        String possibleMemberPath = null;
289
        for (String path : xmlinfo.getTagsPaths()) {
290
            XMLAttributeInfoImpl tag = xmlinfo.getTag(path);
291
            
292
            if (StringUtils.isBlank(possibleMemberPath)
293
                    && !tag.isAttr() 
294
                    && !StringUtils.equalsIgnoreCase(tag.getNs(), "gml")
295
                    && !StringUtils.equalsIgnoreCase(path, "FeatureCollection/boundedBy")
296
                    ) {
297
                
298
                String[] ss = path.split("/");
299
                if(ss.length == 2){
300
                    possibleMemberPath = path;
301
                }
302
            }
303
            if (path.equalsIgnoreCase("FeatureCollection/member")) {
304
                return path;
305
            } else if (path.equalsIgnoreCase("FeatureCollection/featureMember")) {
306
                return path;
307
            }
308
        }
309
        return possibleMemberPath;
310
    }
311

    
312
    private Map<String,GeometryPropertyDefn> findGeometryElements(XMLInfoImpl xmlinfo) {
313
        Map<String,GeometryPropertyDefn> result = new LinkedHashMap<>();
314
        List<String> paths = new ArrayList<>();
315
        for (String path : xmlinfo.getTagsPaths()) {
316
            XMLAttributeInfoImpl tag = xmlinfo.getTag(path);
317
            paths.add(path);
318
        }
319
        for (int i = 0; i < paths.size(); i++) {
320
            String path = paths.get(i);
321
            XMLAttributeInfoImpl tag = xmlinfo.getTag(path);
322
            if(i == paths.size()-1){
323
                continue;
324
            }
325
            if(tag.isAttr()){
326
                continue;
327
            }
328
            XMLAttributeInfoImpl nextTag = xmlinfo.getTag(paths.get(i+1));
329

    
330
            String p = null;
331
            
332
            switch(nextTag.getName().toUpperCase()){
333
                case "POINT":
334
                case "MULTIPOINT":
335
                case "LINESTRING":
336
                    p=path;
337
                    this.gmlVersion = 0;
338
                    break;
339

    
340
                case "POLYGON":
341
                case "MULTIPOLYGON":
342
                    p=path;
343
                    this.gmlVersion = 2;
344
                    break;
345
                case "SOLID":
346
                case "SURFACE":
347
                case "MULTISURFACE":
348
                case "COMPOSITESURFACE":
349
                case "CURVE":
350
                case "MULTICURVE":
351
                    p=path;
352
                    this.gmlVersion = 3;
353
            }
354
            if(p!=null){
355
                int dims = 2;
356
                for (int i2 = 0; i2 < paths.size(); i2++) {
357
                    String path2 = paths.get(i2);
358
                    if(StringUtils.startsWith(path2, path)){
359
                        if(StringUtils.endsWith(path2, "srsDimension")){
360
                            XMLAttributeInfoImpl tag2 = xmlinfo.getTag(path2);
361
                            String s = tag2.getFirstValue();
362
                            if(StringUtils.isNotBlank(s)){
363
                                int n = Integer.parseInt(s);
364
                                if(n>1 && n<=3){
365
                                    dims = n;
366
                                }
367
                            }
368
                            break;
369
                        }
370
                    }
371
                }
372

    
373
                if(p.startsWith(baseElementPath + "/")) {
374
                    p = p.substring(baseElementPath.length() + 1);
375
                }
376
                for (GeometryPropertyDefn geom : result.values()) {
377
                    if(StringUtils.startsWithIgnoreCase(p, geom.getElementPath())){
378
                        p = null;
379
                        break;
380
                    }
381
                }
382
                if (p != null) {
383
                    result.put(
384
                        tag.getName(),
385
                        new GeometryPropertyDefn(
386
                            tag.getName(),
387
                            p,
388
                            nextTag.getName().toUpperCase(),
389
                            dims,
390
                            nextTag.getSrs()
391
                        )
392
                    );
393
                }
394
            }
395
        }
396
        
397
        if(result.isEmpty()){
398
            return null;
399
        }
400
        return result;
401
    }
402
    
403
    @Override
404
    public String toString() {
405
        try {
406
            DataTypesManager datatypesManager = ToolsLocator.getDataTypesManager();
407
            StringBuilder builder = new StringBuilder();
408
            builder.append("<GMLFeatureClassList>\n"
409
                    + "  <GMLFeatureClass>\n"
410
                    + "    <Name>"+getName()+"</Name>\n"
411
                    + "    <ElementPath>"+getBaseElementPath()+"</ElementPath>\n"
412
            );
413
            if(geometries != null){
414
                for (GeometryPropertyDefn property : geometries.values()) {
415
                    builder.append("    <GeomPropertyDefn>\n");
416
                    builder.append("      <Name>");
417
                    builder.append(property.getName());
418
                    builder.append( "</Name>\n");
419

    
420
                    builder.append("      <ElementPath>");
421
                    builder.append(property.getElementPath());
422
                    builder.append("</ElementPath>\n");
423

    
424
                    builder.append("      <Type>");
425
                    builder.append(property.getGeometryTypeName());
426
                    builder.append("</Type>\n");
427

    
428
                    builder.append("      <Dimensions>");
429
                    builder.append(property.getDimensions());
430
                    builder.append("</Dimensions>\n");
431

    
432
                    builder.append("      <Srs>");
433
                    builder.append(property.getSrs());
434
                    builder.append("</Srs>\n");
435

    
436
                    builder.append("    </GeomPropertyDefn>\n");
437

    
438
                }
439
            }
440
            for (PropertyDefn property : properties.values()) {
441
                int type = property.getType();
442
                String propertyType = datatypesManager.getTypeName(type);
443

    
444
                builder.append("    <PropertyDefn>\n");
445
                builder.append("      <Name>");
446
                builder.append(property.getName());
447
                builder.append( "</Name>\n");
448

    
449
                builder.append("      <ElementPath>");
450
                builder.append(property.getElementPath());
451
                
452
                if (property.isAttr()) {
453
                    //cambiamos el ?ltimo | por @
454
                    int lastIndex = builder.lastIndexOf(PROPERTY_PATH_SEPARATOR);
455
                    builder.replace(lastIndex, PROPERTY_PATH_SEPARATOR.length() + lastIndex, PROPERTY_ATTRIBUTE_SEPARATOR);
456
                }
457

    
458
                builder.append("</ElementPath>\n");
459
                builder.append("      <Type>");
460
                builder.append(propertyType);
461
                builder.append("</Type>\n");
462
                if(type == DataTypes.STRING){
463
                    builder.append("      <Width>");
464
                    builder.append(property.getWidth());
465
                    builder.append("</Width>\n");
466
                }
467
                builder.append("    </PropertyDefn>\n");
468

    
469
            }
470

    
471
            builder.append("  </GMLFeatureClass>\n"
472
                    + "</GMLFeatureClassList>");
473
            
474
            return builder.toString();
475
        } catch (Exception ex) {
476
            LOGGER.warn("Can't generate gfs file", ex);
477
            return null;
478
        }
479
    }
480
    
481
    public void fetch(File gmlFile) {
482
        this.properties = new LinkedMap<>();
483
        SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("GML");
484
        status.setAutoremove(true);
485
        try {
486
            status.add();
487
            StructureExtractorImpl extractor = new StructureExtractorImpl();
488
             //Ojo con defaultCharset
489
            XMLInfoImpl xmlinfo = extractor.extractStructure(gmlFile, null, Locale.getDefault(), status);
490
            
491
            
492
            this.name = FilenameUtils.getBaseName(gmlFile.getName());
493
            
494
            this.baseElementPath = findBaseElementPath(xmlinfo);
495
            this.geometries = findGeometryElements(xmlinfo);
496

    
497
            for (String path : xmlinfo.getTagsPaths()) {
498
                XMLAttributeInfoImpl tag = xmlinfo.getTag(path);
499
                if (tag.hasChilds()) {
500
                    continue;
501
                }
502
                if (path.startsWith(baseElementPath+"/")) {
503
                    path = path.substring(baseElementPath.length()+1);
504
                } else {
505
                    continue;
506
                }
507
                boolean found = false;
508
                if(geometries != null){
509
                    for (GeometryPropertyDefn geometry : geometries.values()) {
510
                        if (path.equals(geometry.getElementPath())) {
511
                            found = true;
512
                            break;
513
                        }
514
                        if (path.startsWith(geometry.getElementPath()+"/")) {
515
                            if(tag.getNs().equalsIgnoreCase("gml")){
516
                                found = true;
517
                                break;
518
                            }
519
                        }
520
                    }
521
                    if(found){
522
                        continue;
523
                    }
524
                }
525
                if(path.indexOf('/') < 0 && tag.isAttr()){
526
                    continue;
527
                }
528

    
529
                String[] path_ss = path.split("/");
530
                String lastName = path_ss[path_ss.length -1];
531
                String propertyName = StringUtils.replace(path, "/", PROPERTY_NAME_SEPARATOR);
532
                if(StringUtils.endsWith(path, "$v")){
533
                    propertyName = StringUtils.replace(propertyName, PROPERTY_NAME_SEPARATOR+lastName, "");
534
                }
535
                String propertyPath = StringUtils.replace(path, "/", PROPERTY_PATH_SEPARATOR);
536
                if(StringUtils.endsWith(path, "$v")){
537
                    propertyPath = StringUtils.replace(propertyPath, PROPERTY_PATH_SEPARATOR+lastName, "");
538
                }
539
                this.properties.put(propertyName, new PropertyDefn(propertyName, propertyPath, tag.getType(), tag.getSize(), tag.isAttr()));
540

    
541
            }
542

    
543
            status.terminate();
544
        } catch (Exception ex) {
545
            LOGGER.warn("Can't generate gfs file", ex);
546
            status.abort();
547
            throw new RuntimeException("", ex);
548
        }
549
        
550
    }
551
    
552
    public void load(File gfsFile) {
553
        //https://gdal.org/drivers/vector/gml.html#syntax-of-gfs-files
554
        SimpleTaskStatus status = ToolsLocator.getTaskStatusManager().createDefaultSimpleTaskStatus("GML");
555
        status.setAutoremove(true);
556
        
557
        this.setName(null);
558
        this.setBaseElementPath(null);
559
        this.properties = new LinkedMap<>();
560
        this.geometries = new LinkedMap<>();
561
        
562
        
563
        try {
564
            status.add();
565
            
566
            InputSource is = XmlCommons.openReader(gfsFile,null);
567
            SAXParserFactory spf = SAXParserFactory.newInstance();
568
            spf.setNamespaceAware(true);
569
            List<String> path = new ArrayList<>();
570
            DataTypesManager dataTypesManager = ToolsLocator.getDataTypesManager();
571
            
572
            SAXParser saxParser = spf.newSAXParser();
573
            saxParser.parse(gfsFile, new DefaultHandler() {
574
                private Locator locator;
575
                int refreshInterval = 1;
576
                StringBuilder chars = new StringBuilder();
577
                PropertyDefn property = null;
578
                GeometryPropertyDefn geometry = null;
579
                
580
                @Override
581
                public void setDocumentLocator(Locator locator) {
582
                    this.locator = locator;
583
                }
584

    
585
                @Override
586
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
587
                    int line = this.locator.getLineNumber();
588

    
589
                    if(line % refreshInterval == 0) {
590
                        status.setCurValue(line);
591
                    }
592
                    
593
                    if(line > 100000){
594
                        refreshInterval = 10000;
595
                    } else if(line > 10000){
596
                        refreshInterval = 1000;
597
                    } else if(line > 1000){
598
                        refreshInterval = 100;
599
                    } else if(line > 100){
600
                        refreshInterval = 10;
601
                    }
602
                    
603
                    if(StringUtils.equals(localName, "PropertyDefn")){
604
                        property = new PropertyDefn();
605
                    } else if(StringUtils.equals(localName, "GeomPropertyDefn")){
606
                        geometry = new GeometryPropertyDefn();
607
                    }
608

    
609
                    path.add(localName);
610

    
611
                    chars.setLength(0);
612
                    
613
                }
614

    
615
                @Override
616
                public void endElement(String uri, String localName, String qName) throws SAXException {
617
                    if(StringUtils.equals(localName, "GeomPropertyDefn")){
618
                        geometries.put(this.geometry.getName(), geometry);
619
                        geometry = null;
620
                    } else if(StringUtils.equals(localName, "PropertyDefn")){
621
                        properties.put(this.property.getName(), property);
622
                        property = null;
623
                    } else if(this.property != null){
624
                        if(StringUtils.equals(localName, "Name")){
625
                            String value = this.chars.toString();
626
                            this.property.setName(value);
627
                        } else if(StringUtils.equals(localName, "ElementPath")){
628
                            String value = this.chars.toString();
629
                            if(value.indexOf(PROPERTY_ATTRIBUTE_SEPARATOR)>=0){
630
                                this.property.setIsAttr(true);
631
                                value = value.replace(PROPERTY_ATTRIBUTE_SEPARATOR, PROPERTY_PATH_SEPARATOR);
632
                            }
633
                            this.property.setElementPath(value);
634
                        } else if(StringUtils.equals(localName, "Type")){
635
                            String value = this.chars.toString();
636
                            this.property.setType(dataTypesManager.getType(value));
637
                        } else if(StringUtils.equals(localName, "Width")){
638
                            int value = Integer.valueOf(this.chars.toString());
639
                            this.property.setWidth(value);
640
                        }
641
                    } else if(this.geometry != null){
642
                        if(StringUtils.equals(localName, "Name")){
643
                            String value = this.chars.toString();
644
                            this.geometry.setName(value);
645
                        } else if(StringUtils.equals(localName, "ElementPath")){
646
                            String value = this.chars.toString();
647
                            this.geometry.setElementPath(value);
648
                        } else if(StringUtils.equals(localName, "Type")){
649
                            String value = this.chars.toString();
650
                            this.geometry.setGeometryTypeName(value);
651
                        } else if(StringUtils.equals(localName, "Dimensions")){
652
                            String value = this.chars.toString();
653
                            try {
654
                                this.geometry.setDimensions(Integer.parseInt(value));
655
                            } catch (Exception e) {
656
                                //Do nothing
657
                            }
658
                        } else if(StringUtils.equals(localName, "Srs")){
659
                            String value = this.chars.toString();
660
                            this.geometry.setSrs(value);
661
                        }
662
                        
663
                    } else {
664
                        if(StringUtils.equals(localName, "Name")){
665
                            String value = this.chars.toString();
666
                            setName(value);
667
                        } else if(StringUtils.equals(localName, "ElementPath")){
668
                            String value = this.chars.toString();
669
                            setBaseElementPath(value);
670
                        }
671
                    }
672

    
673
                    chars.setLength(0);
674
                }
675
                
676
                
677
                @Override
678
                public void characters(char[] ch, int start, int length) throws SAXException {
679
                    this.chars.append(ch, start, length);
680
                }
681

    
682
            }
683
            );
684
            status.terminate();
685

    
686
        } catch (Exception ex) {
687
            status.abort();
688
            throw new RuntimeException("Can't load gfs file '"+gfsFile.getAbsolutePath()+"'", ex);
689
        }
690
    }
691
    
692
    public void save(File gfsFile) throws IOException {
693
        BufferedWriter writer = null;
694
        try {
695
            writer = new BufferedWriter(new FileWriter(gfsFile));
696
            writer.append(this.toString());
697
        } finally {
698
            IOUtils.closeQuietly(writer);
699
        }
700
    }
701
    
702
    @Override
703
    public Iterator<PropertyDefn> iterator() {
704
        return this.properties.values().iterator();
705
    }
706

    
707
    @Override
708
    public boolean isEmpty() {
709
        return this.properties.isEmpty();
710
    }
711

    
712
    @Override
713
    public int size() {
714
        return this.properties.size();
715
    }
716
    
717
    public List<String> getPropertiesPaths() {
718
        List<String> res = new ArrayList<>();
719
        for (PropertyDefn property : this.properties.values()) {
720
            res.add(property.getElementPath().replace(PROPERTY_PATH_SEPARATOR, "/"));
721
        }
722
        return res;
723
    }
724
    
725
    public PropertyDefn get(String propertyName) {
726
        return this.properties.get(propertyName);        
727
    }
728
    
729
    @Override
730
    public boolean equals(Object obj) {
731
        if(!(obj instanceof GfsFile)) {
732
            return false;
733
        }
734
        GfsFile other = (GfsFile)obj;
735
        if(!this.name.equals(other.getName())){
736
            return false;
737
        }
738
        if(!this.baseElementPath.equals(other.getBaseElementPath())){
739
            return false;
740
        }
741
        
742
        if(this.size() != other.size()){
743
            return false;
744
        }
745
        for (PropertyDefn property : this) {
746
            PropertyDefn otherProperty = other.get(property.getName());
747
            if(!property.equals(otherProperty)){
748
                System.out.println("MY :"+property.getElementPath());
749
                System.out.println("OT :"+otherProperty.getElementPath());
750
                return false;
751
            }
752
            
753
        }
754
        for (GeometryPropertyDefn geometry : this.geometries.values()) {
755
            PropertyDefn otherGeometry = other.get(geometry.getName());
756
            if(!geometry.equals(otherGeometry)){
757
                System.out.println("MY :"+geometry.getElementPath());
758
                System.out.println("OT :"+otherGeometry.getElementPath());
759
                return false;
760
            }
761
            
762
        }
763
        
764
        return true;
765
    }
766
    
767
    
768
    
769
    public static void main(String[] args) throws Exception {
770
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/1075305YJ2717N.gml";
771
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/Recinto.gml";
772
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/FG-GML-543863-AdmBdry-20190101-0001.gml";
773
//        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/Municipis.gml";
774
        final String XMLFILE1 = "/home/fdiaz/projects/GMLS/navarra.gml";
775

    
776
        new DefaultLibrariesInitializer().fullInitialize();
777
        
778
        GfsFile gfs = new GfsFile();
779
        gfs.fetch(new File(XMLFILE1));
780
        System.out.println(gfs.toString());
781
        System.out.println(StringUtils.join(gfs.getPropertiesPaths(), "\n"));
782
        File gfsFile = new File(FilenameUtils.removeExtension(XMLFILE1)+".gfs");
783
        gfs.save(gfsFile);
784
        
785
        GfsFile gfs2 = new GfsFile();
786
        gfs2.load(gfsFile);
787
        System.out.println("=========================================");
788
        System.out.println(gfs.toString());
789
        System.out.println(StringUtils.join(gfs.getPropertiesPaths(), "\n"));
790
        System.out.println("Los gfs "+(gfs.equals(gfs2)?"S?":"NO")+" son iguales");
791
    }
792
}