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 / StructureExtractorImpl.java @ 47655

History | View | Annotate | Download (10 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.File;
9
import java.io.FileNotFoundException;
10
import java.io.IOException;
11
import java.io.InputStream;
12
import java.io.Reader;
13
import java.nio.charset.Charset;
14
import java.util.ArrayList;
15
import java.util.List;
16
import java.util.Locale;
17
import javax.xml.parsers.SAXParser;
18
import javax.xml.parsers.SAXParserFactory;
19
import org.apache.commons.lang3.StringUtils;
20
import org.apache.tika.utils.CharsetUtils;
21
import org.gvsig.fmap.dal.DALLocator;
22
import org.gvsig.fmap.dal.DataManager;
23
import org.gvsig.fmap.dal.store.gml.virtualrows.xmlinfo.XMLAttributeInfoImpl;
24
import org.gvsig.fmap.dal.store.gml.virtualrows.xmlinfo.XMLInfoImpl;
25
import org.gvsig.tools.ToolsLocator;
26
import org.gvsig.tools.i18n.I18nManager;
27
import org.gvsig.tools.task.SimpleTaskStatus;
28
import org.slf4j.Logger;
29
import org.slf4j.LoggerFactory;
30
import org.xml.sax.Attributes;
31
import org.xml.sax.InputSource;
32
import org.xml.sax.Locator;
33
import org.xml.sax.SAXException;
34
import org.xml.sax.helpers.DefaultHandler;
35

    
36
/**
37
 *
38
 * @author jjdelcerro
39
 */
40
public class StructureExtractorImpl { //implements StructureExtractor {
41

    
42
    private static final Logger LOGGER = LoggerFactory.getLogger(StructureExtractorImpl.class);
43

    
44
    @SuppressWarnings("UseSpecificCatch")
45
    private void extractTags(XMLInfoImpl xmlinfo, Reader reader, SimpleTaskStatus status) {
46
        if( reader == null ) {
47
            throw new IllegalArgumentException("reader is null");
48
        }
49
        try {
50
            final DataManager dataManager = DALLocator.getDataManager();
51
            I18nManager i18n = ToolsLocator.getI18nManager();
52
            status.message(i18n.getTranslation("_Reading_xml")+" 1/5");
53
            status.setRangeOfValues(0, xmlinfo.getCountLines());
54
            
55
            SAXParserFactory spf = SAXParserFactory.newInstance();
56
            spf.setNamespaceAware(true);
57
            SAXParser saxParser = spf.newSAXParser();
58
            InputSource is = new InputSource(reader);
59
            
60
            List<String> path = new ArrayList<>();
61
            
62
            saxParser.parse(is, new DefaultHandler() {
63
                private Locator locator;
64
                int size;
65
                int refreshInterval = 1;
66
                StringBuilder chars = new StringBuilder();
67
                
68
                @Override
69
                public void setDocumentLocator(Locator locator) {
70
                    this.locator = locator;
71
                }
72
                
73
                @Override
74
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
75
                    int line = this.locator.getLineNumber();
76
                    int column = this.locator.getColumnNumber()-2-localName.length();
77

    
78
                    if(line % refreshInterval == 0) {
79
                        status.setCurValue(line);
80
                    }
81
                    
82
                    if(line > 100000){
83
                        refreshInterval = 10000;
84
                    } else if(line > 10000){
85
                        refreshInterval = 1000;
86
                    } else if(line > 1000){
87
                        refreshInterval = 100;
88
                    } else if(line > 100){
89
                        refreshInterval = 10;
90
                    }
91

    
92

    
93
                    String idvalue = dataManager.createUniqueID();
94
                    
95
                    path.add(localName);
96
                    String path_s = StringUtils.join(path, "/");
97
                    XMLAttributeInfoImpl info = xmlinfo.getTag(path_s);
98
                    if( info == null ) {
99
                        info = new XMLAttributeInfoImpl(xmlinfo.getLocale(), path_s, getNs(qName));
100
                        xmlinfo.addTag(info);
101
                        
102
                    }
103
                    XMLAttributeInfoImpl parentinfo = null;
104
                    if( path.size()>1 ) {
105
                        List<String> parentpath = path.subList(0, path.size()-1);
106
                        String parentpath_s = StringUtils.join(parentpath, "/");
107
                        parentinfo = xmlinfo.getTag(parentpath_s);
108
                        parentinfo.incrChildCount(localName);
109
                        parentinfo.setLastChildID(localName, idvalue);
110
                    }
111
                    
112
                    for (int i = 0; i < attributes.getLength(); i++) {
113
                        String name = attributes.getLocalName(i);                        
114
                        String value = attributes.getValue(i);
115
                        String idvalueChild = dataManager.createUniqueID();
116
                        XMLAttributeInfoImpl infoChild = xmlinfo.getTag(path_s+"/"+name);
117
                        if( infoChild == null ) {
118
                            infoChild = new XMLAttributeInfoImpl(xmlinfo.getLocale(), path_s+"/"+name, getNs(qName));
119
                            infoChild.setIsAttr(true);
120
                            xmlinfo.addTag(infoChild);
121
                        }
122
                        if(StringUtils.equalsIgnoreCase(name, "srsName")){
123
                            infoChild.setSrs(value);
124
                            if(parentinfo != null){
125
                                parentinfo.setSrs(value);
126
                            }
127
                        }
128
                        info.incrChildCount(infoChild.getName());
129
                        info.setLastChildID(infoChild.getName(), idvalueChild);
130
                        infoChild.addValue(value);
131
                    }
132
                    chars.setLength(0);
133
                }
134
                
135
                @Override
136
                public void endElement(String uri, String localName, String qName) throws SAXException {
137
                    int line = this.locator.getLineNumber();
138

    
139
//                    status.setCurValue(line);
140

    
141
                    String path_s = StringUtils.join(path, "/");
142
                    XMLAttributeInfoImpl info = xmlinfo.getTag(path_s);
143
                    if( info == null ) {
144
                        info = new XMLAttributeInfoImpl(xmlinfo.getLocale(), path_s, getNs(qName));
145
                        xmlinfo.addTag(info);
146
                    }
147

    
148
                    XMLAttributeInfoImpl parentinfo = null;
149
                    if( path.size()>1 ) {
150
                        List<String> parentpath = path.subList(0, path.size()-1);
151
                        String parentpath_s = StringUtils.join(parentpath, "/");
152
                        parentinfo = xmlinfo.getTag(parentpath_s);
153
                    }
154
                    
155
                    if( info.hasChilds() || (parentinfo != null && (parentinfo.getChildsCount(localName)>1))) {
156
                        String value = this.chars.toString();
157
                        if( StringUtils.isNotBlank(value) ) {
158
                            String name = info.getName()+"$v";                        
159
                            String idvalueChild = dataManager.createUniqueID();
160
                            XMLAttributeInfoImpl infoChild = xmlinfo.getTag(path_s+"/"+name);
161
                            if( infoChild == null ) {
162
                                infoChild = new XMLAttributeInfoImpl(xmlinfo.getLocale(), path_s+"/"+name, getNs(qName));
163
                                xmlinfo.addTag(infoChild);
164
                            }
165
                            info.incrChildCount(infoChild.getName());
166
                            info.setLastChildID(infoChild.getName(), idvalueChild);
167
                            infoChild.addValue(value);
168
                        }
169
                    } else {
170
                        String value = this.chars.toString();
171
                        info.addValue(value);
172
                    }
173
                    info.consolidateChildCounters();
174
                    path.remove(path.size()-1);
175
                    chars.setLength(0);
176
                }
177
                
178
                @Override
179
                public void characters(char[] ch, int start, int length) throws SAXException {
180
                    int line = this.locator.getLineNumber();
181

    
182
//                    status.setCurValue(line);
183
                    this.chars.append(ch, start, length);
184
                }
185
                
186
                
187
            });
188
        } catch (Exception ex) {
189
            throw new RuntimeException("Can't extract tags.", ex);
190
        }
191
    }
192
    
193
    public XMLInfoImpl extractStructure(File xml, Charset charset, Locale locale, SimpleTaskStatus status) throws FileNotFoundException, IOException {
194
        XMLInfoImpl xmlinfo = new XMLInfoImpl();
195
        xmlinfo.setLocale(locale);
196
        long count = XmlCommons.countLines(xml, charset, status);
197
        xmlinfo.setCountLines(count);
198
        InputSource is = XmlCommons.openReader(xml,charset);
199
        return extractStructure(is, xmlinfo, status);
200
    }
201
    
202
    public XMLInfoImpl extractStructure(InputStream xml, Charset charset, Locale locale, SimpleTaskStatus status) throws IOException  {
203
        XMLInfoImpl xmlinfo = new XMLInfoImpl();
204
        xmlinfo.setLocale(locale);
205
        xmlinfo.setCountLines(-1);
206
        InputSource is = XmlCommons.openReader(xml, charset);
207
        return extractStructure(is, xmlinfo, status);
208
    }
209
    
210
    public XMLInfoImpl extractStructure(Reader reader, Locale locale, SimpleTaskStatus status) {
211
        XMLInfoImpl xmlinfo = new XMLInfoImpl();
212
        xmlinfo.setLocale(locale);
213
        InputSource is = new InputSource(reader);
214
        return extractStructure(is, xmlinfo, status);
215
    }
216
    
217
    public XMLInfoImpl extractStructure(InputSource is, XMLInfoImpl xmlinfo, SimpleTaskStatus status) {
218
        
219
        if( xmlinfo.getCharset()==null ) {
220
            xmlinfo.setCharset(CharsetUtils.forName(is.getEncoding()));
221
        }
222
        
223
        extractTags(xmlinfo, is.getCharacterStream(), status);
224
        
225
        return xmlinfo;
226
    }
227
    
228
    private String getNs(String s){
229
        String[] ss = s.split(":");
230
        if(ss.length == 1){
231
            return null;
232
        }
233
        return ss[0];
234
    }
235
    
236
}