Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.xml2db / org.gvsig.xml2db.lib / org.gvsig.xml2db.lib.impl / src / main / java / org / gvsig / xml2db / lib / impl / CopyXML2dbImpl.java @ 47335

History | View | Annotate | Download (13.4 KB)

1
package org.gvsig.xml2db.lib.impl;
2

    
3
import java.io.File;
4
import java.io.InputStream;
5
import java.io.Reader;
6
import java.nio.charset.Charset;
7
import java.util.ArrayList;
8
import java.util.HashMap;
9
import java.util.List;
10
import java.util.Map;
11
import javax.xml.parsers.SAXParser;
12
import javax.xml.parsers.SAXParserFactory;
13
import org.apache.commons.io.FilenameUtils;
14
import org.apache.commons.lang3.StringUtils;
15
import org.apache.commons.lang3.mutable.MutableInt;
16
import org.gvsig.fmap.dal.DALLocator;
17
import org.gvsig.fmap.dal.DataManager;
18
import org.gvsig.fmap.dal.DataStoreParameters;
19
import org.gvsig.fmap.dal.feature.EditableFeature;
20
import org.gvsig.fmap.dal.feature.Feature;
21
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
22
import org.gvsig.fmap.dal.feature.FeatureStore;
23
import org.gvsig.fmap.dal.feature.FeatureType;
24
import org.gvsig.fmap.dal.feature.ForeingKey;
25
import org.gvsig.fmap.dal.store.jdbc.JDBCServerExplorerParameters;
26
import org.gvsig.fmap.dal.store.jdbc.JDBCStoreParameters;
27
import org.gvsig.fmap.dal.store.jdbc2.JDBCServerExplorer;
28
import org.gvsig.tools.dispose.DisposeUtils;
29
import org.gvsig.tools.task.SimpleTaskStatus;
30
import org.slf4j.Logger;
31
import org.slf4j.LoggerFactory;
32
import org.xml.sax.Attributes;
33
import org.xml.sax.InputSource;
34
import org.xml.sax.Locator;
35
import org.xml.sax.SAXException;
36
import org.xml.sax.helpers.DefaultHandler;
37

    
38
/**
39
 *
40
 * @author jjdelcerro
41
 */
42
@SuppressWarnings("UseSpecificCatch")
43
public class CopyXML2dbImpl {
44

    
45
    private static final Logger LOGGER = LoggerFactory.getLogger(CopyXML2dbImpl.class);
46
    
47
    private static class TableInfo {
48
        private final Map<String,TableInfo> tables;
49
        private final JDBCStoreParameters openStoreParams;
50
        private final String tableName;
51
        private FeatureStore store;
52
        private EditableFeature current_row;
53
        private int pkcounter;
54
        private EditableFeature last_row;
55
        
56
        
57
        private TableInfo(Map<String,TableInfo> tables, JDBCStoreParameters openStoreParams) {
58
            this.tables = tables;
59
            this.openStoreParams = openStoreParams;
60
            this.tableName = openStoreParams.getTable();
61
            this.pkcounter = 1;
62
        }
63
        
64
        public void close() {
65
            try {
66
                this.insert();
67
                if( this.store!=null ) {
68
                    System.out.println("###: close("+this.tableName+")");
69
                    this.store.finishEditing();
70
                    DisposeUtils.dispose(this.store);
71
                }
72
            } catch(Throwable t) {
73
                throw new RuntimeException("Can't close table '"+this.getTableName()+"'.", t);
74
            }
75
        }
76
        
77
        public String getTableName() {
78
            return this.tableName;
79
        }
80

    
81
        public FeatureStore getStore() {
82
            if( this.store == null ) {
83
                try {
84
                    System.out.println("###: create store("+this.tableName+")");
85
                    DataManager dataManager = DALLocator.getDataManager();                
86
                    this.store = (FeatureStore) dataManager.openStore(
87
                            this.openStoreParams.getProviderName(), 
88
                            openStoreParams
89
                    );
90
                    this.store.edit(FeatureStore.MODE_APPEND);
91
                } catch(Throwable t) {
92
                    throw new RuntimeException("Can't open and start edit store '"+this.getTableName()+"'.", t);
93
                }
94
            }
95
            return this.store;
96
        }
97
        
98
        public Feature current_row() {
99
            return this.current_row;
100
        }
101

    
102
        private void createRow() {
103
            try {
104
                FeatureStore theStore = this.getStore();
105
//                System.out.println("###: create row("+this.tableName+")");
106
                this.current_row = theStore.createNewFeature();
107
                this.last_row = this.current_row;
108
                FeatureType ft = this.current_row.getType();
109
                for (FeatureAttributeDescriptor attrdesc : ft) {
110
                    if( attrdesc.isPrimaryKey() ) {
111
                       this.set(attrdesc.getName(), this.pkcounter++);
112
                    } else if( attrdesc.isForeingKey() ) {
113
                        ForeingKey fk = attrdesc.getForeingKey();
114
                        TableInfo table = this.tables.get(fk.getTableName().toLowerCase());
115
                        if( table != null ) {
116
                            this.set(attrdesc.getName(), table.getPkValue());
117
                        }
118
                    }
119
                }
120
            } catch(Throwable t) {
121
                throw new RuntimeException("Can't create feature of store '"+this.getTableName()+"'.", t);
122
            }
123
        }
124

    
125
        private void set(String name, Object value) {
126
            if( this.current_row != null ) {
127
//                System.out.println("###: set("+this.tableName+", "+name+", "+Objects.toString(value)+")");
128
                try {
129
                    if( StringUtils.equalsIgnoreCase("CONDICION_METEO", name) ) {
130
                        System.out.println("CONDICION_METEO...");
131
                    }
132
                    this.current_row.set(name, value);
133
                } catch(RuntimeException ex) {
134
                    LOGGER.info("Can't set attribute '"+name+"' in "+ this.getStore().getName()); //, ex);
135
                    throw ex;
136
                }
137
            }
138
        }
139

    
140
        private void insert() {
141
            if( this.store!=null && this.current_row!=null ) {
142
                try {
143
                    
144
                    FeatureType ft = this.current_row.getType();
145
                    for (FeatureAttributeDescriptor attrdesc : ft) {
146
                        if( attrdesc.isForeingKey() ) {
147
                            ForeingKey fk = attrdesc.getForeingKey();
148
                            TableInfo table = this.tables.get(fk.getTableName().toLowerCase());
149
                            if( table != null ) {
150
                                if( current_row.isNull(attrdesc.getName())){
151
                                    this.set(attrdesc.getName(), table.getPkValue());
152
                                }
153
                            }
154
                        }
155
                    }
156
                    
157
//                    System.out.println("###: insert("+this.tableName+")");
158
                    this.store.insert(current_row);
159
                } catch(Throwable t) {
160
                    throw new RuntimeException("Can't insert feature into store '"+this.getTableName()+"'.", t);
161
                }
162
            }
163
            this.current_row = null;
164
        }
165

    
166
        private Object getPkValue() {
167
            if( this.last_row==null ) {
168
                return null;
169
            }
170
            FeatureAttributeDescriptor[] attrdescs = this.last_row.getType().getPrimaryKey();
171
            return this.last_row.get(attrdescs[0].getName());
172
        }
173
    }
174
    
175
    public void copyData(InputSource is, JDBCServerExplorerParameters dbparams, long countLines, SimpleTaskStatus taskStatus) {
176
        if( is == null || is.getCharacterStream()==null ) {
177
            throw new IllegalArgumentException("reader is null");
178
        }
179
        DataManager dataManager = DALLocator.getDataManager();                        
180
        JDBCServerExplorer explorer = null;
181
        try {
182
            explorer = (JDBCServerExplorer) dataManager.openServerExplorer(dbparams.getProviderName(), dbparams);
183
        } catch (Exception ex) {
184
            throw new IllegalArgumentException("Can't open target database", ex);
185
        }
186
        MutableInt line = new MutableInt(0);
187
        MutableInt column = new MutableInt(0);
188
        try {
189
            taskStatus.message("Coping...");
190
            taskStatus.setRangeOfValues(0, countLines);
191
            
192
            SAXParserFactory spf = SAXParserFactory.newInstance();
193
            spf.setNamespaceAware(true);
194
            SAXParser saxParser = spf.newSAXParser();
195
            
196
            List<String> path = new ArrayList<>();
197
            Map<String,TableInfo> tables = new HashMap<>();
198
            for (DataStoreParameters openStoreParams0 : explorer.list()) {
199
                JDBCStoreParameters openStoreParams = (JDBCStoreParameters) openStoreParams0;
200
                TableInfo table = new TableInfo(tables, openStoreParams);
201
                tables.put(table.getTableName().toLowerCase(), table);
202
            }
203
            
204
            saxParser.parse(is, new DefaultHandler() {
205
                private Locator locator;
206
                private StringBuilder valueBuilder;
207
                
208
                @Override
209
                public void setDocumentLocator(Locator locator) {
210
                    this.locator = locator;
211
                }
212
                
213
                @Override
214
                public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
215
                    line.setValue(this.locator.getLineNumber());
216
                    column.setValue(this.locator.getColumnNumber()-2-localName.length());
217

    
218
                    taskStatus.setCurValue(line.intValue());
219
                    try {
220
                        path.add(localName);
221
                        String path_s = StringUtils.join(path, "/");
222
                        String tableName1 = FilenameUtils.getBaseName(path_s).toLowerCase();
223
                        TableInfo table1 = tables.get(tableName1);
224
                        if( table1 != null ) {
225
                            table1.createRow();
226
                            for (int i = 0; i < attributes.getLength(); i++) {
227
                                String name = attributes.getLocalName(i);
228
                                String value = attributes.getValue(i);
229
                                table1.set(name, value);
230
                            }
231
                        }
232
                    } catch(Exception ex) {
233
                        LOGGER.warn("Can't process startElement (line "+line+", column "+column+")",ex);
234
                    }
235
                    this.valueBuilder = null;
236
                }
237
                
238
                @Override
239
                public void endElement(String uri, String localName, String qName) throws SAXException {
240
                    line.setValue(this.locator.getLineNumber());
241
                    column.setValue(this.locator.getColumnNumber()-2-localName.length());
242

    
243
                    taskStatus.setCurValue(line.intValue());
244
                    try {
245
                        String path_s = StringUtils.join(path, "/");
246
                        String tableName1 = FilenameUtils.getBaseName(path_s).toLowerCase();
247
                        TableInfo table1 = tables.get(tableName1);
248
                        if( table1 != null ) {
249
                            table1.insert();
250
                        } else if( path.size()>1 ) {
251
                            List<String> parentpath = path.subList(0, path.size()-1);
252
                            String parentpath_s = StringUtils.join(parentpath, "/");
253
                            String attrname = FilenameUtils.getBaseName(path_s);
254
//                            if( StringUtils.equalsIgnoreCase("CONDICION_FIRME", attrname) ) {
255
//                                System.out.println("CONDICION_FIRME...");
256
//                            }
257
                            String tableName2 = FilenameUtils.getBaseName(parentpath_s).toLowerCase();
258
                            TableInfo table2 = tables.get(tableName2);
259
                            if( table2!=null ) {
260
                                if( this.valueBuilder!=null ) {
261
                                    String value = StringUtils.trimToNull(this.valueBuilder.toString());  
262
                                    if( value != null ) {
263
                                        table2.set(attrname,value);
264
                                    }
265
                                }
266
                            }
267
                        }
268
                    } catch(Exception ex) {
269
                        LOGGER.warn("Can't process endElement (line "+line+", column "+column+")",ex);
270
                    }
271
                    this.valueBuilder = null;
272
                    path.remove(path.size()-1);
273
                }
274
                
275
                @Override
276
                public void characters(char[] ch, int start, int length) throws SAXException {
277
                    line.setValue(this.locator.getLineNumber());
278
                    taskStatus.setCurValue(line.intValue());
279

    
280
                    if( this.valueBuilder == null ) {
281
                        this.valueBuilder = new StringBuilder();
282
                    }
283
                    this.valueBuilder.append(ch, start, length);
284
                }
285
            });
286
            for (TableInfo table : tables.values() ) {
287
                table.close();
288
            }
289
        } catch (Exception ex) {
290
            throw new RuntimeException("Can't copy data (line "+line+", column "+column+").", ex);
291
        }
292
    }
293
    
294
    public void copyData(File xml, Charset charset, JDBCServerExplorerParameters dbparams, SimpleTaskStatus taskStatus) {
295
        long count = Xml2dbCommons.countLines(xml, charset, taskStatus);
296
        
297
        InputSource is = Xml2dbCommons.openReader(xml, charset);
298
        copyData(is, dbparams, count, taskStatus);
299
    }
300
    
301
    public void copyData(InputStream xml, Charset charset, JDBCServerExplorerParameters dbparams, SimpleTaskStatus taskStatus) {
302
        long count = Xml2dbCommons.countLines(xml, charset, taskStatus);
303
        InputSource is = Xml2dbCommons.openReader(xml, charset);
304
        copyData(is, dbparams, count, taskStatus);
305
    }
306
    
307
}