package org.archstudio.schematron.core;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.archstudio.archlight.ArchlightElementIdentifier;
import org.archstudio.archlight.ArchlightIssue;
import org.archstudio.archlight.ArchlightTest;
import org.archstudio.archlight.ArchlightTestResult;
import org.archstudio.sysutils.SystemUtils;
import org.archstudio.xarchadt.ObjRef;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.ILog;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.URI;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
/**
* Myx brick: "Schematron Impl"
*
* @see org.archstudio.schematron.core.SchematronMyxComponentStub
* @generated
*/
public class SchematronMyxComponent extends org.archstudio.schematron.core.SchematronMyxComponentStub {
public static final String TOOL_ID = "Schematron";
protected SchematronTestManager testManager = null;
protected boolean xalanVersionOK = false;
public SchematronMyxComponent() {
}
@Override
public String getToolID() {
return TOOL_ID;
}
protected void addNotice(String text) {
ILog log = Activator.getDefault().getLog();
log.log(new Status(IStatus.INFO, Activator.getDefault().getBundle().getSymbolicName(), TOOL_ID
+ " Archlight Tool: " + text));
}
protected void addError(String text, Throwable t) {
ILog log = Activator.getDefault().getLog();
log.log(new Status(IStatus.ERROR, Activator.getDefault().getBundle().getSymbolicName(), TOOL_ID
+ " Archlight Tool: " + text, t));
}
@Override
public void begin() {
testManager = new SchematronTestManager(TOOL_ID);
addNotice("Initialized at [" + SystemUtils.getDateAndTime() + "]");
String xalanVersion = SchematronUtils.getXalanVersion();
if (xalanVersion == null) {
xalanVersionOK = false;
addError("No Xalan version found. Tests cannot run.", null);
}
else {
xalanVersionOK = true;
addNotice("Xalan version " + xalanVersion);
}
reloadTests();
}
@Override
public void reloadTests() {
addNotice("Reloading tests at [" + SystemUtils.getDateAndTime() + "]");
testManager.reload();
List<? extends ArchlightTest> newTests = testManager.getAllArchlightTests();
tests.addTests(newTests);
List<? extends Object> warnings = testManager.getWarnings();
if (!warnings.isEmpty()) {
for (Object warning : warnings) {
if (warning instanceof String) {
addNotice("Warning:" + warning);
}
else if (warning instanceof Throwable) {
Throwable t = (Throwable) warning;
addError("Error: " + t.getMessage(), t);
}
}
}
}
@Override
public void runTests(ObjRef documentRef, Collection<String> testUIDs) {
List<SchematronTestException> schematronTestErrorList = new ArrayList<SchematronTestException>();
List<ArchlightTestResult> archlightTestResultList = new ArrayList<ArchlightTestResult>();
if (!xalanVersionOK) {
SchematronTestException ste = new SchematronTestException(
"Schematron requires Xalan; but the version of Xalan available was not sufficient to run Schematron tests.");
schematronTestErrorList.add(ste);
}
else {
List<? extends SchematronTestFile> testFiles = testManager.getAllTestFiles();
Set<SchematronTestFile> filesToRun = new HashSet<SchematronTestFile>();
List<String> testUIDsToRun = new ArrayList<String>(testUIDs);
for (String testUIDToRun : testUIDsToRun) {
for (SchematronTestFile testFile : testFiles) {
for (ArchlightTest testInFile : testFile.getArchlightTests()) {
if (testUIDToRun.equals(testInFile.getUID())) {
filesToRun.add(testFile);
break;
}
}
}
}
ObjRef docRef = documentRef;
String xmlDocument = new String(xarch.serialize(xarch.getURI(docRef)));
int filesToRunSize = filesToRun.size();
int f = 0;
for (SchematronTestFile fileToRun : filesToRun) {
try {
fileToRun = SchematronTestFile.create(fileToRun, testUIDsToRun);
}
catch (SchematronTestFileParseException stfpe) {
SchematronTestException ste = new SchematronTestException("Error parsing Schematron test file.",
stfpe);
schematronTestErrorList.add(ste);
}
if (fileToRun != null) {
SchematronTester tester = new SchematronTester(xmlDocument, fileToRun);
addNotice("Processing: " + fileToRun.getSourceURL());
float pct = (float) f / (float) filesToRunSize;
pct *= 100;
if (pct == 0) {
pct = 5;
}
//sendToolStatus("Running Tests", (int)pct);
try {
tester.runTest();
for (Object result : SchematronTestResultParser.parseTestResults(xarch, docRef, TOOL_ID,
tester.getResult())) {
if (result instanceof SchematronTestException) {
schematronTestErrorList.add((SchematronTestException) result);
}
else if (result instanceof ArchlightTestResult) {
//System.out.println("result: " + result);
archlightTestResultList.add((ArchlightTestResult) result);
}
}
}
catch (SchematronInitializationException sie) {
SchematronTestException ste = new SchematronTestException("Error initializing Schematron", sie);
schematronTestErrorList.add(ste);
}
catch (SchematronTestException ste) {
schematronTestErrorList.add(ste);
}
}
f++;
}
//sendToolStatus("Idle", -1);
}
//Now we have two lists: a list of TronTestResults and a list of
//SchematronTestExceptions if anything went wrong during testing.
ArchlightTestResult[] testResults = archlightTestResultList.toArray(new ArchlightTestResult[0]);
try {
// get resource for xarch document ref
URI uri = xarch.getURI(documentRef);
IResource resource = null;
if ("platform".equalsIgnoreCase(uri.scheme())) {
if (uri.segmentCount() > 1 && uri.segment(0).equals("resource")) {
List<String> pathSegs = Lists.newArrayList(uri.segmentsList());
IPath path = new Path(Joiner.on("/").join(pathSegs));
resource = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
}
}
if ("file".equalsIgnoreCase(uri.scheme())) {
for (IFile file : ResourcesPlugin.getWorkspace().getRoot()
.findFilesForLocationURI(new java.net.URI(uri.toString()))) {
resource = file;
break;
}
}
if (resource != null) {
//Remove old issues
for (IMarker marker : resource.findMarkers(IMarker.PROBLEM, false, IResource.DEPTH_INFINITE)) {
if (this.getClass().getName().equals(marker.getAttribute(IMarker.SOURCE_ID))) {
marker.delete();
}
}
//Store the new issues
if (testResults.length > 0) {
for (ArchlightTestResult testResult : testResults) {
for (ArchlightIssue issue : testResult.getIssues()) {
for (ArchlightElementIdentifier id : issue.getElementIdentifiers()) {
IMarker marker = resource.createMarker(IMarker.PROBLEM);
int severity;
switch (issue.getSeverity()) {
case ArchlightIssue.SEVERITY_INFO:
severity = IMarker.SEVERITY_INFO;
break;
case ArchlightIssue.SEVERITY_WARNING:
severity = IMarker.SEVERITY_WARNING;
break;
default:
severity = IMarker.SEVERITY_ERROR;
}
marker.setAttribute(IMarker.SEVERITY, severity);
marker.setAttribute(IMarker.MESSAGE, issue.getDetailedDescription());
marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH);
marker.setAttribute(IMarker.LOCATION, id.getElementID());
marker.setAttribute(IMarker.SOURCE_ID, this.getClass().getName());
}
}
}
}
}
//Store the errors
for (SchematronTestException exception : schematronTestErrorList) {
addError("Error: " + exception.getMessage(), exception);
}
}
catch (Exception e) {
addError("Error: " + e.getMessage(), e);
}
}
}