package org.apache.maven; /* ==================================================================== * Copyright 2001-2005 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ==================================================================== */ import com.sun.msv.verifier.jarv.TheFactoryImpl; import java.io.File; import java.io.FileInputStream; import java.io.ByteArrayInputStream; import javax.xml.parsers.SAXParserFactory; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.iso_relax.verifier.Verifier; import org.iso_relax.verifier.VerifierFactory; import org.iso_relax.verifier.VerifierHandler; import org.xml.sax.ErrorHandler; import org.xml.sax.EntityResolver; import org.xml.sax.SAXParseException; import org.xml.sax.SAXException; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; /** * JaxpMsvBean Bean: Uses JAXP implementation of MSV. * * @author Lukas Theussl */ public class JaxpMsvBean { //~ Instance fields ------------------------------------------------------ /** The schema to use. */ private String schema; /** The file to validate. */ private String file; /** For debug output. */ private Log log = LogFactory.getLog(JaxpMsvBean.class); private static final String EMPTY = ""; private static final ByteArrayInputStream EMPTY_STREAM = new ByteArrayInputStream(EMPTY.getBytes()); private static final int MSV_WARNING = 0; private static final int MSV_ERROR = 1; private static final int MSV_FATAL_ERROR = 2; private boolean isValid = true; private boolean validNamespace = true; private XPathLocationTracker tracker; //~ Methods -------------------------------------------------------------- /** * Performs validation. * @throws Exception Exception */ public void validate() throws Exception { VerifierFactory verifierFactory = new TheFactoryImpl(); Verifier verifier = verifierFactory.newVerifier( new File( schema ) ); verifier.setErrorHandler( new ErrorHandlerImpl() ); VerifierHandler handler = verifier.getVerifierHandler(); SAXParserFactory factory = SAXParserFactory.newInstance(); factory.setNamespaceAware( true ); factory.setValidating( false ); XMLReader reader = factory.newSAXParser().getXMLReader(); tracker = new XPathLocationTracker(); tracker.setParent( reader ); tracker.setContentHandler( handler ); tracker.setEntityResolver( new EntityResolverImpl() ); tracker.parse( new InputSource( new FileInputStream( file ) ) ); endMessage(); } /** * Sets the schema. * @param newSchema The schema to set */ public void setSchema( String newSchema ) { this.schema = newSchema; } /** * Sets the file. * @param newFile The file to set */ public void setFile( String newFile ) { this.file = newFile; } /** * Gets the schema. * @return The schema */ public String getSchema() { return schema; } /** * Gets the file. * @return The file */ public String getFile() { return file; } private void endMessage() { if ( isValid ) { log.info( file + " verified: OK" ); } else { log.info( file + " is NOT valid!" ); } } private void errorMessage( SAXParseException e, int type ) { File xmlFile = new File( file ); if ( type == MSV_ERROR ) { // if namespace is not correct, error messages are crap if ( validNamespace ) { log.error( " ERROR on line " + e.getLineNumber() + " of file " + xmlFile.getName() + "," ); log.error( " XPath location " + tracker.getXPath() + ":" ); log.error( " " + e.getMessage() ); } } else if ( type == MSV_FATAL_ERROR ) { log.error( " Non-recoverable parsing error on line " + e.getLineNumber() + " of file " + xmlFile.getName() + "," ); log.error( " XPath location " + tracker.getXPath() + ":" ); log.error( " " + e.getMessage() ); } else if ( type == MSV_WARNING ) { log.warn( " WARNING on line " + e.getLineNumber() + " of file " + xmlFile.getName() + "," ); log.warn( " XPath location " + tracker.getXPath() + ":" ); log.warn( e.getMessage() ); } } private class ErrorHandlerImpl implements ErrorHandler { public void warning( SAXParseException e ) throws SAXException { errorMessage( e, MSV_WARNING ); throw e; } public void error( SAXParseException e ) throws SAXException { errorMessage( e, MSV_ERROR); isValid = false; if ( e.getMessage() != null && e.getMessage().startsWith("namespace URI of tag") ) { validNamespace = false; } throw e; } public void fatalError( SAXParseException e ) throws SAXException { errorMessage( e, MSV_FATAL_ERROR ); isValid = false; throw e; } } private class EntityResolverImpl implements EntityResolver { public InputSource resolveEntity( String publicId, String systemId ) throws SAXException { log.warn( " WARNING: External entity " + systemId + " won't be resolved" ); return new InputSource( EMPTY_STREAM ); } } }