/* * This software is Copyright 2005,2006,2007,2008 Langdale Consultants. * Langdale Consultants can be contacted at: http://www.langdale.com.au */ package au.com.langdale.cimtoole.builder; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IResourceVisitor; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import au.com.langdale.cimtoole.CIMToolPlugin; import au.com.langdale.cimtoole.builder.ProfileBuildlets.SimpleOWLBuildlet; import au.com.langdale.cimtoole.project.Info; import au.com.langdale.cimtoole.project.Task; import au.com.langdale.inference.RuleParser.ParserException; import au.com.langdale.util.Logger; import au.com.langdale.util.Profiler; import au.com.langdale.util.Profiler.TimeSpan; import au.com.langdale.validation.ValidatorUtil.ValidatorProtocol; import au.com.langdale.workspace.ResourceOutputStream; import au.com.langdale.kena.OntModel; import au.com.langdale.kena.ModelFactory; import com.hp.hpl.jena.shared.JenaException; /** * Buildlet to generate diagnostics for a CIM/XML instance. * Separate subclasses handle direct validation of (small) CIM/XML * instances and large split models. */ public abstract class ValidationBaseBuildlet extends Buildlet { public static final String EXT = "log"; private ValidatorProtocol previousValidator = null; private IFile previousProfile = null; protected abstract boolean isInstanceResource(IResource resource); protected abstract ValidatorProtocol getValidator(OntModel schema, InputStream ruleText) throws ParserException, IOException; @Override protected void build(IFile result, IProgressMonitor monitor) throws CoreException { TimeSpan span = new TimeSpan("Total Validation - " + result.getName()); IResource instance = Info.getInstanceFor(result); if( instance == null) { clean(result, monitor); IFile xerrors = Info.getRelated(result, "xml-log"); if( xerrors.exists()) xerrors.delete(false, monitor); return; } IFile profile = Info.getProfileFor(instance); if( profile == null) { clean(result, monitor); return; } IFile schema = Info.getRelated(profile, "simple-owl"); IFile rules = Info.getRulesFor(instance); IResource base = Info.getBaseModelFor(instance); if( ! schema.exists()) { SimpleOWLBuildlet subordinate = new SimpleOWLBuildlet("RDF/XML-ABBREV", "simple-owl", false); subordinate.build(schema, monitor); if( ! schema.exists()) return; } validate(result, instance, base, schema, rules, monitor); span.stop(); Profiler.print(); } @Override protected void clean(IFile result, IProgressMonitor monitor) throws CoreException { if( result.exists()) result.delete(false, monitor); IFile diagnostic = Info.getRelated(result, "diagnostic"); if( diagnostic.exists()) diagnostic.delete(false, monitor); } @Override protected Collection getOutputs(IResource file) throws CoreException { if(isInstanceResource(file)) return Collections.singletonList(Info.getRelated(file, EXT)); if( Info.isProfile(file) || Info.isRuleSet(file)) return getResultsFor(file); return Collections.EMPTY_LIST; } private Collection getResultsFor(final IResource file) throws CoreException { final ArrayList affected = new ArrayList(); IResourceVisitor resourceVisitor = new IResourceVisitor() { public boolean visit(IResource resource) throws CoreException { if( isInstanceResource(resource)) { IFile profile = Info.getProfileFor(resource); if( profile != null) { if( profile.equals(file)) affected.add(Info.getRelated(resource, EXT)); else { IFile rules = Info.getRulesFor(resource); if( rules != null && rules.equals(file) ) affected.add(Info.getRelated(resource, EXT)); } } return false; } return true; } }; file.getProject().accept(resourceVisitor, IResource.DEPTH_INFINITE, false); return affected; } private ValidatorProtocol selectValidator(IFile profile, IFile rules, IProgressMonitor monitor) throws CoreException, ParserException, IOException { if( previousProfile != null && profile.equals(previousProfile)) return previousValidator; OntModel schema = CIMToolPlugin.getCache().getOntologyWait(profile); monitor.worked(1); InputStream contents; if( rules != null) contents = rules.getContents(); else contents = null; previousValidator = getValidator(schema, contents); previousProfile = profile; monitor.worked(1); return previousValidator; } private void validate(IFile result, IResource instance, IResource base, IFile schema, IFile rules, IProgressMonitor monitor) throws CoreException { IFile diagnostic = Info.getRelated(result, "diagnostic"); if( rules != null) CIMBuilder.removeMarkers(rules); Logger logger = new Logger(new ResourceOutputStream(result, monitor, true, true)); try { String namespace = Info.getProperty(instance, Info.INSTANCE_NAMESPACE); String instpath = instance.getLocation().toOSString(); String basepath = base != null? base.getLocation().toOSString(): null; ValidatorProtocol validator = selectValidator(schema, rules, monitor); OntModel model = validator.run(instpath, basepath, namespace, logger); Task.write(model, null, false, diagnostic, "TURTLE", monitor); diagnostic.setDerived(true); logger.close(); } catch (ParserException e) { if(rules != null ) { CIMBuilder.addMarker(rules, e.getMessage(), e.getLine(), IMarker.SEVERITY_ERROR); clearDiagnostics(result, diagnostic, monitor); return; } else { clearDiagnostics(result, diagnostic, monitor); error(e); } } catch (JenaException e) { clearDiagnostics(result, diagnostic, monitor); error(e); } catch (IOException e) { clearDiagnostics(result, diagnostic, monitor); error(e); } monitor.worked(1); int count = logger.getErrorCount(); if( count > 0) { CIMBuilder.addMarker(diagnostic, instance.getName() + " has " + count + " validation error" + (count > 1? "s": "")); } else { CIMBuilder.removeMarkers(diagnostic); } } private void clearDiagnostics(IFile result, IFile diagnostic, IProgressMonitor monitor) throws CoreException { if( result.exists()) result.delete(false, monitor); Task.write(ModelFactory.createMem(), null, false, diagnostic, "TURTLE", monitor); diagnostic.setDerived(true); CIMBuilder.removeMarkers(diagnostic); } private void error(Exception e) throws CoreException { throw Info.error("could not validate", e); } }