1 18 package org.apache.tools.ant.taskdefs.optional; 19 20 import org.apache.tools.ant.BuildException; 21 import org.apache.tools.ant.Project; 22 import org.apache.tools.ant.util.FileUtils; 23 import org.apache.tools.ant.util.XmlConstants; 24 import org.xml.sax.XMLReader ; 25 import org.xml.sax.SAXNotRecognizedException ; 26 import org.xml.sax.SAXNotSupportedException ; 27 import org.xml.sax.SAXException ; 28 29 import javax.xml.parsers.SAXParserFactory ; 30 import javax.xml.parsers.SAXParser ; 31 import javax.xml.parsers.ParserConfigurationException ; 32 import java.util.Iterator ; 33 import java.util.HashMap ; 34 import java.io.File ; 35 import java.net.MalformedURLException ; 36 37 48 49 public class SchemaValidate extends XMLValidateTask { 50 51 52 private HashMap schemaLocations = new HashMap (); 53 54 55 private boolean fullChecking = true; 56 57 60 private boolean disableDTD = false; 61 62 65 private SchemaLocation anonymousSchema; 66 67 69 public static final String ERROR_SAX_1 = "SAX1 parsers are not supported"; 70 71 72 public static final String ERROR_NO_XSD_SUPPORT 73 = "Parser does not support Xerces or JAXP schema features"; 74 75 76 public static final String ERROR_TOO_MANY_DEFAULT_SCHEMAS 77 = "Only one of defaultSchemaFile and defaultSchemaURL allowed"; 78 79 80 public static final String ERROR_PARSER_CREATION_FAILURE 81 = "Could not create parser"; 82 83 84 public static final String MESSAGE_ADDING_SCHEMA = "Adding schema "; 85 86 87 public static final String ERROR_DUPLICATE_SCHEMA 88 = "Duplicate declaration of schema "; 89 90 96 public void init() throws BuildException { 97 super.init(); 98 setLenient(false); 100 } 101 102 106 public boolean enableXercesSchemaValidation() { 107 try { 108 setFeature(XmlConstants.FEATURE_XSD, true); 109 setNoNamespaceSchemaProperty(XmlConstants.PROPERTY_NO_NAMESPACE_SCHEMA_LOCATION); 111 } catch (BuildException e) { 112 log(e.toString(), Project.MSG_VERBOSE); 113 return false; 114 } 115 return true; 116 } 117 118 122 private void setNoNamespaceSchemaProperty(String property) { 123 String anonSchema = getNoNamespaceSchemaURL(); 124 if (anonSchema != null) { 125 setProperty(property, anonSchema); 126 } 127 } 128 129 135 public boolean enableJAXP12SchemaValidation() { 136 try { 137 setProperty(XmlConstants.FEATURE_JAXP12_SCHEMA_LANGUAGE, XmlConstants.URI_XSD); 139 setNoNamespaceSchemaProperty(XmlConstants.FEATURE_JAXP12_SCHEMA_SOURCE); 141 } catch (BuildException e) { 142 log(e.toString(), Project.MSG_VERBOSE); 143 return false; 144 } 145 return true; 146 } 147 148 154 public void addConfiguredSchema(SchemaLocation location) { 155 log("adding schema " + location, Project.MSG_DEBUG); 156 location.validateNamespace(); 157 SchemaLocation old = (SchemaLocation) schemaLocations.get(location.getNamespace()); 158 if (old != null && !old.equals(location)) { 159 throw new BuildException(ERROR_DUPLICATE_SCHEMA + location); 160 } 161 schemaLocations.put(location.getNamespace(), location); 162 } 163 164 168 public void setFullChecking(boolean fullChecking) { 169 this.fullChecking = fullChecking; 170 } 171 172 176 protected void createAnonymousSchema() { 177 if (anonymousSchema == null) { 178 anonymousSchema = new SchemaLocation(); 179 } 180 anonymousSchema.setNamespace("(no namespace)"); 181 } 182 183 187 public void setNoNamespaceURL(String defaultSchemaURL) { 188 createAnonymousSchema(); 189 this.anonymousSchema.setUrl(defaultSchemaURL); 190 } 191 192 196 public void setNoNamespaceFile(File defaultSchemaFile) { 197 createAnonymousSchema(); 198 this.anonymousSchema.setFile(defaultSchemaFile); 199 } 200 201 205 public void setDisableDTD(boolean disableDTD) { 206 this.disableDTD = disableDTD; 207 } 208 209 215 protected void initValidator() { 216 super.initValidator(); 217 if (isSax1Parser()) { 219 throw new BuildException(ERROR_SAX_1); 220 } 221 222 setFeature(XmlConstants.FEATURE_NAMESPACES, true); 225 if (!enableXercesSchemaValidation() && !enableJAXP12SchemaValidation()) { 226 throw new BuildException(ERROR_NO_XSD_SUPPORT); 228 } 229 230 setFeature(XmlConstants.FEATURE_XSD_FULL_VALIDATION, fullChecking); 232 233 setFeatureIfSupported(XmlConstants.FEATURE_DISALLOW_DTD, disableDTD); 235 236 addSchemaLocations(); 238 } 239 240 246 protected XMLReader createDefaultReader() { 247 SAXParserFactory factory = SAXParserFactory.newInstance(); 248 factory.setValidating(true); 249 factory.setNamespaceAware(true); 250 XMLReader reader = null; 251 try { 252 SAXParser saxParser = factory.newSAXParser(); 253 reader = saxParser.getXMLReader(); 254 } catch (ParserConfigurationException e) { 255 throw new BuildException(ERROR_PARSER_CREATION_FAILURE, e); 256 } catch (SAXException e) { 257 throw new BuildException(ERROR_PARSER_CREATION_FAILURE, e); 258 } 259 return reader; 260 } 261 262 266 protected void addSchemaLocations() { 267 Iterator it = schemaLocations.values().iterator(); 268 StringBuffer buffer = new StringBuffer (); 269 int count = 0; 270 while (it.hasNext()) { 271 if (count > 0) { 272 buffer.append(' '); 273 } 274 SchemaLocation schemaLocation = (SchemaLocation) it.next(); 275 String tuple = schemaLocation.getURIandLocation(); 276 buffer.append(tuple); 277 log("Adding schema " + tuple, Project.MSG_VERBOSE); 278 count++; 279 } 280 if (count > 0) { 281 setProperty(XmlConstants.PROPERTY_SCHEMA_LOCATION, buffer.toString()); 282 } 283 284 } 285 286 290 protected String getNoNamespaceSchemaURL() { 291 if (anonymousSchema == null) { 292 return null; 293 } else { 294 return anonymousSchema.getSchemaLocationURL(); 295 } 296 } 297 298 304 protected void setFeatureIfSupported(String feature, boolean value) { 305 try { 306 getXmlReader().setFeature(feature, value); 307 } catch (SAXNotRecognizedException e) { 308 log("Not recognizied: " + feature, Project.MSG_VERBOSE); 309 } catch (SAXNotSupportedException e) { 310 log("Not supported: " + feature, Project.MSG_VERBOSE); 311 } 312 } 313 314 319 protected void onSuccessfulValidation(int fileProcessed) { 320 log(fileProcessed + MESSAGE_FILES_VALIDATED, Project.MSG_VERBOSE); 321 } 322 323 327 public static class SchemaLocation { 328 private String namespace; 329 330 private File file; 331 332 private String url; 333 334 335 public static final String ERROR_NO_URI = "No namespace URI"; 336 337 338 public static final String ERROR_TWO_LOCATIONS 339 = "Both URL and File were given for schema "; 340 341 342 public static final String ERROR_NO_FILE = "File not found: "; 343 344 345 public static final String ERROR_NO_URL_REPRESENTATION 346 = "Cannot make a URL of "; 347 348 349 public static final String ERROR_NO_LOCATION 350 = "No file or URL supplied for the schema "; 351 352 353 public SchemaLocation() { 354 } 355 356 360 public String getNamespace() { 361 return namespace; 362 } 363 364 368 public void setNamespace(String namespace) { 369 this.namespace = namespace; 370 } 371 372 376 public File getFile() { 377 return file; 378 } 379 380 385 public void setFile(File file) { 386 this.file = file; 387 } 388 389 393 public String getUrl() { 394 return url; 395 } 396 397 401 public void setUrl(String url) { 402 this.url = url; 403 } 404 405 410 public String getSchemaLocationURL() { 411 boolean hasFile = file != null; 412 boolean hasURL = isSet(url); 413 if (!hasFile && !hasURL) { 415 throw new BuildException(ERROR_NO_LOCATION + namespace); 416 } 417 if (hasFile && hasURL) { 418 throw new BuildException(ERROR_TWO_LOCATIONS + namespace); 419 } 420 String schema = url; 421 if (hasFile) { 422 if (!file.exists()) { 423 throw new BuildException(ERROR_NO_FILE + file); 424 } 425 426 try { 427 schema = FileUtils.getFileUtils().getFileURL(file).toString(); 428 } catch (MalformedURLException e) { 429 throw new BuildException(ERROR_NO_URL_REPRESENTATION + file, e); 431 } 432 } 433 return schema; 434 } 435 436 442 public String getURIandLocation() throws BuildException { 443 validateNamespace(); 444 StringBuffer buffer = new StringBuffer (); 445 buffer.append(namespace); 446 buffer.append(' '); 447 buffer.append(getSchemaLocationURL()); 448 return new String (buffer); 449 } 450 451 455 public void validateNamespace() { 456 if (!isSet(getNamespace())) { 457 throw new BuildException(ERROR_NO_URI); 458 } 459 } 460 461 466 private boolean isSet(String property) { 467 return property != null && property.length() != 0; 468 } 469 470 475 476 public boolean equals(Object o) { 477 if (this == o) { 478 return true; 479 } 480 if (!(o instanceof SchemaLocation)) { 481 return false; 482 } 483 484 final SchemaLocation schemaLocation = (SchemaLocation) o; 485 486 if (file != null ? !file.equals(schemaLocation.file) : schemaLocation.file != null) { 487 return false; 488 } 489 if (namespace != null ? !namespace.equals(schemaLocation.namespace) 490 : schemaLocation.namespace != null) { 491 return false; 492 } 493 if (url != null ? !url.equals(schemaLocation.url) : schemaLocation.url != null) { 494 return false; 495 } 496 497 return true; 498 } 499 500 504 public int hashCode() { 505 int result; 506 result = (namespace != null ? namespace.hashCode() : 0); 507 result = 29 * result + (file != null ? file.hashCode() : 0); 508 result = 29 * result + (url != null ? url.hashCode() : 0); 509 return result; 510 } 511 512 517 public String toString() { 518 StringBuffer buffer = new StringBuffer (); 519 buffer.append(namespace != null ? namespace : "(anonymous)"); 520 buffer.append(' '); 521 buffer.append(url != null ? (url + " ") : ""); 522 buffer.append(file != null ? file.getAbsolutePath() : ""); 523 return buffer.toString(); 524 } 525 } } 527 | Popular Tags |