001// Copyright 2011 Leo Przybylski. All rights reserved.
002//
003// Redistribution and use in source and binary forms, with or without modification, are
004// permitted provided that the following conditions are met:
005//
006//    1. Redistributions of source code must retain the above copyright notice, this list of
007//       conditions and the following disclaimer.
008//
009//    2. Redistributions in binary form must reproduce the above copyright notice, this list
010//       of conditions and the following disclaimer in the documentation and/or other materials
011//       provided with the distribution.
012//
013// THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ''AS IS'' AND ANY EXPRESS OR IMPLIED
014// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
015// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> OR
016// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
017// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
018// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
019// ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
020// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
021// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
022//
023// The views and conclusions contained in the software and documentation are those of the
024// authors and should not be interpreted as representing official policies, either expressed
025// or implied, of Leo Przybylski.
026package org.kualigan.tools.liquibase;
027
028import java.io.IOException;
029import java.io.InputStream;
030
031import javax.xml.parsers.SAXParser;
032import javax.xml.parsers.SAXParserFactory;
033
034import liquibase.changelog.ChangeLogParameters;
035import liquibase.changelog.DatabaseChangeLog;
036import liquibase.exception.ChangeLogParseException;
037import liquibase.logging.LogFactory;
038import liquibase.parser.ChangeLogParser;
039import liquibase.parser.core.xml.*;
040import liquibase.resource.ResourceAccessor;
041import liquibase.util.file.FilenameUtils;
042
043import org.xml.sax.ErrorHandler;
044import org.xml.sax.InputSource;
045import org.xml.sax.SAXException;
046import org.xml.sax.SAXNotRecognizedException;
047import org.xml.sax.SAXNotSupportedException;
048import org.xml.sax.SAXParseException;
049import org.xml.sax.XMLReader;
050
051public class XMLChangeLogParser extends liquibase.parser.core.xml.XMLChangeLogSAXParser {
052
053    public static String getSchemaVersion() {
054        return "2.0";
055    }
056
057    /*
058    public DatabaseChangeLog parse(String physicalChangeLogLocation, ChangeLogParameters changeLogParameters, ResourceAccessor resourceAccessor) throws ChangeLogParseException {
059
060        InputStream inputStream = null;
061        try {
062            
063            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
064            try {
065                parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
066            } catch (SAXNotRecognizedException e) {
067                //ok, parser must not support it
068            } catch (SAXNotSupportedException e) {
069                //ok, parser must not support it
070            }
071
072            XMLReader xmlReader = parser.getXMLReader();
073            LiquibaseEntityResolver resolver=new LiquibaseEntityResolver();
074            resolver.useResoureAccessor(resourceAccessor,FilenameUtils.getFullPath(physicalChangeLogLocation));
075            xmlReader.setEntityResolver(resolver);
076            xmlReader.setErrorHandler(new ErrorHandler() {
077                public void warning(SAXParseException exception) throws SAXException {
078                    LogFactory.getLogger().warning(exception.getMessage());
079                    throw exception;
080                }
081
082                public void error(SAXParseException exception) throws SAXException {
083                    LogFactory.getLogger().severe(exception.getMessage());
084                    throw exception;
085                }
086
087                public void fatalError(SAXParseException exception) throws SAXException {
088                    LogFactory.getLogger().severe(exception.getMessage());
089                    throw exception;
090                }
091            });
092                
093            inputStream = resourceAccessor.getResourceAsStream(physicalChangeLogLocation);
094            if (inputStream == null) {
095                throw new ChangeLogParseException(physicalChangeLogLocation + " does not exist");
096            }
097
098            XMLChangeLogSAXHandler contentHandler = new XMLChangeLogSAXHandler(physicalChangeLogLocation, resourceAccessor, changeLogParameters);
099            xmlReader.setContentHandler(contentHandler);
100            xmlReader.parse(new InputSource(inputStream));
101
102            return contentHandler.getDatabaseChangeLog();
103        } catch (ChangeLogParseException e) {
104            throw e;
105        } catch (IOException e) {
106            throw new ChangeLogParseException("Error Reading Migration File: " + e.getMessage(), e);
107        } catch (SAXParseException e) {
108            throw new ChangeLogParseException("Error parsing line " + e.getLineNumber() + " column " + e.getColumnNumber() + " of " + physicalChangeLogLocation +": " + e.getMessage(), e);
109        } catch (SAXException e) {
110            Throwable parentCause = e.getException();
111            while (parentCause != null) {
112                if (parentCause instanceof ChangeLogParseException) {
113                    throw ((ChangeLogParseException) parentCause);
114                }
115                parentCause = parentCause.getCause();
116            }
117            String reason = e.getMessage();
118            String causeReason = null;
119            if (e.getCause() != null) {
120                causeReason = e.getCause().getMessage();
121            }
122
123//            if (reason == null && causeReason==null) {
124//                reason = "Unknown Reason";
125//            }
126            if (reason == null) {
127                if (causeReason != null) {
128                    reason = causeReason;
129                } else {
130                    reason = "Unknown Reason";
131                }
132            }
133
134            throw new ChangeLogParseException("Invalid Migration File: " + reason, e);
135        } catch (Exception e) {
136            throw new ChangeLogParseException(e);
137        } finally {
138            if (inputStream != null) {
139                try {
140                    inputStream.close();
141                } catch (IOException e) {
142                    // probably ok
143                }
144            }
145        }
146    }
147    */
148}