📄 xmlvalidatetask.java
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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. * */package org.apache.tools.ant.taskdefs.optional;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.util.Vector;import org.apache.tools.ant.AntClassLoader;import org.apache.tools.ant.BuildException;import org.apache.tools.ant.DirectoryScanner;import org.apache.tools.ant.Project;import org.apache.tools.ant.Task;import org.apache.tools.ant.types.DTDLocation;import org.apache.tools.ant.types.FileSet;import org.apache.tools.ant.types.Path;import org.apache.tools.ant.types.Reference;import org.apache.tools.ant.types.XMLCatalog;import org.apache.tools.ant.util.FileUtils;import org.apache.tools.ant.util.JAXPUtils;import org.apache.tools.ant.util.XmlConstants;import org.xml.sax.EntityResolver;import org.xml.sax.ErrorHandler;import org.xml.sax.InputSource;import org.xml.sax.Parser;import org.xml.sax.SAXException;import org.xml.sax.SAXNotRecognizedException;import org.xml.sax.SAXNotSupportedException;import org.xml.sax.SAXParseException;import org.xml.sax.XMLReader;import org.xml.sax.helpers.ParserAdapter;/** * Checks XML files are valid (or only well formed). The * task uses the SAX2 parser implementation provided by JAXP by default * (probably the one that is used by Ant itself), but one can specify any * SAX1/2 parser if needed. * */public class XMLValidateTask extends Task { /** * helper for path -> URI and URI -> path conversions. */ private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); protected static final String INIT_FAILED_MSG = "Could not start xml validation: "; // ant task properties // defaults // CheckStyle:VisibilityModifier OFF - bc protected boolean failOnError = true; protected boolean warn = true; protected boolean lenient = false; protected String readerClassName = null; /** file to be validated */ protected File file = null; /** sets of file to be validated */ protected Vector filesets = new Vector(); protected Path classpath; /** * the parser is viewed as a SAX2 XMLReader. If a SAX1 parser is specified, * it's wrapped in an adapter that make it behave as a XMLReader. * a more 'standard' way of doing this would be to use the JAXP1.1 SAXParser * interface. */ protected XMLReader xmlReader = null; // XMLReader used to validation process protected ValidatorErrorHandler errorHandler = new ValidatorErrorHandler(); // to report sax parsing errors // CheckStyle:VisibilityModifier ON /** The vector to store all attributes (features) to be set on the parser. **/ private Vector attributeList = new Vector(); /** * List of properties. */ private final Vector propertyList = new Vector(); private XMLCatalog xmlCatalog = new XMLCatalog(); /** Message for sucessfull validation */ public static final String MESSAGE_FILES_VALIDATED = " file(s) have been successfully validated."; /** * Specify how parser error are to be handled. * Optional, default is <code>true</code>. * <p> * If set to <code>true</code> (default), throw a buildException if the * parser yields an error. * @param fail if set to <code>false</code> do not fail on error */ public void setFailOnError(boolean fail) { failOnError = fail; } /** * Specify how parser error are to be handled. * <p> * If set to <code>true</true> (default), log a warn message for each SAX warn event. * @param bool if set to <code>false</code> do not send warnings */ public void setWarn(boolean bool) { warn = bool; } /** * Specify whether the parser should be validating. Default * is <code>true</code>. * <p> * If set to false, the validation will fail only if the parsed document * is not well formed XML. * <p> * this option is ignored if the specified class * with {@link #setClassName(String)} is not a SAX2 XMLReader. * @param bool if set to <code>false</code> only fail on malformed XML */ public void setLenient(boolean bool) { lenient = bool; } /** * Specify the class name of the SAX parser to be used. (optional) * @param className should be an implementation of SAX2 * <code>org.xml.sax.XMLReader</code> or SAX2 <code>org.xml.sax.Parser</code>. * <p> if className is an implementation of * <code>org.xml.sax.Parser</code>, {@link #setLenient(boolean)}, * will be ignored. * <p> if not set, the default will be used. * @see org.xml.sax.XMLReader * @see org.xml.sax.Parser */ public void setClassName(String className) { readerClassName = className; } /** * Specify the classpath to be searched to load the parser (optional) * @param classpath the classpath to load the parser */ public void setClasspath(Path classpath) { if (this.classpath == null) { this.classpath = classpath; } else { this.classpath.append(classpath); } } /** * @see #setClasspath * @return the classpath created */ public Path createClasspath() { if (this.classpath == null) { this.classpath = new Path(getProject()); } return this.classpath.createPath(); } /** * Where to find the parser class; optional. * @see #setClasspath * @param r reference to a classpath defined elsewhere */ public void setClasspathRef(Reference r) { createClasspath().setRefid(r); } /** * specify the file to be checked; optional. * @param file the file to be checked */ public void setFile(File file) { this.file = file; } /** * add an XMLCatalog as a nested element; optional. * @param catalog XMLCatalog to use */ public void addConfiguredXMLCatalog(XMLCatalog catalog) { xmlCatalog.addConfiguredXMLCatalog(catalog); } /** * specify a set of file to be checked * @param set the fileset to check */ public void addFileset(FileSet set) { filesets.addElement(set); } /** * Add an attribute nested element. This is used for setting arbitrary * features of the SAX parser. * Valid attributes * <a href= * "http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description" * >include</a> * @return attribute created * @since ant1.6 */ public Attribute createAttribute() { final Attribute feature = new Attribute(); attributeList.addElement(feature); return feature; } /** * Creates a property. * * @return a property. * @since ant 1.6.2 */ public Property createProperty() { final Property prop = new Property(); propertyList.addElement(prop); return prop; } /** * Called by the project to let the task initialize properly. * * @exception BuildException if something goes wrong with the build */ public void init() throws BuildException { super.init(); xmlCatalog.setProject(getProject()); } /** * Create a DTD location record; optional. * This stores the location of a DTD. The DTD is identified * by its public Id. * @return created DTD location */ public DTDLocation createDTD() { DTDLocation dtdLocation = new DTDLocation(); xmlCatalog.addDTD(dtdLocation); return dtdLocation; } /** * accessor to the xmlCatalog used in the task * @return xmlCatalog reference */ protected EntityResolver getEntityResolver() { return xmlCatalog; } /** * get the XML reader. Non-null only after {@link #initValidator()}. * If the reader is an instance of {@link ParserAdapter} then * the parser is a SAX1 parser, and you cannot call * {@link #setFeature(String, boolean)} or {@link #setProperty(String, String)} * on it. * @return the XML reader or null. */ protected XMLReader getXmlReader() { return xmlReader; } /** * execute the task * @throws BuildException if <code>failonerror</code> is true and an error happens */ public void execute() throws BuildException { int fileProcessed = 0; if (file == null && (filesets.size() == 0)) { throw new BuildException( "Specify at least one source - " + "a file or a fileset."); } if (file != null) { if (file.exists() && file.canRead() && file.isFile()) { doValidate(file); fileProcessed++; } else { String errorMsg = "File " + file + " cannot be read"; if (failOnError) { throw new BuildException(errorMsg); } else { log(errorMsg, Project.MSG_ERR); } } } for (int i = 0; i < filesets.size(); i++) { FileSet fs = (FileSet) filesets.elementAt(i); DirectoryScanner ds = fs.getDirectoryScanner(getProject()); String[] files = ds.getIncludedFiles(); for (int j = 0; j < files.length; j++) { File srcFile = new File(fs.getDir(getProject()), files[j]); doValidate(srcFile); fileProcessed++; } } onSuccessfulValidation(fileProcessed); } /** * handler called on successful file validation. * @param fileProcessed number of files processed. */ protected void onSuccessfulValidation(int fileProcessed) { log(fileProcessed + MESSAGE_FILES_VALIDATED); } /** * init the parser : * load the parser class, and set features if necessary * It is only after this that the reader is valid * @throws BuildException if something went wrong */ protected void initValidator() { xmlReader = createXmlReader(); xmlReader.setEntityResolver(getEntityResolver()); xmlReader.setErrorHandler(errorHandler); if (!isSax1Parser()) { // turn validation on if (!lenient) { setFeature(XmlConstants.FEATURE_VALIDATION, true); } // set the feature from the attribute list for (int i = 0; i < attributeList.size(); i++) { Attribute feature = (Attribute) attributeList.elementAt(i); setFeature(feature.getName(), feature.getValue()); } // Sets properties for (int i = 0; i < propertyList.size(); i++) { final Property prop = (Property) propertyList.elementAt(i); setProperty(prop.getName(), prop.getValue()); } } } /** * test that returns true if we are using a SAX1 parser. * @return true when a SAX1 parser is in use */ protected boolean isSax1Parser() { return (xmlReader instanceof ParserAdapter); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -