/******************************************************************************* * Copyright (c) 2007, 2011 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.issues.common; import java.util.concurrent.atomic.AtomicReference; import org.simantics.db.AsyncReadGraph; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.ResourceAsyncRead; import org.simantics.db.common.request.ResourceRead; import org.simantics.db.common.utils.ListUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncMultiProcedure; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.issues.Severity; import org.simantics.issues.ontology.IssueResource; /** * @author Tuukka Lehtonen */ public class MaxIssueSeveritySingle extends ResourceAsyncRead{ public MaxIssueSeveritySingle(Resource resource) { super(resource); } // @Override // public Severity perform(ReadGraph graph) throws DatabaseException { // //System.out.println("severityFor: " + NameUtils.getSafeName(graph, resource)); // IssueResource ISSUE = IssueResource.getInstance(graph); // Severity maxSeverity = null; // Collection issues = graph.getObjects(resource, ISSUE.IsIssueContextOf); // for (Resource issue : issues) { // boolean resolved = graph.hasStatement(issue, ISSUE.Resolved); // if (resolved) // continue; // // Resource severity = graph.getPossibleObject(issue, ISSUE.HasSeverity); // if (severity != null) // maxSeverity = Severity.moreSevere(maxSeverity, toSeverity(ISSUE, severity)); // } // // //System.out.println("severityFor: " + NameUtils.getSafeName(graph, resource) + " : " + maxSeverity); // return maxSeverity; // } @Override public void perform(AsyncReadGraph graph, final AsyncProcedure procedure) { final IssueResource ISSUE = graph.getService(IssueResource.class); AtomicReference maxSeverity = new AtomicReference(); graph.forEachObject(resource, ISSUE.Issue_HasContext_Inverse, new AsyncMultiProcedure() { @Override public void execute(AsyncReadGraph graph, final Resource issue) { /* * Compare severity of each related issue and find the maximum severity. * The issues that are not resolved and have active issue source manager * are taken into account. */ acceptIfNotResolved(graph, procedure, ISSUE, issue, maxSeverity); } @Override public void finished(AsyncReadGraph graph) { } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); graph.forEachObject(resource, ISSUE.Issue_ContextList_Element_Inverse, new AsyncMultiProcedure() { @Override public void execute(AsyncReadGraph graph, final Resource element) { graph.asyncRequest(new ResourceRead(element) { @Override public Resource perform(ReadGraph graph) throws DatabaseException { Resource list = ListUtils.getListElementList(graph, resource); return graph.getSingleObject(list, ISSUE.Issue_HasContexts_Inverse); } }, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Resource issue) { /* * Compare severity of each related issue and find the maximum severity. * The issues that are not resolved and have active issue source manager * are taken into account. */ acceptIfNotResolved(graph, procedure, ISSUE, issue, maxSeverity); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); } @Override public void finished(AsyncReadGraph graph) { } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); procedure.execute(graph, maxSeverity.get()); } /** * Accept an issue for maximum severity comparison, if the issue has not been resolved * * @param graph AsyncReadGraph * @param procedure AsyncProcedure * @param issue Issue resource * @param maxSeverity Current maximum severity */ private void acceptIfNotResolved(AsyncReadGraph graph, final AsyncProcedure procedure, final IssueResource ISSUE, final Resource issue, final AtomicReference maxSeverity) { graph.forHasStatement(issue, ISSUE.Resolved, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Boolean resolved) { if (resolved) return; acceptIfSourceIsActive(graph, procedure, ISSUE, issue, maxSeverity); } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); } /** * Accept an issue for maximum severity comparison if the issue source is active * @param graph AsyncReadGraph * @param procedure AsyncProcedure * @param issue Issue resource * @param maxSeverity Current maximum severity */ private void acceptIfSourceIsActive(AsyncReadGraph graph, final AsyncProcedure procedure, final IssueResource ISSUE, final Resource issue, final AtomicReference maxSeverity) { graph.forPossibleObject(issue, ISSUE.IssueSource_Manages_Inverse, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Resource issueSource) { if (issueSource != null) { graph.forPossibleRelatedValue(issueSource, ISSUE.IssueSource_active, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Boolean active) { if (!Boolean.FALSE.equals(active)) { compareSeverity(graph, procedure, ISSUE, issue, maxSeverity); } } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); } else { // Not managed by an issue source => user issue compareSeverity(graph, procedure, ISSUE, issue, maxSeverity); } } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); } /** * Compare issue's severity for current maximum severity. Update the maximum severity * if issue is more severe. * @param graph AsyncReadGraph * @param procedure AsyncProcedure * @param issue Issue resource * @param maxSeverity Current maximum severity */ private void compareSeverity(AsyncReadGraph graph, final AsyncProcedure procedure, final IssueResource ISSUE, final Resource issue, final AtomicReference maxSeverity) { graph.forPossibleObject(issue, ISSUE.Issue_HasSeverity, new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Resource severity) { if (severity != null) { synchronized (maxSeverity) { maxSeverity.set(Severity.moreSevere(maxSeverity.get(), toSeverity(ISSUE, severity))); } } } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { procedure.exception(graph, throwable); } }); } private static Severity toSeverity(IssueResource ISSUE, Resource severity) { if (ISSUE.Severity_Fatal.equals(severity)) return Severity.FATAL; if (ISSUE.Severity_Error.equals(severity)) return Severity.ERROR; if (ISSUE.Severity_Warning.equals(severity)) return Severity.WARNING; if (ISSUE.Severity_Info.equals(severity)) return Severity.INFO; if (ISSUE.Severity_Note.equals(severity)) return Severity.NOTE; return null; } }