1 | /*
|
---|
2 | * Copyright 2000-2004 The Apache Software Foundation
|
---|
3 | *
|
---|
4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
5 | * you may not use this file except in compliance with the License.
|
---|
6 | * You may obtain a copy of the License at
|
---|
7 | *
|
---|
8 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
9 | *
|
---|
10 | * Unless required by applicable law or agreed to in writing, software
|
---|
11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
13 | * See the License for the specific language governing permissions and
|
---|
14 | * limitations under the License.
|
---|
15 | *
|
---|
16 | */
|
---|
17 | package org.apache.tools.ant.taskdefs.optional;
|
---|
18 |
|
---|
19 | import java.io.File;
|
---|
20 | import java.io.FileInputStream;
|
---|
21 | import java.io.IOException;
|
---|
22 | import java.util.Vector;
|
---|
23 |
|
---|
24 | import org.apache.tools.ant.AntClassLoader;
|
---|
25 | import org.apache.tools.ant.BuildException;
|
---|
26 | import org.apache.tools.ant.DirectoryScanner;
|
---|
27 | import org.apache.tools.ant.Project;
|
---|
28 | import org.apache.tools.ant.Task;
|
---|
29 | import org.apache.tools.ant.types.DTDLocation;
|
---|
30 | import org.apache.tools.ant.types.FileSet;
|
---|
31 | import org.apache.tools.ant.types.Path;
|
---|
32 | import org.apache.tools.ant.types.Reference;
|
---|
33 | import org.apache.tools.ant.types.XMLCatalog;
|
---|
34 | import org.apache.tools.ant.util.FileUtils;
|
---|
35 | import org.apache.tools.ant.util.JAXPUtils;
|
---|
36 |
|
---|
37 | import org.xml.sax.EntityResolver;
|
---|
38 | import org.xml.sax.ErrorHandler;
|
---|
39 | import org.xml.sax.InputSource;
|
---|
40 | import org.xml.sax.Parser;
|
---|
41 | import org.xml.sax.SAXException;
|
---|
42 | import org.xml.sax.SAXNotRecognizedException;
|
---|
43 | import org.xml.sax.SAXNotSupportedException;
|
---|
44 | import org.xml.sax.SAXParseException;
|
---|
45 | import org.xml.sax.XMLReader;
|
---|
46 | import org.xml.sax.helpers.ParserAdapter;
|
---|
47 |
|
---|
48 | /**
|
---|
49 | * Checks XML files are valid (or only well formed). The
|
---|
50 | * task uses the SAX2 parser implementation provided by JAXP by default
|
---|
51 | * (probably the one that is used by Ant itself), but one can specify any
|
---|
52 | * SAX1/2 parser if needed.
|
---|
53 | *
|
---|
54 | */
|
---|
55 | public class XMLValidateTask extends Task {
|
---|
56 |
|
---|
57 | /**
|
---|
58 | * helper for path -> URI and URI -> path conversions.
|
---|
59 | */
|
---|
60 | private static final FileUtils FILE_UTILS = FileUtils.newFileUtils();
|
---|
61 |
|
---|
62 | protected static final String INIT_FAILED_MSG =
|
---|
63 | "Could not start xml validation: ";
|
---|
64 |
|
---|
65 | // ant task properties
|
---|
66 | // defaults
|
---|
67 | protected boolean failOnError = true;
|
---|
68 | protected boolean warn = true;
|
---|
69 | protected boolean lenient = false;
|
---|
70 | protected String readerClassName = null;
|
---|
71 |
|
---|
72 | /** file to be validated */
|
---|
73 | protected File file = null;
|
---|
74 | /** sets of file to be validated */
|
---|
75 | protected Vector filesets = new Vector();
|
---|
76 | protected Path classpath;
|
---|
77 |
|
---|
78 | /**
|
---|
79 | * the parser is viewed as a SAX2 XMLReader. If a SAX1 parser is specified,
|
---|
80 | * it's wrapped in an adapter that make it behave as a XMLReader.
|
---|
81 | * a more 'standard' way of doing this would be to use the JAXP1.1 SAXParser
|
---|
82 | * interface.
|
---|
83 | */
|
---|
84 | protected XMLReader xmlReader = null;
|
---|
85 | // XMLReader used to validation process
|
---|
86 | protected ValidatorErrorHandler errorHandler = new ValidatorErrorHandler();
|
---|
87 | // to report sax parsing errors
|
---|
88 |
|
---|
89 | /** The vector to store all attributes (features) to be set on the parser. **/
|
---|
90 | private Vector attributeList = new Vector();
|
---|
91 |
|
---|
92 | /**
|
---|
93 | * List of properties.
|
---|
94 | */
|
---|
95 | private final Vector propertyList = new Vector();
|
---|
96 |
|
---|
97 | private XMLCatalog xmlCatalog = new XMLCatalog();
|
---|
98 |
|
---|
99 | /**
|
---|
100 | * Specify how parser error are to be handled.
|
---|
101 | * Optional, default is <code>true</code>.
|
---|
102 | * <p>
|
---|
103 | * If set to <code>true</code> (default), throw a buildException if the
|
---|
104 | * parser yields an error.
|
---|
105 | * @param fail if set to <code>false</code> do not fail on error
|
---|
106 | */
|
---|
107 | public void setFailOnError(boolean fail) {
|
---|
108 | failOnError = fail;
|
---|
109 | }
|
---|
110 |
|
---|
111 | /**
|
---|
112 | * Specify how parser error are to be handled.
|
---|
113 | * <p>
|
---|
114 | * If set to <code>true</true> (default), log a warn message for each SAX warn event.
|
---|
115 | * @param bool if set to <code>false</code> do not send warnings
|
---|
116 | */
|
---|
117 | public void setWarn(boolean bool) {
|
---|
118 | warn = bool;
|
---|
119 | }
|
---|
120 |
|
---|
121 | /**
|
---|
122 | * Specify whether the parser should be validating. Default
|
---|
123 | * is <code>true</code>.
|
---|
124 | * <p>
|
---|
125 | * If set to false, the validation will fail only if the parsed document
|
---|
126 | * is not well formed XML.
|
---|
127 | * <p>
|
---|
128 | * this option is ignored if the specified class
|
---|
129 | * with {@link #setClassName(String)} is not a SAX2 XMLReader.
|
---|
130 | * @param bool if set to <code>false</code> only fail on malformed XML
|
---|
131 | */
|
---|
132 | public void setLenient(boolean bool) {
|
---|
133 | lenient = bool;
|
---|
134 | }
|
---|
135 |
|
---|
136 | /**
|
---|
137 | * Specify the class name of the SAX parser to be used. (optional)
|
---|
138 | * @param className should be an implementation of SAX2
|
---|
139 | * <code>org.xml.sax.XMLReader</code> or SAX2 <code>org.xml.sax.Parser</code>.
|
---|
140 | * <p> if className is an implementation of
|
---|
141 | * <code>org.xml.sax.Parser</code>, {@link #setLenient(boolean)},
|
---|
142 | * will be ignored.
|
---|
143 | * <p> if not set, the default will be used.
|
---|
144 | * @see org.xml.sax.XMLReader
|
---|
145 | * @see org.xml.sax.Parser
|
---|
146 | */
|
---|
147 | public void setClassName(String className) {
|
---|
148 | readerClassName = className;
|
---|
149 | }
|
---|
150 |
|
---|
151 | /**
|
---|
152 | * Specify the classpath to be searched to load the parser (optional)
|
---|
153 | * @param classpath the classpath to load the parser
|
---|
154 | */
|
---|
155 | public void setClasspath(Path classpath) {
|
---|
156 | if (this.classpath == null) {
|
---|
157 | this.classpath = classpath;
|
---|
158 | } else {
|
---|
159 | this.classpath.append(classpath);
|
---|
160 | }
|
---|
161 | }
|
---|
162 |
|
---|
163 | /**
|
---|
164 | * @see #setClasspath
|
---|
165 | * @return the classpath created
|
---|
166 | */
|
---|
167 | public Path createClasspath() {
|
---|
168 | if (this.classpath == null) {
|
---|
169 | this.classpath = new Path(getProject());
|
---|
170 | }
|
---|
171 | return this.classpath.createPath();
|
---|
172 | }
|
---|
173 |
|
---|
174 | /**
|
---|
175 | * Where to find the parser class; optional.
|
---|
176 | * @see #setClasspath
|
---|
177 | * @param r reference to a classpath defined elsewhere
|
---|
178 | */
|
---|
179 | public void setClasspathRef(Reference r) {
|
---|
180 | createClasspath().setRefid(r);
|
---|
181 | }
|
---|
182 |
|
---|
183 | /**
|
---|
184 | * specify the file to be checked; optional.
|
---|
185 | * @param file the file to be checked
|
---|
186 | */
|
---|
187 | public void setFile(File file) {
|
---|
188 | this.file = file;
|
---|
189 | }
|
---|
190 |
|
---|
191 | /**
|
---|
192 | * add an XMLCatalog as a nested element; optional.
|
---|
193 | * @param catalog XMLCatalog to use
|
---|
194 | */
|
---|
195 | public void addConfiguredXMLCatalog(XMLCatalog catalog) {
|
---|
196 | xmlCatalog.addConfiguredXMLCatalog(catalog);
|
---|
197 | }
|
---|
198 |
|
---|
199 | /**
|
---|
200 | * specify a set of file to be checked
|
---|
201 | * @param set the fileset to check
|
---|
202 | */
|
---|
203 | public void addFileset(FileSet set) {
|
---|
204 | filesets.addElement(set);
|
---|
205 | }
|
---|
206 |
|
---|
207 | /**
|
---|
208 | * Add an attribute nested element. This is used for setting arbitrary
|
---|
209 | * features of the SAX parser.
|
---|
210 | * Valid attributes
|
---|
211 | * <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">include</a>
|
---|
212 | * @return attribute created
|
---|
213 | * @since ant1.6
|
---|
214 | */
|
---|
215 | public Attribute createAttribute() {
|
---|
216 | final Attribute feature = new Attribute();
|
---|
217 | attributeList.addElement(feature);
|
---|
218 | return feature;
|
---|
219 | }
|
---|
220 |
|
---|
221 | /**
|
---|
222 | * Creates a property.
|
---|
223 | *
|
---|
224 | * @return a property.
|
---|
225 | * @since ant 1.6.2
|
---|
226 | */
|
---|
227 | public Property createProperty() {
|
---|
228 | final Property prop = new Property();
|
---|
229 | propertyList.addElement(prop);
|
---|
230 | return prop;
|
---|
231 | }
|
---|
232 |
|
---|
233 | /**
|
---|
234 | * Called by the project to let the task initialize properly.
|
---|
235 | *
|
---|
236 | * @exception BuildException if something goes wrong with the build
|
---|
237 | */
|
---|
238 | public void init() throws BuildException {
|
---|
239 | super.init();
|
---|
240 | xmlCatalog.setProject(getProject());
|
---|
241 | }
|
---|
242 |
|
---|
243 | /**
|
---|
244 | * Create a DTD location record; optional.
|
---|
245 | * This stores the location of a DTD. The DTD is identified
|
---|
246 | * by its public Id.
|
---|
247 | * @return created DTD location
|
---|
248 | */
|
---|
249 | public DTDLocation createDTD() {
|
---|
250 | DTDLocation dtdLocation = new DTDLocation();
|
---|
251 | xmlCatalog.addDTD(dtdLocation);
|
---|
252 | return dtdLocation;
|
---|
253 | }
|
---|
254 | /**
|
---|
255 | * accessor to the xmlCatalog used in the task
|
---|
256 | * @return xmlCatalog reference
|
---|
257 | */
|
---|
258 | protected EntityResolver getEntityResolver() {
|
---|
259 | return xmlCatalog;
|
---|
260 | }
|
---|
261 | /**
|
---|
262 | * execute the task
|
---|
263 | * @throws BuildException if <code>failonerror</code> is true and an error happens
|
---|
264 | */
|
---|
265 | public void execute() throws BuildException {
|
---|
266 |
|
---|
267 | int fileProcessed = 0;
|
---|
268 | if (file == null && (filesets.size() == 0)) {
|
---|
269 | throw new BuildException(
|
---|
270 | "Specify at least one source - " + "a file or a fileset.");
|
---|
271 | }
|
---|
272 |
|
---|
273 | initValidator();
|
---|
274 |
|
---|
275 | if (file != null) {
|
---|
276 | if (file.exists() && file.canRead() && file.isFile()) {
|
---|
277 | doValidate(file);
|
---|
278 | fileProcessed++;
|
---|
279 | } else {
|
---|
280 | String errorMsg = "File " + file + " cannot be read";
|
---|
281 | if (failOnError) {
|
---|
282 | throw new BuildException(errorMsg);
|
---|
283 | } else {
|
---|
284 | log(errorMsg, Project.MSG_ERR);
|
---|
285 | }
|
---|
286 | }
|
---|
287 | }
|
---|
288 |
|
---|
289 | for (int i = 0; i < filesets.size(); i++) {
|
---|
290 |
|
---|
291 | FileSet fs = (FileSet) filesets.elementAt(i);
|
---|
292 | DirectoryScanner ds = fs.getDirectoryScanner(getProject());
|
---|
293 | String[] files = ds.getIncludedFiles();
|
---|
294 |
|
---|
295 | for (int j = 0; j < files.length; j++) {
|
---|
296 | File srcFile = new File(fs.getDir(getProject()), files[j]);
|
---|
297 | doValidate(srcFile);
|
---|
298 | fileProcessed++;
|
---|
299 | }
|
---|
300 | }
|
---|
301 | log(fileProcessed + " file(s) have been successfully validated.");
|
---|
302 | }
|
---|
303 |
|
---|
304 | /**
|
---|
305 | * init the parser :
|
---|
306 | * load the parser class, and set features if necessary
|
---|
307 | */
|
---|
308 | private void initValidator() {
|
---|
309 |
|
---|
310 | Object reader = null;
|
---|
311 | if (readerClassName == null) {
|
---|
312 | try {
|
---|
313 | reader = JAXPUtils.getXMLReader();
|
---|
314 | } catch (BuildException exc) {
|
---|
315 | reader = JAXPUtils.getParser();
|
---|
316 | }
|
---|
317 | } else {
|
---|
318 |
|
---|
319 | Class readerClass = null;
|
---|
320 | try {
|
---|
321 | // load the parser class
|
---|
322 | if (classpath != null) {
|
---|
323 | AntClassLoader loader =
|
---|
324 | getProject().createClassLoader(classpath);
|
---|
325 | readerClass = Class.forName(readerClassName, true, loader);
|
---|
326 | } else {
|
---|
327 | readerClass = Class.forName(readerClassName);
|
---|
328 | }
|
---|
329 |
|
---|
330 | reader = readerClass.newInstance();
|
---|
331 | } catch (ClassNotFoundException e) {
|
---|
332 | throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
|
---|
333 | } catch (InstantiationException e) {
|
---|
334 | throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
|
---|
335 | } catch (IllegalAccessException e) {
|
---|
336 | throw new BuildException(INIT_FAILED_MSG + readerClassName, e);
|
---|
337 | }
|
---|
338 | }
|
---|
339 |
|
---|
340 | // then check it implements XMLReader
|
---|
341 | if (reader instanceof XMLReader) {
|
---|
342 | xmlReader = (XMLReader) reader;
|
---|
343 | log(
|
---|
344 | "Using SAX2 reader " + reader.getClass().getName(),
|
---|
345 | Project.MSG_VERBOSE);
|
---|
346 | } else {
|
---|
347 |
|
---|
348 | // see if it is a SAX1 Parser
|
---|
349 | if (reader instanceof Parser) {
|
---|
350 | xmlReader = new ParserAdapter((Parser) reader);
|
---|
351 | log(
|
---|
352 | "Using SAX1 parser " + reader.getClass().getName(),
|
---|
353 | Project.MSG_VERBOSE);
|
---|
354 | } else {
|
---|
355 | throw new BuildException(
|
---|
356 | INIT_FAILED_MSG
|
---|
357 | + reader.getClass().getName()
|
---|
358 | + " implements nor SAX1 Parser nor SAX2 XMLReader.");
|
---|
359 | }
|
---|
360 | }
|
---|
361 |
|
---|
362 | xmlReader.setEntityResolver(getEntityResolver());
|
---|
363 | xmlReader.setErrorHandler(errorHandler);
|
---|
364 |
|
---|
365 | if (!(xmlReader instanceof ParserAdapter)) {
|
---|
366 | // turn validation on
|
---|
367 | if (!lenient) {
|
---|
368 | setFeature("http://xml.org/sax/features/validation", true);
|
---|
369 | }
|
---|
370 | // set the feature from the attribute list
|
---|
371 | for (int i = 0; i < attributeList.size(); i++) {
|
---|
372 | Attribute feature = (Attribute) attributeList.elementAt(i);
|
---|
373 | setFeature(feature.getName(), feature.getValue());
|
---|
374 |
|
---|
375 | }
|
---|
376 |
|
---|
377 | // Sets properties
|
---|
378 | for (int i = 0; i < propertyList.size(); i++) {
|
---|
379 | final Property prop = (Property) propertyList.elementAt(i);
|
---|
380 | setProperty(prop.getName(), prop.getValue());
|
---|
381 | }
|
---|
382 | }
|
---|
383 | }
|
---|
384 |
|
---|
385 | /**
|
---|
386 | * Set a feature on the parser.
|
---|
387 | * @param feature the name of the feature to set
|
---|
388 | * @param value the value of the feature
|
---|
389 | */
|
---|
390 | private void setFeature(String feature, boolean value)
|
---|
391 | throws BuildException {
|
---|
392 |
|
---|
393 | try {
|
---|
394 | xmlReader.setFeature(feature, value);
|
---|
395 | } catch (SAXNotRecognizedException e) {
|
---|
396 | throw new BuildException(
|
---|
397 | "Parser "
|
---|
398 | + xmlReader.getClass().getName()
|
---|
399 | + " doesn't recognize feature "
|
---|
400 | + feature,
|
---|
401 | e,
|
---|
402 | getLocation());
|
---|
403 | } catch (SAXNotSupportedException e) {
|
---|
404 | throw new BuildException(
|
---|
405 | "Parser "
|
---|
406 | + xmlReader.getClass().getName()
|
---|
407 | + " doesn't support feature "
|
---|
408 | + feature,
|
---|
409 | e,
|
---|
410 | getLocation());
|
---|
411 | }
|
---|
412 | }
|
---|
413 |
|
---|
414 | /**
|
---|
415 | * Sets a property.
|
---|
416 | *
|
---|
417 | * @param name a property name
|
---|
418 | * @param value a property value.
|
---|
419 | * @throws BuildException if an error occurs.
|
---|
420 | */
|
---|
421 | private void setProperty(String name, String value) throws BuildException {
|
---|
422 | // Validates property
|
---|
423 | if (name == null || value == null) {
|
---|
424 | throw new BuildException("Property name and value must be specified.");
|
---|
425 | }
|
---|
426 |
|
---|
427 | try {
|
---|
428 | xmlReader.setProperty(name, value);
|
---|
429 | } catch (SAXNotRecognizedException e) {
|
---|
430 | throw new BuildException(
|
---|
431 | "Parser "
|
---|
432 | + xmlReader.getClass().getName()
|
---|
433 | + " doesn't recognize property "
|
---|
434 | + name,
|
---|
435 | e,
|
---|
436 | getLocation());
|
---|
437 | } catch (SAXNotSupportedException e) {
|
---|
438 | throw new BuildException(
|
---|
439 | "Parser "
|
---|
440 | + xmlReader.getClass().getName()
|
---|
441 | + " doesn't support property "
|
---|
442 | + name,
|
---|
443 | e,
|
---|
444 | getLocation());
|
---|
445 | }
|
---|
446 | }
|
---|
447 |
|
---|
448 | /**
|
---|
449 | * parse the file
|
---|
450 | */
|
---|
451 | private void doValidate(File afile) {
|
---|
452 | try {
|
---|
453 | log("Validating " + afile.getName() + "... ", Project.MSG_VERBOSE);
|
---|
454 | errorHandler.init(afile);
|
---|
455 | InputSource is = new InputSource(new FileInputStream(afile));
|
---|
456 | String uri = FILE_UTILS.toURI(afile.getAbsolutePath());
|
---|
457 | is.setSystemId(uri);
|
---|
458 | xmlReader.parse(is);
|
---|
459 | } catch (SAXException ex) {
|
---|
460 | if (failOnError) {
|
---|
461 | throw new BuildException(
|
---|
462 | "Could not validate document " + afile);
|
---|
463 | } else {
|
---|
464 | log("Could not validate document " + afile + ": " + ex.toString());
|
---|
465 | }
|
---|
466 | } catch (IOException ex) {
|
---|
467 | throw new BuildException(
|
---|
468 | "Could not validate document " + afile,
|
---|
469 | ex);
|
---|
470 | }
|
---|
471 |
|
---|
472 | if (errorHandler.getFailure()) {
|
---|
473 | if (failOnError) {
|
---|
474 | throw new BuildException(
|
---|
475 | afile + " is not a valid XML document.");
|
---|
476 | } else {
|
---|
477 | log(afile + " is not a valid XML document", Project.MSG_ERR);
|
---|
478 | }
|
---|
479 | }
|
---|
480 | }
|
---|
481 |
|
---|
482 | /**
|
---|
483 | * ValidatorErrorHandler role :
|
---|
484 | * <ul>
|
---|
485 | * <li> log SAX parse exceptions,
|
---|
486 | * <li> remember if an error occurred
|
---|
487 | * </ul>
|
---|
488 | */
|
---|
489 | protected class ValidatorErrorHandler implements ErrorHandler {
|
---|
490 |
|
---|
491 | protected File currentFile = null;
|
---|
492 | protected String lastErrorMessage = null;
|
---|
493 | protected boolean failed = false;
|
---|
494 | /**
|
---|
495 | * initialises the class
|
---|
496 | * @param file file used
|
---|
497 | */
|
---|
498 | public void init(File file) {
|
---|
499 | currentFile = file;
|
---|
500 | failed = false;
|
---|
501 | }
|
---|
502 | /**
|
---|
503 | * did an error happen during last parsing ?
|
---|
504 | * @return did an error happen during last parsing ?
|
---|
505 | */
|
---|
506 | public boolean getFailure() {
|
---|
507 | return failed;
|
---|
508 | }
|
---|
509 |
|
---|
510 | /**
|
---|
511 | * record a fatal error
|
---|
512 | * @param exception the fatal error
|
---|
513 | */
|
---|
514 | public void fatalError(SAXParseException exception) {
|
---|
515 | failed = true;
|
---|
516 | doLog(exception, Project.MSG_ERR);
|
---|
517 | }
|
---|
518 | /**
|
---|
519 | * receive notification of a recoverable error
|
---|
520 | * @param exception the error
|
---|
521 | */
|
---|
522 | public void error(SAXParseException exception) {
|
---|
523 | failed = true;
|
---|
524 | doLog(exception, Project.MSG_ERR);
|
---|
525 | }
|
---|
526 | /**
|
---|
527 | * receive notification of a warning
|
---|
528 | * @param exception the warning
|
---|
529 | */
|
---|
530 | public void warning(SAXParseException exception) {
|
---|
531 | // depending on implementation, XMLReader can yield hips of warning,
|
---|
532 | // only output then if user explicitly asked for it
|
---|
533 | if (warn) {
|
---|
534 | doLog(exception, Project.MSG_WARN);
|
---|
535 | }
|
---|
536 | }
|
---|
537 |
|
---|
538 | private void doLog(SAXParseException e, int logLevel) {
|
---|
539 |
|
---|
540 | log(getMessage(e), logLevel);
|
---|
541 | }
|
---|
542 |
|
---|
543 | private String getMessage(SAXParseException e) {
|
---|
544 | String sysID = e.getSystemId();
|
---|
545 | if (sysID != null) {
|
---|
546 | String name = sysID;
|
---|
547 | if (sysID.startsWith("file:")) {
|
---|
548 | try {
|
---|
549 | name = FILE_UTILS.fromURI(sysID);
|
---|
550 | } catch (Exception ex) {
|
---|
551 | // if this is not a valid file: just use the uri
|
---|
552 | }
|
---|
553 | }
|
---|
554 | int line = e.getLineNumber();
|
---|
555 | int col = e.getColumnNumber();
|
---|
556 | return name
|
---|
557 | + (line == -1
|
---|
558 | ? ""
|
---|
559 | : (":" + line + (col == -1 ? "" : (":" + col))))
|
---|
560 | + ": "
|
---|
561 | + e.getMessage();
|
---|
562 | }
|
---|
563 | return e.getMessage();
|
---|
564 | }
|
---|
565 | }
|
---|
566 |
|
---|
567 | /**
|
---|
568 | * The class to create to set a feature of the parser.
|
---|
569 | * @since ant1.6
|
---|
570 | */
|
---|
571 | public class Attribute {
|
---|
572 | /** The name of the attribute to set.
|
---|
573 | *
|
---|
574 | * Valid attributes <a href="http://www.saxproject.org/apidoc/org/xml/sax/package-summary.html#package_description">include.</a>
|
---|
575 | */
|
---|
576 | private String attributeName = null;
|
---|
577 |
|
---|
578 | /**
|
---|
579 | * The value of the feature.
|
---|
580 | **/
|
---|
581 | private boolean attributeValue;
|
---|
582 |
|
---|
583 | /**
|
---|
584 | * Set the feature name.
|
---|
585 | * @param name the name to set
|
---|
586 | */
|
---|
587 | public void setName(String name) {
|
---|
588 | attributeName = name;
|
---|
589 | }
|
---|
590 | /**
|
---|
591 | * Set the feature value to true or false.
|
---|
592 | * @param value feature value
|
---|
593 | */
|
---|
594 | public void setValue(boolean value) {
|
---|
595 | attributeValue = value;
|
---|
596 | }
|
---|
597 |
|
---|
598 | /**
|
---|
599 | * Gets the attribute name.
|
---|
600 | * @return the feature name
|
---|
601 | */
|
---|
602 | public String getName() {
|
---|
603 | return attributeName;
|
---|
604 | }
|
---|
605 |
|
---|
606 | /**
|
---|
607 | * Gets the attribute value.
|
---|
608 | * @return the feature value
|
---|
609 | */
|
---|
610 | public boolean getValue() {
|
---|
611 | return attributeValue;
|
---|
612 | }
|
---|
613 | }
|
---|
614 |
|
---|
615 | /**
|
---|
616 | * A Parser property.
|
---|
617 | * See <a href="http://xml.apache.org/xerces-j/properties.html">
|
---|
618 | * XML parser properties</a> for usable properties
|
---|
619 | * @since ant 1.6.2
|
---|
620 | */
|
---|
621 | public final class Property {
|
---|
622 |
|
---|
623 | private String name;
|
---|
624 | private String value;
|
---|
625 | /**
|
---|
626 | * accessor to the name of the property
|
---|
627 | * @return name of the property
|
---|
628 | */
|
---|
629 | public String getName() {
|
---|
630 | return name;
|
---|
631 | }
|
---|
632 | /**
|
---|
633 | * setter for the name of the property
|
---|
634 | * @param name name of the property
|
---|
635 | */
|
---|
636 | public void setName(String name) {
|
---|
637 | this.name = name;
|
---|
638 | }
|
---|
639 |
|
---|
640 | /**
|
---|
641 | * getter for the value of the property
|
---|
642 | * @return value of the property
|
---|
643 | */
|
---|
644 | public String getValue() {
|
---|
645 | return value;
|
---|
646 | }
|
---|
647 | /**
|
---|
648 | * sets the value of the property
|
---|
649 | * @param value value of the property
|
---|
650 | */
|
---|
651 | public void setValue(String value) {
|
---|
652 | this.value = value;
|
---|
653 | }
|
---|
654 |
|
---|
655 | } // Property
|
---|
656 |
|
---|
657 | }
|
---|