Source Code Cross Referenced for XmlDataFileParser.java in  » Database-Client » SQL-Workbench » workbench » db » importer » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database Client » SQL Workbench » workbench.db.importer 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * XmlDataFileParser.java
003:         *
004:         * This file is part of SQL Workbench/J, http://www.sql-workbench.net
005:         *
006:         * Copyright 2002-2008, Thomas Kellerer
007:         * No part of this code maybe reused without the permission of the author
008:         *
009:         * To contact the author please send an email to: support@sql-workbench.net
010:         *
011:         */
012:        package workbench.db.importer;
013:
014:        import java.io.File;
015:        import java.io.IOException;
016:        import java.io.Reader;
017:        import java.sql.SQLException;
018:        import java.sql.Types;
019:        import java.util.ArrayList;
020:        import java.util.Collections;
021:        import java.util.Iterator;
022:        import java.util.LinkedList;
023:        import java.util.List;
024:        import javax.xml.parsers.SAXParser;
025:        import javax.xml.parsers.SAXParserFactory;
026:        import org.xml.sax.Attributes;
027:        import org.xml.sax.InputSource;
028:        import org.xml.sax.SAXException;
029:        import org.xml.sax.SAXParseException;
030:        import org.xml.sax.helpers.DefaultHandler;
031:        import workbench.db.ColumnIdentifier;
032:        import workbench.db.TableIdentifier;
033:        import workbench.db.WbConnection;
034:        import workbench.db.exporter.XmlRowDataConverter;
035:        import workbench.db.importer.modifier.ImportValueModifier;
036:        import workbench.interfaces.JobErrorHandler;
037:        import workbench.resource.ResourceMgr;
038:        import workbench.util.ExceptionUtil;
039:        import workbench.interfaces.ImportFileParser;
040:        import workbench.log.LogMgr;
041:        import workbench.util.FileUtil;
042:        import workbench.util.MessageBuffer;
043:        import workbench.util.SqlUtil;
044:        import workbench.util.StringUtil;
045:        import workbench.util.ValueConverter;
046:        import workbench.util.WbFile;
047:        import workbench.util.WbStringTokenizer;
048:
049:        /**
050:         *
051:         * @author  support@sql-workbench.net
052:         */
053:        public class XmlDataFileParser extends DefaultHandler implements 
054:                RowDataProducer, ImportFileParser {
055:            private String sourceDirectory;
056:            private File inputFile;
057:            private String tableName;
058:            private String tableNameFromFile;
059:
060:            private int currentRowNumber = 1;
061:            private int colCount;
062:            private int realColCount;
063:
064:            private List<ColumnIdentifier> columnsToImport;
065:            private ColumnIdentifier[] columns;
066:            private String encoding = "UTF-8";
067:
068:            private Object[] currentRow;
069:            private RowDataReceiver receiver;
070:            private boolean ignoreCurrentRow = false;
071:            private boolean abortOnError = false;
072:            private boolean checkDependencies = false;
073:            private boolean[] warningAdded;
074:            private JobErrorHandler errorHandler;
075:            private boolean verboseFormat = true;
076:            private boolean formatKnown = false;
077:            private String missingColumn;
078:            private MessageBuffer messages;
079:            private String extensionToUse;
080:
081:            private int currentColIndex = 0;
082:            private int realColIndex = 0;
083:            private long columnLongValue = 0;
084:            private String columnDataFile = null;
085:            private boolean isNull = false;
086:            private StringBuilder chars;
087:            private boolean keepRunning;
088:            private boolean regularStop;
089:            private String rowTag = XmlRowDataConverter.LONG_ROW_TAG;
090:            private String columnTag = XmlRowDataConverter.LONG_COLUMN_TAG;
091:
092:            private boolean hasErrors = false;
093:            private boolean hasWarnings = false;
094:
095:            private SAXParser saxParser;
096:            private ImportFileHandler fileHandler = new ImportFileHandler();
097:            private WbConnection dbConn;
098:
099:            private ValueConverter converter = new ValueConverter();
100:            private ImportValueModifier valueModifier;
101:
102:            public XmlDataFileParser() {
103:                SAXParserFactory factory = SAXParserFactory.newInstance();
104:                factory.setValidating(false);
105:                try {
106:                    saxParser = factory.newSAXParser();
107:                } catch (Exception e) {
108:                    // should not happen!
109:                    LogMgr.logError("XmlDataFileParser.<init>",
110:                            "Error creating XML parser", e);
111:                }
112:            }
113:
114:            public XmlDataFileParser(File inputFile) {
115:                this ();
116:                this .inputFile = inputFile;
117:            }
118:
119:            public void setValueModifier(ImportValueModifier mod) {
120:                this .valueModifier = mod;
121:            }
122:
123:            public ImportFileHandler getFileHandler() {
124:                return this .fileHandler;
125:            }
126:
127:            public String getColumns() {
128:                return StringUtil
129:                        .listToString(this .columnsToImport, ',', false);
130:            }
131:
132:            public String getLastRecord() {
133:                return null;
134:            }
135:
136:            public void setCheckDependencies(boolean flag) {
137:                this .checkDependencies = flag;
138:            }
139:
140:            public boolean hasErrors() {
141:                return this .hasErrors;
142:            }
143:
144:            public boolean hasWarnings() {
145:                if (this .hasWarnings)
146:                    return true;
147:                if (this .warningAdded == null)
148:                    return false;
149:                for (boolean b : warningAdded) {
150:                    if (b)
151:                        return true;
152:                }
153:                return false;
154:            }
155:
156:            public void setValueConverter(ValueConverter convert) {
157:                this .converter = convert;
158:            }
159:
160:            public void setColumns(String columnList) throws SQLException {
161:                if (columnList != null && columnList.trim().length() > 0) {
162:                    WbStringTokenizer tok = new WbStringTokenizer(columnList,
163:                            ",");
164:                    this .columnsToImport = new ArrayList<ColumnIdentifier>();
165:                    while (tok.hasMoreTokens()) {
166:                        String col = tok.nextToken();
167:                        if (col == null)
168:                            continue;
169:                        col = col.trim();
170:                        if (col.length() == 0)
171:                            continue;
172:                        ColumnIdentifier ci = new ColumnIdentifier(col);
173:                        this .columnsToImport.add(ci);
174:                    }
175:                } else {
176:                    this .columnsToImport = null;
177:                }
178:                checkImportColumns();
179:            }
180:
181:            /**	 Define the columns to be imported
182:             */
183:            public void setColumns(List<ColumnIdentifier> cols)
184:                    throws SQLException {
185:                if (cols != null && cols.size() > 0) {
186:                    this .columnsToImport = new ArrayList<ColumnIdentifier>(cols
187:                            .size());
188:                    Iterator<ColumnIdentifier> itr = cols.iterator();
189:                    while (itr.hasNext()) {
190:                        ColumnIdentifier id = itr.next();
191:                        if (!id.getColumnName().equals(
192:                                RowDataProducer.SKIP_INDICATOR)) {
193:                            this .columnsToImport.add(id);
194:                        }
195:                    }
196:                } else {
197:                    this .columnsToImport = null;
198:                }
199:                checkImportColumns();
200:            }
201:
202:            public void setConnection(WbConnection conn) {
203:                this .dbConn = conn;
204:            }
205:
206:            /**
207:             * Check if all columns defined for the import (through the table definition
208:             * as part of the XML file, or passed by the user on the command line) are
209:             * actually available in the target table. 
210:             * For this all columns of the target table are retrieved from the database,
211:             * and each column that has been defined through setColumns() is checked 
212:             * whether it exists there. Columns that are not found are dropped from
213:             * the list of import columns
214:             * If continueOnError == true, a warning is added to the messages. Otherwise
215:             * an Exception is thrown.
216:             */
217:            public void checkTargetColumns() throws SQLException {
218:                if (this .dbConn == null)
219:                    return;
220:                if (this .columns == null)
221:                    return;
222:                TableIdentifier tbl = new TableIdentifier(
223:                        this .tableName == null ? this .tableNameFromFile
224:                                : this .tableName);
225:                if (!this .dbConn.getMetadata().tableExists(tbl)) {
226:                    String msg = ResourceMgr.getFormattedString(
227:                            "ErrImportTableNotFound", tbl.getTableName());
228:                    this .messages.append(msg);
229:                    this .messages.appendNewLine();
230:                    throw new SQLException("Table '" + tbl.getTableName()
231:                            + "' not found!");
232:                }
233:                List<ColumnIdentifier> tableCols = this .dbConn.getMetadata()
234:                        .getTableColumns(tbl);
235:                List<ColumnIdentifier> validCols = new LinkedList<ColumnIdentifier>();
236:
237:                for (int colIndex = 0; colIndex < this .columns.length; colIndex++) {
238:                    int i = tableCols.indexOf(this .columns[colIndex]);
239:
240:                    if (i != -1) {
241:                        // Use the column definition retrieved from the database
242:                        // to make sure we are using the correct data types when converting the input (String) values
243:                        // this is also important to get quoting of column names
244:                        // with special characters correctly (as this is handled by DbMetadata already
245:                        // but the columns retrieved from the XML file are not quoted correctly)
246:                        ColumnIdentifier tc = tableCols.get(i);
247:                        this .columns[colIndex] = tc;
248:                        validCols.add(tc);
249:                    } else {
250:                        String errorColumn = (this .columns[colIndex] != null ? this .columns[colIndex]
251:                                .getColumnName()
252:                                : "n/a");
253:                        String msg = ResourceMgr
254:                                .getString("ErrImportColumnNotFound");
255:                        msg = StringUtil.replace(msg, "%column%", errorColumn);
256:                        msg = StringUtil.replace(msg, "%table%", tbl
257:                                .getTableExpression());
258:                        this .messages.append(msg);
259:                        this .messages.appendNewLine();
260:                        if (this .abortOnError) {
261:                            this .hasErrors = true;
262:                            throw new SQLException("Column " + errorColumn
263:                                    + " not found in target table");
264:                        } else {
265:                            this .hasWarnings = true;
266:                            LogMgr.logWarning(
267:                                    "XmlDataFileParser.checkTargetColumns()",
268:                                    msg);
269:                        }
270:                    }
271:                }
272:
273:                // Make sure we are using the columns collected during the check
274:                if (validCols.size() != columns.length) {
275:                    this .columnsToImport = validCols;
276:                    this .realColCount = this .columnsToImport.size();
277:                }
278:            }
279:
280:            private void checkImportColumns() throws SQLException {
281:                if (this .columnsToImport == null) {
282:                    this .realColCount = this .colCount;
283:                    return;
284:                }
285:
286:                this .missingColumn = null;
287:
288:                try {
289:                    if (this .columns == null)
290:                        this .readXmlTableDefinition();
291:                } catch (Throwable e) {
292:                    LogMgr.logError("XmlDataFileParser.checkImportColumns()",
293:                            "Error reading table definition from XML file", e);
294:                    this .hasErrors = true;
295:                    throw new SQLException(
296:                            "Could not read table definition from XML file");
297:                }
298:
299:                for (ColumnIdentifier c : columnsToImport) {
300:                    if (!this .containsColumn(c)) {
301:                        this .missingColumn = c.getColumnName();
302:                        this .hasErrors = true;
303:                        throw new SQLException("Import column "
304:                                + c.getColumnName()
305:                                + " not present in input file!");
306:                    }
307:                }
308:                this .realColCount = this .columnsToImport.size();
309:            }
310:
311:            /**
312:             *	Returns the first column from the import columns
313:             *  that is not found in the import file
314:             *	@see #setColumns(String)
315:             *  @see #setColumns(List)
316:             */
317:            public String getMissingColumn() {
318:                return this .missingColumn;
319:            }
320:
321:            private boolean containsColumn(ColumnIdentifier col) {
322:                if (this .columns == null)
323:                    return false;
324:                for (int i = 0; i < this .columns.length; i++) {
325:                    if (this .columns[i].equals(col))
326:                        return true;
327:                }
328:                return false;
329:            }
330:
331:            public void setTableName(String aName) {
332:                this .tableName = aName;
333:            }
334:
335:            public List<ColumnIdentifier> getColumnsFromFile() {
336:                try {
337:                    if (this .columns == null)
338:                        this .readXmlTableDefinition();
339:                } catch (IOException e) {
340:                    return Collections.emptyList();
341:                } catch (SAXException e) {
342:                    return Collections.emptyList();
343:                }
344:                ArrayList<ColumnIdentifier> result = new ArrayList<ColumnIdentifier>(
345:                        this .columns.length);
346:                for (int i = 0; i < this .columns.length; i++) {
347:                    result.add(this .columns[i]);
348:                }
349:                return result;
350:            }
351:
352:            private void detectTagFormat() {
353:                try {
354:                    fileHandler.setMainFile(this .inputFile, this .encoding);
355:                    XmlTableDefinitionParser tableDef = new XmlTableDefinitionParser(
356:                            this .fileHandler);
357:                    detectTagFormat(tableDef);
358:                } catch (Exception e) {
359:                    LogMgr
360:                            .logError(
361:                                    "XmlDataFileParser",
362:                                    "Could not detect XML tag format. Assuming 'verbose'",
363:                                    e);
364:                    this .setUseVerboseFormat(true);
365:                }
366:            }
367:
368:            private void detectTagFormat(XmlTableDefinitionParser tableDef) {
369:                String format = tableDef.getTagFormat();
370:                if (format != null) {
371:                    if (XmlRowDataConverter.KEY_FORMAT_LONG.equals(format)) {
372:                        this .setUseVerboseFormat(true);
373:                    } else if (XmlRowDataConverter.KEY_FORMAT_SHORT
374:                            .equals(format)) {
375:                        this .setUseVerboseFormat(false);
376:                    }
377:                }
378:            }
379:
380:            private void readXmlTableDefinition() throws IOException,
381:                    SAXException {
382:                fileHandler.setMainFile(this .inputFile, this .encoding);
383:
384:                XmlTableDefinitionParser tableDef = new XmlTableDefinitionParser(
385:                        this .fileHandler);
386:                this .columns = tableDef.getColumns();
387:                this .colCount = this .columns.length;
388:                this .tableNameFromFile = tableDef.getTableName();
389:                this .warningAdded = new boolean[this .colCount];
390:                detectTagFormat(tableDef);
391:            }
392:
393:            public String getSourceFilename() {
394:                if (this .inputFile == null)
395:                    return null;
396:                return this .inputFile.getAbsolutePath();
397:            }
398:
399:            public void setSourceFile(File file) {
400:                this .sourceDirectory = null;
401:                this .inputFile = file;
402:            }
403:
404:            public void setSourceExtension(String ext) {
405:                this .extensionToUse = ext;
406:            }
407:
408:            public void setSourceDirectory(String dir) {
409:                File f = new File(dir);
410:                if (!f.isDirectory())
411:                    throw new IllegalArgumentException(dir
412:                            + " is not a directory");
413:                this .sourceDirectory = dir;
414:                this .inputFile = null;
415:            }
416:
417:            public String getSourceDirectory() {
418:                return this .sourceDirectory;
419:            }
420:
421:            public void setAbortOnError(boolean flag) {
422:                this .abortOnError = flag;
423:            }
424:
425:            private void processOneFile() throws Exception {
426:                this .keepRunning = true;
427:                this .regularStop = false;
428:
429:                // readTableDefinition relies on the fileHandler, so this 
430:                // has to be called after initializing the fileHandler
431:                if (this .columns == null)
432:                    this .readXmlTableDefinition();
433:                if (!this .formatKnown) {
434:                    detectTagFormat();
435:                }
436:
437:                if (this .columnsToImport == null) {
438:                    this .realColCount = this .colCount;
439:                } else {
440:                    this .realColCount = this .columnsToImport.size();
441:                }
442:
443:                // Re-initialize the reader in case we are reading from a ZIP archive
444:                // because readTableDefinition() can change the file handler
445:                this .fileHandler.setMainFile(this .inputFile, this .encoding);
446:
447:                this .messages = new MessageBuffer();
448:                this .sendTableDefinition();
449:                Reader in = null;
450:                boolean finished = false;
451:
452:                try {
453:                    in = this .fileHandler.getMainFileReader();
454:                    InputSource source = new InputSource(in);
455:                    saxParser.parse(source, this );
456:                } catch (ParsingInterruptedException e) {
457:                    if (this .regularStop) {
458:                        this .receiver.importFinished();
459:                    } else {
460:                        this .receiver.importCancelled();
461:                        this .hasErrors = true;
462:                    }
463:                    finished = true;
464:                } catch (Exception e) {
465:                    String msg = "Error during parsing of data row: "
466:                            + (this .currentRowNumber)
467:                            + ", column: "
468:                            + this .currentColIndex
469:                            + ", current data: "
470:                            + (this .chars == null ? "<n/a>" : "["
471:                                    + this .chars.toString() + "]")
472:                            + ", message: " + ExceptionUtil.getDisplay(e);
473:                    LogMgr
474:                            .logWarning("XmlDataFileParser.processOneFile()",
475:                                    msg);
476:                    this .messages.append(msg);
477:                    this .messages.appendNewLine();
478:                    this .receiver.tableImportError();
479:                    throw e;
480:                } finally {
481:                    FileUtil.closeQuitely(in);
482:                    if (!finished) {
483:                        this .receiver.importFinished();
484:                    }
485:                }
486:            }
487:
488:            private void reset() {
489:                messages = new MessageBuffer();
490:                tableName = null;
491:                tableNameFromFile = null;
492:                ignoreCurrentRow = false;
493:                currentColIndex = 0;
494:                realColIndex = 0;
495:                columnLongValue = 0;
496:                isNull = false;
497:                chars = null;
498:                columns = null;
499:                columnsToImport = null;
500:                keepRunning = true;
501:            }
502:
503:            private void processDirectory() throws Exception {
504:                File dir = new File(this .sourceDirectory);
505:                boolean verbose = this .verboseFormat;
506:                if (this .extensionToUse == null)
507:                    this .extensionToUse = ".xml";
508:
509:                FileNameSorter sorter = new FileNameSorter(this .dbConn, dir,
510:                        extensionToUse, new XmlTableNameResolver(encoding));
511:                List<WbFile> toProcess = null;
512:                if (this .checkDependencies) {
513:                    try {
514:                        toProcess = sorter.getSortedList();
515:                    } catch (CycleErrorException e) {
516:                        hasErrors = true;
517:                        LogMgr.logError("XmlDataFileParser.processDirectory()",
518:                                "Error when checking dependencies", e);
519:                        throw e;
520:                    }
521:                } else {
522:                    toProcess = sorter.getFiles();
523:                }
524:
525:                for (WbFile sourceFile : toProcess) {
526:                    if (!this .keepRunning)
527:                        break;
528:                    try {
529:                        this .inputFile = sourceFile;
530:                        this .reset();
531:
532:                        // readTableDefinition() might reset the verbose 
533:                        // flag if a new XML structure is used
534:                        // this ensures, that the flag specified by the 
535:                        // user will be used for files that do not have the 
536:                        // flag in the meta-data tag
537:                        this .verboseFormat = verbose;
538:                        this .processOneFile();
539:                    } catch (ParsingInterruptedException e) {
540:                        // cancel the import
541:                        break;
542:                    } catch (Exception e) {
543:                        if (this .abortOnError)
544:                            throw e;
545:                    }
546:                }
547:            }
548:
549:            public void start() throws Exception {
550:                this .hasErrors = false;
551:                this .hasWarnings = false;
552:                this .keepRunning = true;
553:
554:                this .receiver.setTableCount(-1); // clear multi-table flag in receiver
555:                this .receiver.setCurrentTable(-1);
556:
557:                try {
558:                    if (this .sourceDirectory == null) {
559:                        processOneFile();
560:                    } else {
561:                        processDirectory();
562:                    }
563:                } finally {
564:                    try {
565:                        this .fileHandler.done();
566:                    } catch (Throwable th) {
567:                    }
568:                }
569:            }
570:
571:            public void stop() {
572:                this .keepRunning = false;
573:                this .regularStop = true;
574:            }
575:
576:            public boolean isCancelled() {
577:                return !this .keepRunning && !regularStop;
578:            }
579:
580:            public void cancel() {
581:                this .keepRunning = false;
582:                this .regularStop = false;
583:            }
584:
585:            private void clearRowData() {
586:                for (int i = 0; i < this .realColCount; i++) {
587:                    this .currentRow[i] = null;
588:                }
589:                this .currentColIndex = 0;
590:                this .realColIndex = 0;
591:            }
592:
593:            public String getEncoding() {
594:                return this .encoding;
595:            }
596:
597:            public void setEncoding(String enc) {
598:                this .encoding = enc;
599:            }
600:
601:            public void setReceiver(RowDataReceiver aReceiver) {
602:                this .receiver = aReceiver;
603:            }
604:
605:            public void startDocument() throws SAXException {
606:                Thread.yield();
607:                if (!this .keepRunning)
608:                    throw new ParsingInterruptedException();
609:            }
610:
611:            public void endDocument() throws SAXException {
612:                Thread.yield();
613:                if (!this .keepRunning)
614:                    throw new ParsingInterruptedException();
615:            }
616:
617:            public void startElement(String namespaceURI, String sName,
618:                    String qName, Attributes attrs) throws SAXException {
619:                Thread.yield();
620:                if (!this .keepRunning)
621:                    throw new ParsingInterruptedException();
622:
623:                if (qName.equals(this .rowTag)) {
624:                    // row definition ended, start a new row
625:                    this .clearRowData();
626:                    this .chars = null;
627:                } else if (qName.equals(this .columnTag)) {
628:                    this .chars = new StringBuilder();
629:                    String attrValue = attrs
630:                            .getValue(XmlRowDataConverter.ATTR_LONGVALUE);
631:                    if (attrValue != null) {
632:                        try {
633:                            columnLongValue = Long.parseLong(attrValue);
634:                        } catch (NumberFormatException e) {
635:                            LogMgr.logError("XmlDataFileParser.startElement()",
636:                                    "Error converting longvalue", e);
637:                        }
638:                    }
639:                    attrValue = attrs.getValue(XmlRowDataConverter.ATTR_NULL);
640:                    this .isNull = "true".equals(attrValue);
641:                    columnDataFile = attrs
642:                            .getValue(XmlRowDataConverter.ATTR_DATA_FILE);
643:                } else {
644:                    this .chars = null;
645:                }
646:            }
647:
648:            public void endElement(String namespaceURI, String sName,
649:                    String qName) throws SAXException {
650:                if (!this .keepRunning)
651:                    throw new ParsingInterruptedException();
652:                if (qName.equals(this .rowTag)) {
653:                    if (!this .receiver.shouldProcessNextRow()) {
654:                        this .receiver.nextRowSkipped();
655:                    } else {
656:                        if (!this .ignoreCurrentRow) {
657:                            try {
658:                                this .sendRowData();
659:                            } catch (Exception e) {
660:                                // don't need to log the error as sendRowData() has already done that.
661:                                if (this .abortOnError)
662:                                    throw new ParsingInterruptedException();
663:                            }
664:                        }
665:                    }
666:                    this .ignoreCurrentRow = false;
667:                    this .currentRowNumber++;
668:                } else if (qName.equals(this .columnTag)) {
669:                    this .buildColumnData();
670:                    this .currentColIndex++;
671:                }
672:                this .chars = null;
673:            }
674:
675:            public void characters(char buf[], int offset, int len)
676:                    throws SAXException {
677:                Thread.yield();
678:                if (!this .keepRunning)
679:                    throw new ParsingInterruptedException();
680:                if (chars != null) {
681:                    this .chars.append(buf, offset, len);
682:                }
683:            }
684:
685:            /**	Only implemented to have even more possibilities for cancelling the import */
686:            public void ignorableWhitespace(char[] ch, int start, int length)
687:                    throws SAXException {
688:                Thread.yield();
689:                if (!this .keepRunning)
690:                    throw new ParsingInterruptedException();
691:            }
692:
693:            public void processingInstruction(String target, String data)
694:                    throws SAXException {
695:                Thread.yield();
696:                if (!this .keepRunning)
697:                    throw new ParsingInterruptedException();
698:            }
699:
700:            public void error(SAXParseException e) throws SAXParseException {
701:                String msg = "XML Parse error in line=" + e.getLineNumber()
702:                        + ",data-row=" + (this .currentRowNumber);
703:                LogMgr.logError("XmlDataFileParser.error()", msg, e);
704:                this .ignoreCurrentRow = true;
705:            }
706:
707:            public void fatalError(SAXParseException e)
708:                    throws SAXParseException {
709:                String msg = "Fatal XML parse error in line="
710:                        + e.getLineNumber() + ",data-row="
711:                        + (this .currentRowNumber)
712:                        + "\nRest of file will be ignored!";
713:                LogMgr.logError("XmlDataFileParser.fatalError()", msg, e);
714:                this .ignoreCurrentRow = true;
715:            }
716:
717:            // dump warnings too
718:            public void warning(SAXParseException err) throws SAXParseException {
719:                this .messages.append(ExceptionUtil.getDisplay(err));
720:                this .messages.appendNewLine();
721:                if (!this .keepRunning)
722:                    throw err;
723:            }
724:
725:            /**
726:             *	Creates the approriate column data object and puts it
727:             *	into rowData[currentColIndex]
728:             *  {@link workbench.util.ValueConverter} is not used because
729:             *  for most of the datatypes we have some special processing here
730:             *  Date and time can be initialized through the long value in the XML file
731:             *  Numeric types contain the actual class to be used {@link #createNumericType(String, String)}
732:             */
733:            private void buildColumnData() throws ParsingInterruptedException {
734:                if (this .columnsToImport != null
735:                        && !this .columnsToImport
736:                                .contains(this .columns[this .currentColIndex]))
737:                    return;
738:                this .currentRow[this .realColIndex] = null;
739:
740:                if (!this .receiver.shouldProcessNextRow())
741:                    return;
742:
743:                // the isNull flag will be set by the startElement method
744:                // as that is an attribute of the tag
745:                if (this .isNull) {
746:                    this .realColIndex++;
747:                    return;
748:                }
749:
750:                String value = this .chars.toString();
751:                if (this .valueModifier != null) {
752:                    value = this .valueModifier.modifyValue(
753:                            this .columns[this .realColIndex], value);
754:                }
755:
756:                int type = this .columns[this .realColIndex].getDataType();
757:                try {
758:                    if (SqlUtil.isCharacterType(type)) {
759:                        // if clobs are exported as external files, than we'll have a filename in the
760:                        // attribute (just like with BLOBS)
761:                        if (this .columnDataFile == null) {
762:                            this .currentRow[this .realColIndex] = value;
763:                        } else {
764:                            String fileDir = this .inputFile.getParent();
765:                            this .currentRow[this .realColIndex] = new File(
766:                                    fileDir, columnDataFile);
767:                        }
768:                    } else if (SqlUtil.isBlobType(type)) {
769:                        String fileDir = this .inputFile.getParent();
770:                        this .currentRow[this .realColIndex] = new File(fileDir,
771:                                columnDataFile);
772:                    } else if (SqlUtil.isDateType(type)) {
773:                        // For Date types we don't need the ValueConverter as already we 
774:                        // have a suitable long value that doesn't need parsing
775:                        java.sql.Date d = new java.sql.Date(
776:                                this .columnLongValue);
777:                        if (type == Types.TIMESTAMP) {
778:                            this .currentRow[this .realColIndex] = new java.sql.Timestamp(
779:                                    d.getTime());
780:                        } else {
781:                            this .currentRow[this .realColIndex] = d;
782:                        }
783:                    } else {
784:                        // for all other types we can use the ValueConverter
785:                        this .currentRow[this .realColIndex] = converter
786:                                .convertValue(value, type);
787:                    }
788:                } catch (Exception e) {
789:                    String msg = ResourceMgr.getString("ErrConvertError");
790:                    msg = StringUtil.replace(msg, "%type%", SqlUtil
791:                            .getTypeName(this .columns[realColIndex]
792:                                    .getDataType()));
793:                    msg = StringUtil.replace(msg, "%column%",
794:                            this .columns[realColIndex].getColumnName());
795:                    msg = StringUtil.replace(msg, "%error%", e.getMessage());
796:                    msg = StringUtil.replace(msg, "%value%", value);
797:                    msg = StringUtil.replace(msg, "%row%", Integer
798:                            .toString(this .currentRowNumber));
799:
800:                    this .messages.append(msg);
801:                    this .messages.appendNewLine();
802:
803:                    if (this .abortOnError) {
804:                        LogMgr.logError("XmlDataFileParser.buildColumnData()",
805:                                msg, e);
806:                        this .hasErrors = true;
807:                        throw new ParsingInterruptedException();
808:                    } else {
809:                        this .messages.append(ResourceMgr
810:                                .getString("ErrConvertWarning"));
811:                        this .hasWarnings = true;
812:                        LogMgr.logWarning(
813:                                "XmlDataFileParser.buildColumnData()", msg,
814:                                null);
815:                    }
816:                }
817:
818:                this .realColIndex++;
819:            }
820:
821:            private TableIdentifier getTargetTable() {
822:                TableIdentifier tbl = null;
823:                if (this .tableName == null) {
824:                    tbl = new TableIdentifier(this .tableNameFromFile);
825:                } else {
826:                    tbl = new TableIdentifier(this .tableName);
827:                }
828:                return tbl;
829:            }
830:
831:            private void sendTableDefinition() throws SQLException {
832:                try {
833:                    TableIdentifier tbl = getTargetTable();
834:
835:                    checkTargetColumns();
836:                    if (this .columnsToImport == null) {
837:                        this .receiver.setTargetTable(tbl, this .columns);
838:                    } else {
839:                        ColumnIdentifier[] cols = new ColumnIdentifier[this .realColCount];
840:                        int index = 0;
841:                        for (int i = 0; i < this .colCount; i++) {
842:                            if (this .columnsToImport.contains(this .columns[i])) {
843:                                cols[index] = this .columns[i];
844:                                index++;
845:                            }
846:                        }
847:                        this .receiver.setTargetTable(tbl, cols);
848:                    }
849:                    this .currentRow = new Object[this .realColCount];
850:                } catch (SQLException e) {
851:                    this .currentRow = null;
852:                    this .hasErrors = true;
853:                    throw e;
854:                }
855:            }
856:
857:            private void sendRowData() throws SAXException, Exception {
858:                if (this .receiver != null) {
859:                    try {
860:                        this .receiver.processRow(this .currentRow);
861:                    } catch (Exception e) {
862:                        LogMgr.logError("XmlDataFileParser.sendRowData()",
863:                                "Error when sending row data to receiver", e);
864:                        if (this .abortOnError) {
865:                            this .hasErrors = true;
866:                            throw e;
867:                        }
868:                        this .hasWarnings = true;
869:                        if (this .errorHandler != null) {
870:                            int choice = errorHandler.getActionOnError(
871:                                    this .currentRowNumber + 1, null, null,
872:                                    ExceptionUtil.getDisplay(e, false));
873:                            if (choice == JobErrorHandler.JOB_ABORT)
874:                                throw e;
875:                            if (choice == JobErrorHandler.JOB_IGNORE_ALL) {
876:                                this .abortOnError = false;
877:                            }
878:                        }
879:
880:                    }
881:                }
882:                if (!this .keepRunning)
883:                    throw new ParsingInterruptedException();
884:            }
885:
886:            public MessageBuffer getMessages() {
887:                return this .messages;
888:            }
889:
890:            private void setUseVerboseFormat(boolean flag) {
891:                this .formatKnown = true;
892:                this .verboseFormat = flag;
893:                if (this .verboseFormat) {
894:                    rowTag = XmlRowDataConverter.LONG_ROW_TAG;
895:                    columnTag = XmlRowDataConverter.LONG_COLUMN_TAG;
896:                } else {
897:                    rowTag = XmlRowDataConverter.SHORT_ROW_TAG;
898:                    columnTag = XmlRowDataConverter.SHORT_COLUMN_TAG;
899:                }
900:            }
901:
902:            public void setErrorHandler(JobErrorHandler handler) {
903:                this.errorHandler = handler;
904:            }
905:
906:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.