Changeset 5382
- Timestamp:
- 06/24/14 15:15:32 (10 years ago)
- Location:
- CMDIValidator/trunk
- Files:
-
- 4 added
- 5 deleted
- 5 edited
- 3 moved
Legend:
- Unmodified
- Added
- Removed
-
CMDIValidator/trunk/cmdi-validator-core/pom.xml
r5336 r5382 6 6 <groupId>eu.clarin.cmdi</groupId> 7 7 <artifactId>cmdi-validator</artifactId> 8 <version>0.0. 4-SNAPSHOT</version>8 <version>0.0.5-SNAPSHOT</version> 9 9 </parent> 10 10 <artifactId>cmdi-validator-core</artifactId> -
CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDISchemaLoader.java
r5369 r5382 25 25 import org.slf4j.LoggerFactory; 26 26 27 final classSchemaLoader {28 static final long DISABLE_CACHE_AGING = -1;27 public final class CMDISchemaLoader { 28 public static final long DISABLE_CACHE_AGING = -1; 29 29 private static final Logger logger = 30 LoggerFactory.getLogger( SchemaLoader.class);30 LoggerFactory.getLogger(CMDISchemaLoader.class); 31 31 private static final String XML_XSD_RESSOURCE = "/xml.xsd"; 32 32 private final File cacheDirectory; … … 35 35 36 36 37 SchemaLoader(File cacheDirectory, long maxCacheAge) {37 public CMDISchemaLoader(File cacheDirectory, long maxCacheAge) { 38 38 if (cacheDirectory == null) { 39 39 throw new NullPointerException("cacheDirectory == null"); … … 43 43 } 44 44 this.cacheDirectory = cacheDirectory; 45 this.maxCacheAge = maxCacheAge;46 this.httpClient = new DefaultHttpClient();45 this.maxCacheAge = maxCacheAge; 46 this.httpClient = new DefaultHttpClient(); 47 47 48 48 final HttpParams params = this.httpClient.getParams(); … … 55 55 56 56 57 public CMDISchemaLoader(File cacheDirectory) { 58 this(cacheDirectory, DISABLE_CACHE_AGING); 59 } 60 61 57 62 public synchronized InputStream loadSchemaFile(String targetNamespace, 58 63 String schemaLocation) throws IOException { … … 64 69 } 65 70 66 logger. debug("loading schema: targetNamespace={}, location={}",71 logger.trace("loading schema: targetNamespace={}, location={}", 67 72 targetNamespace, schemaLocation); 68 73 InputStream stream = null; … … 70 75 stream = this.getClass().getResourceAsStream(XML_XSD_RESSOURCE); 71 76 if (stream != null) { 72 logger. debug("using bundled schema for '{}'", schemaLocation);77 logger.trace("using bundled schema for '{}'", schemaLocation); 73 78 return stream; 74 79 } … … 77 82 } 78 83 79 final String key = stripBadChars(schemaLocation);80 81 84 // fall back to file cache ... 82 final File cacheFile = makeCacheFile( key);85 final File cacheFile = makeCacheFile(schemaLocation); 83 86 if (cacheFile.exists()) { 84 87 final long age = 85 88 System.currentTimeMillis() - cacheFile.lastModified(); 86 89 if ((maxCacheAge != DISABLE_CACHE_AGING) && (age > maxCacheAge)) { 87 logger. debug("-> cached file '{}' expired", cacheFile);90 logger.trace("-> cached file '{}' expired", cacheFile); 88 91 cacheFile.delete(); 89 92 } else { 90 logger. debug("-> from file cache");93 logger.trace("-> from file cache"); 91 94 return new FileInputStream(cacheFile); 92 95 } … … 94 97 95 98 try { 96 logger.debug(" ->downloading schema from '{}'", schemaLocation);99 logger.debug("downloading schema from '{}'", schemaLocation); 97 100 final URI uri = new URI(schemaLocation); 98 101 final HttpResponse response = executeRequest(uri); … … 134 137 135 138 136 private File makeCacheFile(String key) { 137 return new File(cacheDirectory, key + ".xsd"); 138 } 139 140 141 private static String stripBadChars(String uri) { 139 private File makeCacheFile(String schemaLocation) { 142 140 final StringBuilder sb = new StringBuilder(); 143 for (int i = 0; i < uri.length(); i++) {144 final char c = uri.charAt(i);141 for (int i = 0; i < schemaLocation.length(); i++) { 142 final char c = schemaLocation.charAt(i); 145 143 switch (c) { 144 case '.': 145 /* FALL-THROUGH */ 146 146 case ':': 147 147 /* FALL-THROUGH */ 148 case ';': 149 /* FALL-THROUGH */ 150 case '?': 151 /* FALL-THROUGH */ 152 case '&': 153 /* FALL-THROUGH */ 154 case '=': 155 /* FALL-THROUGH */ 156 case '"': 157 /* FALL-THROUGH */ 158 case '\'': 159 /* FALL-THROUGH */ 148 160 case '/': 149 /* FALL-THROUGH */150 case '?':151 /* FALL-THROUGH */152 case '&':153 /* FALL-THROUGH */154 case '=':155 /* FALL-THROUGH */156 case '.':157 /* FALL-THROUGH */158 case ';':159 /* FALL-THROUGH */160 case '"':161 /* FALL-THROUGH */162 case '\'':163 161 /* FALL-THROUGH */ 164 162 case '\\': … … 168 166 sb.append(c); 169 167 } 170 } 171 return sb.toString(); 168 } // for 169 sb.append(".xsd"); 170 return new File(cacheDirectory, sb.toString()); 172 171 } 173 172 … … 177 176 HttpResponse response = null; 178 177 try { 179 logger. debug("submitting HTTP request: {}", uri.toString());178 logger.trace("submitting HTTP request: {}", uri.toString()); 180 179 request = new HttpGet(uri); 181 180 response = httpClient.execute(request); … … 212 211 } 213 212 214 } // class SchemaLoader213 } // class CMDISchemaLoader -
CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidator.java
r5370 r5382 2 2 3 3 import java.io.File; 4 import java.io.FileFilter; 4 5 import java.io.IOException; 5 6 import java.io.InputStream; 7 import java.net.MalformedURLException; 8 import java.net.URL; 9 import java.util.Collections; 6 10 import java.util.LinkedHashSet; 11 import java.util.LinkedList; 7 12 import java.util.List; 8 13 import java.util.Map; 9 14 import java.util.Set; 15 import java.util.concurrent.ConcurrentHashMap; 16 import java.util.concurrent.atomic.AtomicInteger; 10 17 11 18 import javax.xml.XMLConstants; 12 19 import javax.xml.transform.dom.DOMSource; 13 20 import javax.xml.transform.stream.StreamSource; 21 22 import net.java.truevfs.access.TFile; 23 import net.java.truevfs.access.TFileInputStream; 14 24 import net.sf.saxon.s9api.Axis; 15 25 import net.sf.saxon.s9api.DocumentBuilder; … … 25 35 import net.sf.saxon.s9api.XdmNode; 26 36 import net.sf.saxon.s9api.XdmSequenceIterator; 37 import net.sf.saxon.s9api.XsltCompiler; 27 38 import net.sf.saxon.s9api.XsltExecutable; 28 39 import net.sf.saxon.s9api.XsltTransformer; 29 40 41 import org.apache.commons.lang3.SystemUtils; 30 42 import org.apache.xerces.impl.xs.XMLSchemaLoader; 31 43 import org.apache.xerces.impl.xs.XSDDescription; … … 53 65 54 66 public final class CMDIValidator { 67 public enum Result { 68 OK, ABORTED, ERROR 69 } 55 70 private static final Logger logger = 56 71 LoggerFactory.getLogger(CMDIValidator.class); 72 private static final String SCHEMATATRON_STAGE_1 = 73 "/schematron/iso_dsdl_include.xsl"; 74 private static final String SCHEMATATRON_STAGE_2 = 75 "/schematron/iso_abstract_expand.xsl"; 76 private static final String SCHEMATATRON_STAGE_3 = 77 "/schematron/iso_svrl_for_xslt2.xsl"; 78 private static final String DEFAULT_SCHEMATRON_SCHEMA = 79 "/default.sch"; 57 80 private static final String XML_SCHEMA_LOCATION = 58 81 "http://www.w3.org/2001/xml.xsd"; … … 72 95 "http://apache.org/xml/features/honour-all-schemaLocations"; 73 96 private static final int INITAL_SYMBOL_TABLE_SIZE = 16141; 74 private static final String SVRL_NAMESPACE_URI = "http://purl.oclc.org/dsdl/svrl"; 75 private static final String SVRL_NAMESPACE_PREFIX = "svrl"; 97 private static final String SVRL_NAMESPACE_URI = 98 "http://purl.oclc.org/dsdl/svrl"; 99 private static final String SVRL_NAMESPACE_PREFIX = 100 "svrl"; 76 101 private static final QName SVRL_TEXT = 77 102 new QName(SVRL_NAMESPACE_URI, "text"); … … 79 104 new QName(SVRL_NAMESPACE_URI, "failed-assert"); 80 105 private final Processor processor; 106 private final CMDISchemaLoader schemaLoader; 107 private final XsltExecutable schematronValidatorExecutable; 81 108 private final XPathExecutable xpath1; 82 109 private final XPathExecutable xpath2; 83 private final XsltTransformer schematronValidator;84 private final XML11Configuration config;85 private final DocumentBuilder builder;86 110 private final List<CMDIValidatorExtension> extensions; 87 private final CMDIValidatorResultImpl result; 88 89 90 CMDIValidator(final Processor processor, 91 final SchemaLoader schemaLoader, 92 XsltExecutable schematronExecutable, 93 List<CMDIValidatorExtension> extensions) 111 private final FileEnumerator files; 112 private final CMDIValidatorHandler handler; 113 private final Map<Thread, ThreadContext> contexts = 114 new ConcurrentHashMap<Thread, ThreadContext>(); 115 private final AtomicInteger threadsProcessing = new AtomicInteger(); 116 private State state = State.INIT; 117 private Result result = null; 118 119 120 public CMDIValidator(final CMDIValidatorConfig config) 94 121 throws CMDIValidatorInitException { 95 if (processor == null) { 96 throw new NullPointerException("processor == null"); 97 } 98 this.processor = processor; 99 if (schematronExecutable != null) { 122 if (config == null) { 123 throw new NullPointerException("config == null"); 124 } 125 126 /* 127 * initialize custom schema loader 128 */ 129 if (config.getSchemaLoader() != null) { 130 logger.debug("using supplied schema loader ..."); 131 this.schemaLoader = config.getSchemaLoader(); 132 } else { 133 logger.debug("initializing schema loader ..."); 134 this.schemaLoader = initSchemaLoader(config); 135 } 136 137 /* 138 * initialize Saxon processor 139 */ 140 logger.debug("initializing Saxon ..."); 141 this.processor = new Processor(true); 142 143 /* 144 * initialize Schematron validator 145 */ 146 if (!config.isSchematronDisabled()) { 147 this.schematronValidatorExecutable = 148 initSchematronValidator(config, processor); 100 149 try { 101 150 final XPathCompiler compiler = processor.newXPathCompiler(); … … 103 152 this.xpath1 = compiler.compile("//(svrl:failed-assert|svrl:successful-report)"); 104 153 this.xpath2 = compiler.compile("preceding-sibling::svrl:fired-rule/@role"); 105 this.schematronValidator = schematronExecutable.load();106 154 } catch (SaxonApiException e) { 107 155 throw new CMDIValidatorInitException( 108 "error initializing validator", e); 109 } 156 "error initializing schematron validator", e); 157 } 158 logger.debug("Schematron validator successfully initialized"); 110 159 } else { 111 this.xpath1 = null; 112 this.xpath2 = null; 113 this.schematronValidator = null; 114 } 115 160 this.schematronValidatorExecutable = null; 161 this.xpath1 = null; 162 this.xpath2 = null; 163 } 164 165 /* 166 * initialize extensions 167 */ 168 final List<CMDIValidatorExtension> exts = config.getExtensions(); 169 if (exts != null) { 170 this.extensions = new LinkedList<CMDIValidatorExtension>(); 171 for (CMDIValidatorExtension extension : exts) { 172 extension.initalize(processor); 173 extensions.add(extension); 174 } 175 } else { 176 this.extensions = null; 177 } 178 179 /* 180 * other stuff 181 */ 182 final TFile root = new TFile(config.getRoot()); 183 this.files = new FileEnumerator(root, config.getFileFilter()); 184 if (config.getHandler() == null) { 185 throw new NullPointerException("handler == null"); 186 } 187 this.handler = config.getHandler(); 188 } 189 190 191 public CMDIValidatorHandler getHandler() { 192 return handler; 193 } 194 195 196 public void abort() { 197 synchronized (this) { 198 if ((state == State.INIT) || (state == State.RUN)) { 199 state = State.DONE; 200 files.flush(); 201 if (result == null) { 202 result = Result.ABORTED; 203 } 204 } 205 } // synchronized (this) 206 } 207 208 209 boolean processOneFile() throws CMDIValidatorException { 116 210 try { 211 TFile file = null; 212 boolean done; 213 214 threadsProcessing.incrementAndGet(); 215 216 synchronized (this) { 217 switch (state) { 218 case INIT: 219 try { 220 state = State.RUN; 221 handler.onJobStarted(); 222 } catch (CMDIValidatorException e) { 223 state = State.DONE; 224 throw e; 225 } 226 /* FALL-THROUGH */ 227 case RUN: 228 file = files.nextFile(); 229 if (files.isEmpty() && (state == State.RUN)) { 230 state = State.DONE; 231 } 232 break; 233 default: 234 // ignore 235 } 236 237 done = (state == State.DONE); 238 } // synchronized (this) 239 240 if (file != null) { 241 ThreadContext context = contexts.get(Thread.currentThread()); 242 if (context == null) { 243 context = new ThreadContext(); 244 contexts.put(Thread.currentThread(), context); 245 } 246 context.validate(file); 247 } 248 249 return done; 250 } catch (CMDIValidatorException e) { 251 synchronized (this) { 252 state = State.DONE; 253 if (result == null) { 254 result = Result.ERROR; 255 } 256 } // synchronized (this) 257 throw e; 258 } finally { 259 if (threadsProcessing.decrementAndGet() <= 0) { 260 synchronized (this) { 261 if (state == State.DONE) { 262 state = State.FINI; 263 if (result == null) { 264 result = Result.OK; 265 } 266 267 // notify handler 268 handler.onJobFinished(result); 269 } 270 } // synchronized (this) 271 } 272 } 273 } 274 275 276 private static CMDISchemaLoader initSchemaLoader( 277 final CMDIValidatorConfig config) throws CMDIValidatorInitException { 278 File cacheDirectory = config.getSchemaCacheDirectory(); 279 if (cacheDirectory == null) { 280 if (SystemUtils.IS_OS_WINDOWS && 281 (SystemUtils.JAVA_IO_TMPDIR != null)) { 282 cacheDirectory = 283 new File(SystemUtils.JAVA_IO_TMPDIR, "cmdi-validator"); 284 } else if (SystemUtils.IS_OS_UNIX && 285 (SystemUtils.USER_HOME != null)) { 286 cacheDirectory = 287 new File(SystemUtils.USER_HOME, ".cmdi-validator"); 288 } 289 if (cacheDirectory != null) { 290 if (!cacheDirectory.exists()) { 291 if (!cacheDirectory.mkdir()) { 292 throw new CMDIValidatorInitException( 293 "cannot create cache directory: " + 294 cacheDirectory); 295 } 296 } 297 } else { 298 if (SystemUtils.JAVA_IO_TMPDIR == null) { 299 throw new CMDIValidatorInitException( 300 "cannot determine temporary directory"); 301 } 302 cacheDirectory = new File(SystemUtils.JAVA_IO_TMPDIR); 303 } 304 } else { 305 if (!cacheDirectory.isDirectory()) { 306 throw new CMDIValidatorInitException( 307 "supplied cache dircetory '" + 308 cacheDirectory.getAbsolutePath() + 309 "' is not a directory"); 310 } 311 if (!cacheDirectory.canWrite()) { 312 throw new CMDIValidatorInitException("cache dircetory '" + 313 cacheDirectory.getAbsolutePath() + "' is not writable"); 314 } 315 } 316 return new CMDISchemaLoader(cacheDirectory, CMDISchemaLoader.DISABLE_CACHE_AGING); 317 } 318 319 320 private static XsltExecutable initSchematronValidator( 321 final CMDIValidatorConfig config, final Processor processor) 322 throws CMDIValidatorInitException { 323 URL schema = null; 324 File schematronSchemaFile = config.getSchematronSchemaFile(); 325 if (schematronSchemaFile != null) { 326 if (!schematronSchemaFile.exists()) { 327 throw new CMDIValidatorInitException("file '" + 328 schematronSchemaFile.getAbsolutePath() + 329 "' does not exist"); 330 } 331 if (!schematronSchemaFile.isFile()) { 332 throw new CMDIValidatorInitException("file '" + 333 schematronSchemaFile.getAbsolutePath() + 334 "' is not a regular file"); 335 } 336 if (!schematronSchemaFile.canRead()) { 337 throw new CMDIValidatorInitException("file '" + 338 schematronSchemaFile.getAbsolutePath() + 339 "' cannot be read"); 340 } 341 try { 342 schema = schematronSchemaFile.toURI().toURL(); 343 } catch (MalformedURLException e) { 344 throw new CMDIValidatorInitException("internal error", e); 345 } 346 } else { 347 schema = CMDIValidator.class.getResource(DEFAULT_SCHEMATRON_SCHEMA); 348 if (schema == null) { 349 throw new CMDIValidatorInitException( 350 "cannot locate bundled Schematron schema: " + 351 DEFAULT_SCHEMATRON_SCHEMA); 352 } 353 } 354 final XsltCompiler compiler = processor.newXsltCompiler(); 355 XsltTransformer stage1 = 356 loadStylesheet(processor, compiler, SCHEMATATRON_STAGE_1); 357 XsltTransformer stage2 = 358 loadStylesheet(processor, compiler, SCHEMATATRON_STAGE_2); 359 XsltTransformer stage3 = 360 loadStylesheet(processor, compiler, SCHEMATATRON_STAGE_3); 361 try { 362 XdmDestination destination = new XdmDestination(); 363 stage1.setSource(new StreamSource(schema.toExternalForm())); 364 stage1.setDestination(stage2); 365 stage2.setDestination(stage3); 366 stage3.setDestination(destination); 367 stage1.transform(); 368 return compiler.compile(destination.getXdmNode().asSource()); 369 } catch (SaxonApiException e) { 370 throw new CMDIValidatorInitException( 371 "error compiling schematron rules", e); 372 } 373 } 374 375 376 private static XsltTransformer loadStylesheet(final Processor processor, 377 final XsltCompiler compiler, final String name) 378 throws CMDIValidatorInitException { 379 try { 380 logger.debug("loading stylesheet '{}'", name); 381 final URL uri = CMDIValidator.class.getResource(name); 382 if (uri != null) { 383 DocumentBuilder builder = processor.newDocumentBuilder(); 384 XdmNode source = 385 builder.build(new StreamSource(uri.toExternalForm())); 386 XsltExecutable stylesheet = compiler.compile(source.asSource()); 387 return stylesheet.load(); 388 } else { 389 throw new CMDIValidatorInitException("cannot find resource '" + 390 name + "'"); 391 } 392 } catch (SaxonApiException e) { 393 throw new CMDIValidatorInitException( 394 "error loading schematron stylesheet '" + name + "'", e); 395 } 396 } 397 398 399 private enum State { 400 INIT, RUN, DONE, FINI; 401 } 402 403 404 private final class ThreadContext { 405 private final XML11Configuration xercesConfig; 406 private final XsltTransformer schematronValidator; 407 private final DocumentBuilder builder; 408 private final ResultImpl result = new ResultImpl(); 409 410 411 private ThreadContext() { 117 412 /* 118 413 * initialize Xerces 119 414 */ 120 XMLEntityResolver resolver = new XMLEntityResolver() {415 final XMLEntityResolver resolver = new XMLEntityResolver() { 121 416 @Override 122 417 public XMLInputSource resolveEntity( … … 125 420 final String uri = identifier.getExpandedSystemId(); 126 421 if (uri == null) { 127 throw new IOException("bad schema location for namespace '" + 422 throw new IOException( 423 "bad schema location for namespace '" + 128 424 identifier.getNamespace() + "': " + 129 425 identifier.getLiteralSystemId()); … … 148 444 } 149 445 446 150 447 @Override 151 448 public void error(String domain, String key, XMLParseException e) … … 154 451 } 155 452 453 156 454 @Override 157 455 public void fatalError(String domain, String key, … … 161 459 }); 162 460 163 InputStream stream = null;164 461 try { 165 stream = schemaLoader.loadSchemaFile(XMLConstants.XML_NS_URI, 166 XML_SCHEMA_LOCATION); 167 Grammar grammar = xsdLoader.loadGrammar( 168 new XMLInputSource(XMLConstants.XML_NS_URI, 169 XML_SCHEMA_LOCATION, null, stream, null)); 170 if (grammar != null) { 171 pool.cacheGrammars(XML_SCHEMA_GRAMMAR_TYPE, 172 new Grammar[] { grammar }); 173 } 174 pool.lockPool(); 175 } finally { 176 if (stream != null) { 177 stream.close(); 178 } 179 } 180 181 config = new XML11Configuration(symbols, pool); 182 config.setFeature(NAMESPACES_FEATURE_ID, true); 183 config.setFeature(VALIDATION_FEATURE_ID, true); 184 config.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true); 185 config.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true); 186 config.setFeature(HONOUR_ALL_SCHEMA_LOCATIONS_ID, true); 187 config.setEntityResolver(resolver); 188 config.setErrorHandler(new XMLErrorHandler() { 462 InputStream stream = null; 463 try { 464 stream = schemaLoader.loadSchemaFile( 465 XMLConstants.XML_NS_URI, XML_SCHEMA_LOCATION); 466 Grammar grammar = xsdLoader.loadGrammar(new XMLInputSource( 467 XMLConstants.XML_NS_URI, XML_SCHEMA_LOCATION, null, 468 stream, null)); 469 if (grammar != null) { 470 pool.cacheGrammars(XML_SCHEMA_GRAMMAR_TYPE, 471 new Grammar[] { grammar }); 472 } 473 pool.lockPool(); 474 } finally { 475 if (stream != null) { 476 stream.close(); 477 } 478 } 479 } catch (IOException e) { 480 /* 481 * Should never happen 482 */ 483 logger.error("error initaliting thread context", e); 484 } 485 486 xercesConfig = new XML11Configuration(symbols, pool); 487 xercesConfig.setFeature(NAMESPACES_FEATURE_ID, true); 488 xercesConfig.setFeature(VALIDATION_FEATURE_ID, true); 489 xercesConfig.setFeature(SCHEMA_VALIDATION_FEATURE_ID, true); 490 xercesConfig.setFeature(SCHEMA_FULL_CHECKING_FEATURE_ID, true); 491 xercesConfig.setFeature(HONOUR_ALL_SCHEMA_LOCATIONS_ID, true); 492 xercesConfig.setEntityResolver(resolver); 493 xercesConfig.setErrorHandler(new XMLErrorHandler() { 189 494 @Override 190 495 public void warning(String domain, String key, 191 496 XMLParseException e) throws XNIException { 192 reportWarning(e.getLineNumber(), e.getColumnNumber(), 497 reportWarning(e.getLineNumber(), 498 e.getColumnNumber(), 193 499 e.getMessage(), e); 194 500 } 195 501 502 196 503 @Override 197 public void error(String domain, String key, XMLParseException e) 198 throws XNIException { 199 reportError(e.getLineNumber(), e.getColumnNumber(), 504 public void error(String domain, String key, 505 XMLParseException e) throws XNIException { 506 reportError(e.getLineNumber(), 507 e.getColumnNumber(), 200 508 e.getMessage(), e); 201 509 throw e; 202 510 } 511 203 512 204 513 @Override 205 514 public void fatalError(String domain, String key, 206 515 XMLParseException e) throws XNIException { 207 reportError(e.getLineNumber(), e.getColumnNumber(), 516 reportError(e.getLineNumber(), 517 e.getColumnNumber(), 208 518 e.getMessage(), e); 209 519 throw e; … … 214 524 * initialize Saxon document builder 215 525 */ 216 this.builder = this.processor.newDocumentBuilder();526 this.builder = processor.newDocumentBuilder(); 217 527 this.builder.setWhitespaceStrippingPolicy( 218 528 WhitespaceStrippingPolicy.IGNORABLE); 219 529 220 530 /* 221 * extensions531 * initialize schematron 222 532 */ 223 this.extensions = extensions; 224 225 /* 226 * initialize other stuff 227 */ 228 this.result = new CMDIValidatorResultImpl(); 229 } catch (IOException e) { 230 throw new CMDIValidatorInitException("initialization failed", e); 533 if (schematronValidatorExecutable != null) { 534 this.schematronValidator = schematronValidatorExecutable.load(); 535 } else { 536 this.schematronValidator = null; 537 } 538 } 539 540 541 private void validate(final TFile file) throws CMDIValidatorException { 542 TFileInputStream stream = null; 543 try { 544 /* 545 * step 0: prepare 546 */ 547 logger.debug("validating file '{}' ({} bytes)", 548 file, file.length()); 549 result.setFile(file); 550 stream = new TFileInputStream(file); 551 552 /* 553 * step 1: parse document and perform schema validation 554 */ 555 final XdmNode document = parseInstance(stream); 556 557 if (document != null) { 558 /* 559 * step 2: perform Schematron validation 560 */ 561 if (schematronValidator != null) { 562 validateSchematron(document); 563 } 564 565 /* 566 * step 3: run extensions, if any 567 */ 568 if (extensions != null) { 569 for (CMDIValidatorExtension extension : extensions) { 570 extension.validate(document, result); 571 } 572 } 573 } 574 } catch (IOException e) { 575 throw new CMDIValidatorException( 576 "error reading file '" + file + "'", e); 577 } catch (CMDIValidatorException e) { 578 throw e; 579 } finally { 580 try { 581 if (stream != null) { 582 stream.close(); 583 } 584 } catch (IOException e) { 585 throw new CMDIValidatorException( 586 "error closing file '" + file + "'", e); 587 } finally { 588 if (handler != null) { 589 if (result.isHighestSeverity(Severity.ERROR)) { 590 handler.onValidationFailure(result); 591 } else { 592 handler.onValidationSuccess(result); 593 } 594 } 595 result.reset(); 596 } 597 } 598 } 599 600 601 private XdmNode parseInstance(InputStream stream) 602 throws CMDIValidatorException { 603 try { 604 final DOMParser parser = new DOMParser(xercesConfig); 605 try { 606 parser.parse(new InputSource(stream)); 607 stream.close(); 608 609 final Document dom = parser.getDocument(); 610 if (dom == null) { 611 throw new CMDIValidatorException( 612 "parser returned no return result"); 613 } 614 return builder.build(new DOMSource(dom)); 615 } finally { 616 parser.reset(); 617 } 618 } catch (SAXException e) { 619 logger.trace("error parsing instance", e); 620 return null; 621 } catch (SaxonApiException e) { 622 logger.trace("error parsing instance", e); 623 return null; 624 } catch (IOException e) { 625 final String message = (e.getMessage() != null) 626 ? e.getMessage() 627 : "input/output error"; 628 throw new CMDIValidatorException(message, e); 629 } finally { 630 /* really make sure, stream is closed */ 631 try { 632 stream.close(); 633 } catch (IOException e) { 634 /* IGNORE */ 635 } 636 } 637 } 638 639 640 private void validateSchematron(XdmNode document) 641 throws CMDIValidatorException { 642 try { 643 logger.trace("performing schematron validation ..."); 644 schematronValidator.setSource(document.asSource()); 645 final XdmDestination destination = new XdmDestination(); 646 schematronValidator.setDestination(destination); 647 schematronValidator.transform(); 648 649 final XPathSelector selector = xpath1.load(); 650 selector.setContextItem(destination.getXdmNode()); 651 for (XdmItem item : selector) { 652 final XdmNode node = (XdmNode) item; 653 final XdmNode text = getFirstChild(node, SVRL_TEXT); 654 String msg = (text != null) 655 ? text.getStringValue().trim() 656 : null; 657 if (SVRL_FAILED_ASSERT.equals(node.getNodeName())) { 658 final XPathSelector selector2 = xpath2.load(); 659 String role = null; 660 selector2.setContextItem(node); 661 XdmItem evaluateSingle = selector2.evaluateSingle(); 662 if (evaluateSingle != null) { 663 role = evaluateSingle.getStringValue().trim(); 664 } 665 if ("warning".equalsIgnoreCase(role)) { 666 result.reportWarning(-1, -1, msg); 667 } else { 668 result.reportError(-1, -1, msg); 669 } 670 } else { 671 result.reportInfo(-1, -1, msg); 672 } 673 } 674 } catch (SaxonApiException e) { 675 throw new CMDIValidatorException( 676 "error performing schematron validation", e); 677 } 678 } 679 680 681 private XdmNode getFirstChild(XdmNode parent, QName name) { 682 XdmSequenceIterator i = parent.axisIterator(Axis.CHILD, name); 683 if (i.hasNext()) { 684 return (XdmNode) i.next(); 685 } else { 686 return null; 687 } 688 } 689 690 691 private void reportWarning(int line, int col, String message, 692 Throwable cause) { 693 logger.debug("reporting warning: [{}:{}]: {}", line, col, message); 694 if (result != null) { 695 result.reportWarning(line, col, message, cause); 696 } 697 } 698 699 700 private void reportError(int line, int col, String message, 701 Throwable cause) { 702 logger.debug("reporting error: [{}:{}]: {}", line, col, message); 703 if (result != null) { 704 result.reportError(line, col, message, cause); 705 } 231 706 } 232 707 } 233 708 234 709 235 public void validate(InputStream stream, File file, 236 CMDIValidatorJobHandler handler) throws CMDIValidatorException { 237 if (stream == null) { 238 throw new NullPointerException("stream == null"); 239 } 240 241 try { 242 result.setFile(file); 243 244 /* 245 * step 1: parse document and perform schema validation 246 */ 247 final XdmNode document = parseInstance(stream); 248 249 if (document != null) { 250 /* 251 * step 2: perform Schematron validation 252 */ 253 if (schematronValidator != null) { 254 validateSchematron(document); 255 } 256 257 /* 258 * step 3: run extensions, if any 259 */ 260 if (extensions != null) { 261 for (CMDIValidatorExtension extension : extensions) { 262 extension.validate(document, result); 263 } 264 } 710 private static final class FileEnumerator { 711 private final class FileList { 712 private final TFile[] fileList; 713 private int idx = 0; 714 715 716 private FileList(TFile[] fileList) { 717 this.fileList = fileList; 718 } 719 720 721 private TFile nextFile() { 722 while (idx < fileList.length) { 723 final TFile file = fileList[idx++]; 724 if (file.isDirectory()) { 725 return file; 726 } 727 if ((filter != null) && !filter.accept(file)) { 728 continue; 729 } 730 return file; 731 } // while 732 return null; 733 } 734 735 private int size() { 736 return (fileList.length - idx); 737 } 738 } 739 private final FileFilter filter; 740 private final LinkedList<FileList> stack = 741 new LinkedList<FileList>(); 742 743 744 FileEnumerator(TFile root, FileFilter filter) { 745 if (root == null) { 746 throw new NullPointerException("root == null"); 747 } 748 if (root.isDirectory()) { 749 pushDirectory(root); 265 750 } else { 266 logger.debug("parseInstance() returned no result"); 267 } 268 } catch (CMDIValidatorException e) { 269 throw e; 270 } finally { 271 if (handler != null) { 272 if (result.isHighestSeverity(Severity.ERROR)) { 273 handler.onValidationFailure(result); 274 } else { 275 handler.onValidationSuccess(result); 276 } 277 } 278 result.reset(); 279 } 280 } 281 282 283 private XdmNode parseInstance(InputStream stream) 284 throws CMDIValidatorException { 285 try { 286 final DOMParser parser = new DOMParser(config); 287 try { 288 parser.parse(new InputSource(stream)); 289 stream.close(); 290 291 final Document dom = parser.getDocument(); 292 if (dom == null) { 293 throw new CMDIValidatorException( 294 "parser returned no return result"); 295 } 296 return builder.build(new DOMSource(dom)); 297 } finally { 298 parser.reset(); 299 } 300 } catch (XNIException e) { 301 throw new CMDIValidatorException(e.getMessage(), e); 302 } catch (SaxonApiException e) { 303 throw new CMDIValidatorException(e.getMessage(), e); 304 } catch (SAXException e) { 305 throw new CMDIValidatorException(e.getMessage(), e); 306 } catch (IOException e) { 307 throw new CMDIValidatorException(e.getMessage(), e); 308 } finally { 309 /* make sure, steam is closed */ 310 try { 311 stream.close(); 312 } catch (IOException e) { 313 /* IGNORE */ 314 } 315 } 316 } 317 318 319 private void validateSchematron(XdmNode document) 320 throws CMDIValidatorException { 321 try { 322 logger.debug("performing schematron validation ..."); 323 schematronValidator.setSource(document.asSource()); 324 final XdmDestination destination = new XdmDestination(); 325 schematronValidator.setDestination(destination); 326 schematronValidator.transform(); 327 328 329 XPathSelector selector = xpath1.load(); 330 selector.setContextItem(destination.getXdmNode()); 331 for (XdmItem item : selector) { 332 final XdmNode node = (XdmNode) item; 333 final XdmNode text = getFirstChild(node, SVRL_TEXT); 334 String msg = (text != null) ? text.getStringValue().trim() : null; 335 if (SVRL_FAILED_ASSERT.equals(node.getNodeName())) { 336 XPathSelector selector2 = xpath2.load(); 337 String role = null; 338 selector2.setContextItem(node); 339 XdmItem evaluateSingle = selector2.evaluateSingle(); 340 if (evaluateSingle != null) { 341 role = evaluateSingle.getStringValue().trim(); 342 } 343 if ("warning".equalsIgnoreCase(role)) { 344 result.reportWarning(-1, -1, msg); 345 } else { 346 result.reportError(-1, -1, msg); 347 } 348 } else { 349 result.reportInfo(-1, -1, msg); 350 } 351 } 352 } catch (SaxonApiException e) { 353 throw new CMDIValidatorException( 354 "error performing schematron validation", e); 355 } 356 } 357 358 359 private static XdmNode getFirstChild(XdmNode parent, QName name) { 360 XdmSequenceIterator i = parent.axisIterator(Axis.CHILD, name); 361 if (i.hasNext()) { 362 return (XdmNode) i.next(); 363 } else { 751 stack.add(new FileList(new TFile[] { root })); 752 } 753 this.filter = filter; 754 } 755 756 757 boolean isEmpty() { 758 return stack.isEmpty(); 759 } 760 761 762 TFile nextFile() { 763 for (;;) { 764 if (stack.isEmpty()) { 765 break; 766 } 767 final FileList list = stack.peek(); 768 final TFile file = list.nextFile(); 769 if ((list.size() == 0) || (file == null)) { 770 stack.pop(); 771 if (file == null) { 772 continue; 773 } 774 } 775 if (file.isDirectory()) { 776 pushDirectory(file); 777 continue; 778 } 779 return file; 780 } 364 781 return null; 365 782 } 366 } 367 368 369 private void reportWarning(int line, int col, String message, Throwable cause) { 370 logger.debug("reporting warning: [{}:{}]: {}", line, col, message); 371 if (result != null) { 372 result.reportWarning(line, col, message, cause); 373 } 374 } 375 376 377 private void reportError(int line, int col, String message, Throwable cause) { 378 logger.debug("reporting error: [{}:{}]: {}", line, col, message); 379 if (result != null) { 380 result.reportError(line, col, message, cause); 381 } 382 } 383 384 385 private static class ShadowCacheXMLGrammarPool implements XMLGrammarPool { 783 784 785 void flush() { 786 stack.clear(); 787 } 788 789 790 private void pushDirectory(TFile directory) { 791 final TFile[] files = directory.listFiles(); 792 if ((files != null) && (files.length > 0)) { 793 stack.push(new FileList(files)); 794 } 795 } 796 797 } // class FileEnumerator 798 799 800 private static final class ShadowCacheXMLGrammarPool implements 801 XMLGrammarPool { 386 802 private final Set<Grammar> cache = 387 803 new LinkedHashSet<Grammar>(); … … 409 825 @Override 410 826 public Grammar retrieveGrammar(XMLGrammarDescription d) { 411 logger. debug("search for grammar: {} / {} / {} / {}",827 logger.trace("search for grammar: {} / {} / {} / {}", 412 828 d.getNamespace(), 413 829 d.getLiteralSystemId(), … … 415 831 d.getBaseSystemId()); 416 832 if ((d.getNamespace() == null) || !(d instanceof XSDDescription)) { 417 logger. debug("-> miss (invalid arguments supplied by caller)");833 logger.trace("-> miss (invalid arguments supplied by caller)"); 418 834 return null; 419 835 } … … 423 839 Grammar result = findGrammerFromCache(desc); 424 840 if (result != null) { 425 logger. debug("-> match from cache: {} -> {} / {}",841 logger.trace("-> match from cache: {} -> {} / {}", 426 842 namespace, 427 843 desc.getNamespace(), … … 436 852 locationHint = h[0]; 437 853 } 438 logger. debug("-> hint: {}", locationHint);854 logger.trace("-> hint: {}", locationHint); 439 855 } else if (desc.getLiteralSystemId() != null) { 440 856 locationHint = desc.getLiteralSystemId(); … … 444 860 Grammar grammar = shadowCache.get(locationHint); 445 861 if (grammar != null) { 446 logger. debug("-> match from shadow cache: {} -> {}",862 logger.trace("-> match from shadow cache: {} -> {}", 447 863 grammar.getGrammarDescription().getNamespace(), 448 864 locationHint); … … 450 866 } 451 867 } 452 logger. debug("-> miss");868 logger.trace("-> miss"); 453 869 return null; 454 870 } … … 485 901 if (findGrammerFromCache(gd) == null) { 486 902 if (!locked) { 487 logger. debug("cached grammar: {} / {}",903 logger.trace("cached grammar: {} / {}", 488 904 gd.getNamespace(), 489 905 gd.getLiteralSystemId()); … … 493 909 gd.getLiteralSystemId(); 494 910 if (!shadowCache.containsKey(literalSystemId)) { 495 logger. debug("shadow cached grammar: {} / {}",911 logger.trace("shadow cached grammar: {} / {}", 496 912 gd.getNamespace(), 497 913 gd.getLiteralSystemId()); … … 519 935 } // class ShadowCacheGrammarPool 520 936 937 938 private static final class ResultImpl implements 939 CMDIValidatorWriteableResult { 940 private final List<Message> messages = new LinkedList<Message>(); 941 private File file; 942 private Severity highestSeverity; 943 944 945 private ResultImpl() { 946 reset(); 947 } 948 949 950 @Override 951 public File getFile() { 952 return file; 953 } 954 955 956 @Override 957 public Severity getHighestSeverity() { 958 return highestSeverity; 959 } 960 961 962 @Override 963 public boolean isHighestSeverity(Severity severity) { 964 if (severity == null) { 965 throw new NullPointerException("severity == null"); 966 } 967 return this.highestSeverity.equals(severity); 968 } 969 970 971 @Override 972 public List<Message> getMessages() { 973 if (messages.isEmpty()) { 974 return Collections.emptyList(); 975 } else { 976 return Collections.unmodifiableList(messages); 977 } 978 } 979 980 981 @Override 982 public Message getFirstMessage() { 983 return messages.isEmpty() ? null : messages.get(0); 984 } 985 986 987 @Override 988 public Message getFirstMessage(Severity severity) { 989 if (severity == null) { 990 throw new NullPointerException("severity == null"); 991 } 992 993 if (!messages.isEmpty()) { 994 for (Message msg : messages) { 995 if (severity.equals(msg.getSeverity())) { 996 return msg; 997 } 998 } 999 } 1000 return null; 1001 } 1002 1003 1004 @Override 1005 public int getMessageCount() { 1006 return messages.size(); 1007 } 1008 1009 1010 @Override 1011 public int getMessageCount(Severity severity) { 1012 if (severity == null) { 1013 throw new NullPointerException("severity == null"); 1014 } 1015 1016 int count = 0; 1017 if (!messages.isEmpty()) { 1018 for (Message msg : messages) { 1019 if (severity.equals(msg.getSeverity())) { 1020 count++; 1021 } 1022 } 1023 } 1024 return count; 1025 } 1026 1027 1028 @Override 1029 public void reportInfo(int line, int col, String message) { 1030 reportInfo(line, col, message, null); 1031 } 1032 1033 1034 @Override 1035 public void reportInfo(int line, int col, String message, 1036 Throwable cause) { 1037 messages.add(new MessageImpl(Severity.INFO, line, col, message, 1038 cause)); 1039 } 1040 1041 1042 @Override 1043 public void reportWarning(int line, int col, String message) { 1044 reportWarning(line, col, message, null); 1045 } 1046 1047 1048 @Override 1049 public void reportWarning(int line, int col, String message, 1050 Throwable cause) { 1051 switch (highestSeverity) { 1052 case WARNING: 1053 /* FALL-THROUGH */ 1054 case ERROR: 1055 break; 1056 default: 1057 highestSeverity = Severity.WARNING; 1058 } 1059 messages.add(new MessageImpl(Severity.WARNING, line, col, message, 1060 cause)); 1061 } 1062 1063 1064 @Override 1065 public void reportError(int line, int col, String message) { 1066 reportError(line, col, message, null); 1067 } 1068 1069 1070 @Override 1071 public void reportError(int line, int col, String message, 1072 Throwable cause) { 1073 switch (highestSeverity) { 1074 case ERROR: 1075 break; 1076 default: 1077 highestSeverity = Severity.ERROR; 1078 } 1079 messages.add(new MessageImpl(Severity.ERROR, line, col, message, 1080 cause)); 1081 } 1082 1083 1084 private void setFile(File file) { 1085 this.file = file; 1086 } 1087 1088 1089 private void reset() { 1090 this.messages.clear(); 1091 this.file = null; 1092 this.highestSeverity = Severity.INFO; 1093 } 1094 } // class ResultImpl 1095 1096 1097 private static final class MessageImpl implements 1098 CMDIValidatorResult.Message { 1099 private final Severity severity; 1100 private final int line; 1101 private final int col; 1102 private final String message; 1103 private final Throwable cause; 1104 1105 1106 private MessageImpl(Severity severity, int line, int col, 1107 String message, Throwable cause) { 1108 this.severity = severity; 1109 this.line = line; 1110 this.col = col; 1111 this.message = message; 1112 this.cause = cause; 1113 } 1114 1115 1116 @Override 1117 public Severity getSeverity() { 1118 return severity; 1119 } 1120 1121 1122 @Override 1123 public int getLineNumber() { 1124 return line; 1125 } 1126 1127 1128 @Override 1129 public int getColumnNumber() { 1130 return col; 1131 } 1132 1133 1134 @Override 1135 public String getMessage() { 1136 return message; 1137 } 1138 1139 1140 @Override 1141 public Throwable getCause() { 1142 return cause; 1143 } 1144 } // class MessageImpl 1145 521 1146 } // class CMDIValidator -
CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorHandler.java
r5369 r5382 2 2 3 3 4 public interface CMDIValidator JobHandler {4 public interface CMDIValidatorHandler { 5 5 6 6 public void onJobStarted() … … 8 8 9 9 10 public void onJobFinished( boolean wasCanceled)10 public void onJobFinished(final CMDIValidator.Result result) 11 11 throws CMDIValidatorException; 12 12 13 13 14 public void onValidationSuccess( CMDIValidatorResult result)14 public void onValidationSuccess(final CMDIValidatorResult result) 15 15 throws CMDIValidatorException; 16 16 17 17 18 public void onValidationFailure( CMDIValidatorResult result)18 public void onValidationFailure(final CMDIValidatorResult result) 19 19 throws CMDIValidatorException; 20 20 -
CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorHandlerAdapter.java
r5369 r5382 2 2 3 3 4 public class CMDIValidator JobHandlerAdapter implements CMDIValidatorJobHandler {4 public class CMDIValidatorHandlerAdapter implements CMDIValidatorHandler { 5 5 6 6 @Override … … 10 10 11 11 @Override 12 public void onJobFinished( boolean wasCanceled)12 public void onJobFinished(final CMDIValidator.Result result) 13 13 throws CMDIValidatorException { 14 14 } -
CMDIValidator/trunk/cmdi-validator-tool/pom.xml
r5337 r5382 6 6 <groupId>eu.clarin.cmdi</groupId> 7 7 <artifactId>cmdi-validator</artifactId> 8 <version>0.0. 4-SNAPSHOT</version>8 <version>0.0.5-SNAPSHOT</version> 9 9 </parent> 10 10 <artifactId>cmdi-validator-tool</artifactId> -
CMDIValidator/trunk/cmdi-validator-tool/src/main/java/eu/clarin/cmdi/validator/tool/CMDIValidatorTool.java
r5371 r5382 7 7 import java.util.Locale; 8 8 import java.util.concurrent.TimeUnit; 9 10 9 import net.java.truevfs.access.TFile; 11 10 import net.java.truevfs.access.TVFS; … … 23 22 import org.slf4j.LoggerFactory; 24 23 24 import eu.clarin.cmdi.validator.ThreadedCMDIValidatorProcessor; 25 25 import eu.clarin.cmdi.validator.CMDIValidator; 26 import eu.clarin.cmdi.validator.CMDIValidator Engine;26 import eu.clarin.cmdi.validator.CMDIValidatorConfig; 27 27 import eu.clarin.cmdi.validator.CMDIValidatorException; 28 import eu.clarin.cmdi.validator.CMDIValidatorFactory;29 import eu.clarin.cmdi.validator.CMDIValidatorFactoryConfig;30 28 import eu.clarin.cmdi.validator.CMDIValidatorInitException; 31 import eu.clarin.cmdi.validator.CMDIValidatorJob; 32 import eu.clarin.cmdi.validator.CMDIValidatorJobHandlerAdapter; 29 import eu.clarin.cmdi.validator.CMDIValidatorHandlerAdapter; 33 30 import eu.clarin.cmdi.validator.CMDIValidatorResult; 34 31 import eu.clarin.cmdi.validator.CMDIValidatorResult.Message; … … 169 166 TFile archive = null; 170 167 try { 171 /*172 * initialize CMDIValidatorFactory173 */174 168 if (schemaCacheDir != null) { 175 169 logger.info("using schema cache directory: {}", schemaCacheDir); … … 178 172 logger.info("using Schematron schema from file: {}", schematronFile); 179 173 } 180 181 final CMDIValidatorFactoryConfig config =182 new CMDIValidatorFactoryConfig.Builder()183 .schemaCacheDirectory(schemaCacheDir)184 .schematronSchemaFile(schematronFile)185 .schematronDisabled(disableSchematron)186 .build();187 final CMDIValidatorFactory factory =188 CMDIValidatorFactory.newInstance(config);189 190 if (checkPids) {191 logger.info("performing PID checking");192 factory.registerExtension(193 new CheckHandlesExtension(threadCount, true));194 }195 196 174 197 175 /* … … 199 177 */ 200 178 archive = new TFile(remaining[0]); 201 202 179 if (archive.exists()) { 203 180 if (archive.isArchive()) { … … 217 194 } 218 195 219 final CMDIValidatorEngine engine = 220 new CMDIValidatorEngine(factory, threadCount); 221 final JobHandler handler = new JobHandler(verbose); 196 197 final ValidationHandler handler = new ValidationHandler(verbose); 198 199 final CMDIValidatorConfig.Builder builder = 200 new CMDIValidatorConfig.Builder(archive, handler); 201 if (schemaCacheDir != null) { 202 builder.schemaCacheDirectory(schemaCacheDir); 203 } 204 if (schematronFile != null) { 205 builder.schematronSchemaFile(schematronFile); 206 } 207 if (disableSchematron) { 208 builder.disableSchematron(); 209 } 210 if (checkPids) { 211 logger.info("performing PID checking"); 212 builder.extension( 213 new CheckHandlesExtension(threadCount, true)); 214 } 215 216 final ThreadedCMDIValidatorProcessor processor = 217 new ThreadedCMDIValidatorProcessor(threadCount); 218 processor.start(); 222 219 try { 223 final CMDIValidatorJob job = 224 new CMDIValidatorJob(archive, handler); 225 226 engine.start(); 227 logger.debug("submitting batch validation job ..."); 228 engine.submit(job); 220 final CMDIValidator validator = 221 new CMDIValidator(builder.build()); 222 processor.process(validator); 229 223 230 224 /* … … 272 266 } // for (;;) 273 267 } finally { 274 engine.shutdown();268 processor.shutdown(); 275 269 } 276 270 … … 412 406 413 407 414 private static class JobHandler extends CMDIValidatorJobHandlerAdapter {408 private static class ValidationHandler extends CMDIValidatorHandlerAdapter { 415 409 private final boolean verbose; 416 410 private long started = System.currentTimeMillis(); … … 423 417 424 418 425 private JobHandler(boolean verbose) {419 private ValidationHandler(boolean verbose) { 426 420 this.verbose = verbose; 427 421 } … … 483 477 484 478 @Override 485 public void onJobFinished(boolean wasCancled) { 479 public void onJobStarted() throws CMDIValidatorException { 480 logger.debug("validation process started"); 481 } 482 483 484 @Override 485 public void onJobFinished(final CMDIValidator.Result result) 486 throws CMDIValidatorException { 486 487 finished = System.currentTimeMillis(); 488 switch (result) { 489 case OK: 490 logger.debug("validation process finished successfully"); 491 break; 492 case ABORTED: 493 logger.info("processing was aborted"); 494 break; 495 case ERROR: 496 logger.debug("validation process yielded an error"); 497 break; 498 default: 499 logger.debug("unknown result: " + result); 500 } // switch 501 487 502 synchronized (waiter) { 488 503 isCompleted = true; 489 504 waiter.notifyAll(); 490 505 } // synchronized (waiter) 491 if (wasCancled) {492 logger.info("processing was canceled ...");493 }494 506 } 495 507 496 508 497 509 @Override 498 public void onValidationSuccess(CMDIValidatorResult result) { 510 public void onValidationSuccess(final CMDIValidatorResult result) 511 throws CMDIValidatorException { 499 512 final File file = result.getFile(); 500 513 synchronized (this) { … … 534 547 } 535 548 } else { 536 logger.debug("file '{}' is valid", file , result.getFile());549 logger.debug("file '{}' is valid", file); 537 550 } 538 551 } … … 540 553 541 554 @Override 542 public void onValidationFailure( CMDIValidatorResult result) {555 public void onValidationFailure(final CMDIValidatorResult result) { 543 556 final File file = result.getFile(); 544 557 synchronized (this) { -
CMDIValidator/trunk/pom.xml
r5336 r5382 5 5 <groupId>eu.clarin.cmdi</groupId> 6 6 <artifactId>cmdi-validator</artifactId> 7 <version>0.0. 4-SNAPSHOT</version>7 <version>0.0.5-SNAPSHOT</version> 8 8 <packaging>pom</packaging> 9 9
Note: See TracChangeset
for help on using the changeset viewer.