View Javadoc

1   package org.apache.maven;
2   
3   /* ====================================================================
4    *   Licensed to the Apache Software Foundation (ASF) under one or more
5    *   contributor license agreements.  See the NOTICE file distributed with
6    *   this work for additional information regarding copyright ownership.
7    *   The ASF licenses this file to You under the Apache License, Version 2.0
8    *   (the "License"); you may not use this file except in compliance with
9    *   the License.  You may obtain a copy of the License at
10   *
11   *       http://www.apache.org/licenses/LICENSE-2.0
12   *
13   *   Unless required by applicable law or agreed to in writing, software
14   *   distributed under the License is distributed on an "AS IS" BASIS,
15   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   *   See the License for the specific language governing permissions and
17   *   limitations under the License.
18   * ====================================================================
19   */
20  
21  import com.sun.msv.verifier.jarv.TheFactoryImpl;
22  
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.ByteArrayInputStream;
26  
27  import javax.xml.parsers.SAXParserFactory;
28  
29  import org.apache.commons.logging.Log;
30  import org.apache.commons.logging.LogFactory;
31  
32  import org.iso_relax.verifier.Verifier;
33  import org.iso_relax.verifier.VerifierFactory;
34  import org.iso_relax.verifier.VerifierHandler;
35  
36  import org.xml.sax.ErrorHandler;
37  import org.xml.sax.EntityResolver;
38  import org.xml.sax.SAXParseException;
39  import org.xml.sax.SAXException;
40  import org.xml.sax.InputSource;
41  import org.xml.sax.XMLReader;
42  
43  /**
44   * JaxpMsvBean Bean: Uses JAXP implementation of MSV.
45   *
46   * @author <a href="mailto:ltheussl@apache.org">Lukas Theussl</a>
47   */
48  public class JaxpMsvBean
49  {
50      //~ Instance fields ------------------------------------------------------
51  
52      /** The schema to use. */
53      private String schema;
54  
55      /** The file to validate. */
56      private String file;
57  
58      /** For debug output. */
59      private Log log = LogFactory.getLog(JaxpMsvBean.class);
60  
61      private static final String EMPTY = "";
62      private static final ByteArrayInputStream EMPTY_STREAM =
63          new ByteArrayInputStream(EMPTY.getBytes());
64  
65      private static final int MSV_WARNING = 0;
66      private static final int MSV_ERROR = 1;
67      private static final int MSV_FATAL_ERROR = 2;
68  
69      private boolean isValid = true;
70      private boolean validNamespace = true;
71      private XPathLocationTracker tracker;
72  
73      //~ Methods --------------------------------------------------------------
74  
75      /**
76       * Performs validation.
77       * @throws Exception Exception
78       */
79      public void validate() throws Exception
80      {
81          VerifierFactory verifierFactory = new TheFactoryImpl();
82  
83          Verifier verifier = verifierFactory.newVerifier( new File( schema ) );
84          verifier.setErrorHandler( new ErrorHandlerImpl() );
85  
86          VerifierHandler handler = verifier.getVerifierHandler();
87  
88          SAXParserFactory factory = SAXParserFactory.newInstance();
89          factory.setNamespaceAware( true );
90          factory.setValidating( false );
91  
92          XMLReader reader = factory.newSAXParser().getXMLReader();
93  
94          tracker = new XPathLocationTracker();
95          tracker.setParent( reader );
96          tracker.setContentHandler( handler );
97          tracker.setEntityResolver( new EntityResolverImpl() );
98  
99          tracker.parse( new InputSource( new FileInputStream( file ) ) );
100 
101         endMessage();
102     }
103 
104     /**
105      * Sets the schema.
106      * @param newSchema The schema to set
107      */
108     public void setSchema( String newSchema )
109     {
110       this.schema = newSchema;
111     }
112 
113     /**
114      * Sets the file.
115      * @param newFile The file to set
116      */
117     public void setFile( String newFile )
118     {
119       this.file = newFile;
120     }
121 
122     /**
123      * Gets the schema.
124      * @return The schema
125      */
126     public String getSchema()
127     {
128       return schema;
129     }
130 
131     /**
132      * Gets the file.
133      * @return The file
134      */
135     public String getFile()
136     {
137       return file;
138     }
139 
140     private void endMessage()
141     {
142         if ( isValid )
143         {
144             log.info( file + " verified: OK" );
145         }
146         else
147         {
148             log.info( file + " is NOT valid!" );
149         }
150     }
151 
152     private void errorMessage( SAXParseException e, int type )
153     {
154         File xmlFile = new File( file );
155 
156         if ( type == MSV_ERROR )
157         {
158             // if namespace is not correct, error messages are crap
159             if ( validNamespace )
160             {
161                 log.error( "    ERROR on line " + e.getLineNumber()
162                     + " of file " + xmlFile.getName() + "," );
163                 log.error( "    XPath location " + tracker.getXPath() + ":" );
164                 log.error( "    " + e.getMessage() );
165             }
166         }
167         else if ( type == MSV_FATAL_ERROR )
168         {
169             log.error( "    Non-recoverable parsing error on line "
170                 + e.getLineNumber() + " of file " + xmlFile.getName() + "," );
171             log.error( "    XPath location " + tracker.getXPath() + ":" );
172             log.error( "    " + e.getMessage() );
173         }
174         else if ( type == MSV_WARNING )
175         {
176             log.warn( "    WARNING on line " + e.getLineNumber()
177                 + " of file " + xmlFile.getName() + "," );
178             log.warn( "    XPath location " + tracker.getXPath() + ":" );
179             log.warn( e.getMessage() );
180         }
181     }
182 
183     private class ErrorHandlerImpl implements ErrorHandler
184     {
185         public void warning( SAXParseException e ) throws SAXException
186         {
187             errorMessage( e, MSV_WARNING );
188             throw e;
189         }
190 
191         public void error( SAXParseException e ) throws SAXException
192         {
193             errorMessage( e, MSV_ERROR);
194             isValid = false;
195             if ( e.getMessage() != null
196                 && e.getMessage().startsWith("namespace URI of tag") )
197             {
198                 validNamespace = false;
199             }
200             throw e;
201         }
202 
203         public void fatalError( SAXParseException e ) throws SAXException
204         {
205             errorMessage( e, MSV_FATAL_ERROR );
206             isValid = false;
207             throw e;
208         }
209     }
210 
211     private class EntityResolverImpl implements EntityResolver
212     {
213         public InputSource resolveEntity( String publicId,
214                              String systemId ) throws SAXException
215         {
216             log.warn( "    WARNING: External entity " + systemId
217                 + " won't be resolved" );
218             return new InputSource( EMPTY_STREAM );
219         }
220     }
221 
222 }