001: package liquibase.parser.xml;
002:
003: import liquibase.DatabaseChangeLog;
004: import liquibase.FileOpener;
005: import liquibase.exception.ChangeLogParseException;
006: import liquibase.log.LogFactory;
007: import liquibase.parser.LiquibaseSchemaResolver;
008: import org.xml.sax.*;
009:
010: import javax.xml.parsers.SAXParser;
011: import javax.xml.parsers.SAXParserFactory;
012: import java.io.IOException;
013: import java.io.InputStream;
014:
015: public class XMLChangeLogParser {
016:
017: public static String getSchemaVersion() {
018: return "1.5";
019: }
020:
021: public DatabaseChangeLog parse(String physicalChangeLogLocation,
022: FileOpener fileOpener) throws ChangeLogParseException {
023:
024: SAXParserFactory saxParserFactory = SAXParserFactory
025: .newInstance();
026: if (System.getProperty("java.vm.version").startsWith("1.4")) {
027: saxParserFactory.setValidating(false);
028: saxParserFactory.setNamespaceAware(false);
029: } else {
030: saxParserFactory.setValidating(true);
031: saxParserFactory.setNamespaceAware(true);
032: }
033:
034: InputStream inputStream = null;
035: try {
036: SAXParser parser = saxParserFactory.newSAXParser();
037: try {
038: parser
039: .setProperty(
040: "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
041: "http://www.w3.org/2001/XMLSchema");
042: } catch (SAXNotRecognizedException e) {
043: ; //ok, parser must not support it
044: } catch (SAXNotSupportedException e) {
045: ; //ok, parser must not support it
046: }
047:
048: XMLReader xmlReader = parser.getXMLReader();
049: xmlReader.setEntityResolver(new LiquibaseSchemaResolver());
050: xmlReader.setErrorHandler(new ErrorHandler() {
051: public void warning(SAXParseException exception)
052: throws SAXException {
053: LogFactory.getLogger().warning(
054: exception.getMessage());
055: throw exception;
056: }
057:
058: public void error(SAXParseException exception)
059: throws SAXException {
060: LogFactory.getLogger().severe(
061: exception.getMessage());
062: throw exception;
063: }
064:
065: public void fatalError(SAXParseException exception)
066: throws SAXException {
067: LogFactory.getLogger().severe(
068: exception.getMessage());
069: throw exception;
070: }
071: });
072:
073: inputStream = fileOpener
074: .getResourceAsStream(physicalChangeLogLocation);
075: if (inputStream == null) {
076: throw new ChangeLogParseException(
077: physicalChangeLogLocation + " does not exist");
078: }
079:
080: XMLChangeLogHandler contentHandler = new XMLChangeLogHandler(
081: physicalChangeLogLocation, fileOpener);
082: xmlReader.setContentHandler(contentHandler);
083: xmlReader.parse(new InputSource(inputStream));
084:
085: return contentHandler.getDatabaseChangeLog();
086: } catch (ChangeLogParseException e) {
087: throw e;
088: } catch (IOException e) {
089: throw new ChangeLogParseException(
090: "Error Reading Migration File: " + e.getMessage(),
091: e);
092: } catch (SAXParseException e) {
093: throw new ChangeLogParseException("Error parsing line "
094: + e.getLineNumber() + " column "
095: + e.getColumnNumber() + " of " + ": "
096: + e.getMessage());
097: } catch (SAXException e) {
098: Throwable parentCause = e.getException();
099: while (parentCause != null) {
100: if (parentCause instanceof ChangeLogParseException) {
101: throw ((ChangeLogParseException) parentCause);
102: }
103: parentCause = parentCause.getCause();
104: }
105: String reason = e.getMessage();
106: String causeReason = null;
107: if (e.getCause() != null) {
108: causeReason = e.getCause().getMessage();
109: }
110:
111: // if (reason == null && causeReason==null) {
112: // reason = "Unknown Reason";
113: // }
114: if (reason == null) {
115: if (causeReason != null) {
116: reason = causeReason;
117: } else {
118: reason = "Unknown Reason";
119: }
120: }
121:
122: throw new ChangeLogParseException(
123: "Invalid Migration File: " + reason, e);
124: } catch (Exception e) {
125: throw new ChangeLogParseException(e);
126: } finally {
127: if (inputStream != null) {
128: try {
129: inputStream.close();
130: } catch (IOException e) {
131: ;
132: }
133: }
134: }
135: }
136: }
|