/******************************************************************************* * 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.Collection; import java.util.Collections; import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import org.simantics.db.AsyncReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.TernaryAsyncRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncProcedure; import org.simantics.issues.Severity; /** * @author Tuukka Lehtonen */ public class ChildMaxIssueSeverity extends TernaryAsyncRead, Severity> { static class AsyncReadResult { private AtomicReference resultRef; private Throwable throwable; private AtomicInteger counter = new AtomicInteger(1); private AsyncProcedure procedure; AsyncReadResult(AsyncProcedure procedure, AtomicReference resultRef) { this.procedure = procedure; this.resultRef = resultRef; } void except(AsyncReadGraph graph, Throwable throwable) { this.throwable = throwable; dec(graph); } void set(AsyncReadGraph graph, T result) { resultRef.set(result); dec(graph); } void inc() { counter.incrementAndGet(); } void dec(AsyncReadGraph graph) { if(counter.decrementAndGet() == 0) { if(throwable != null) procedure.exception(graph, throwable); else procedure.execute(graph, resultRef.get()); } } } public ChildMaxIssueSeverity(Resource resource, Resource childRelation, Set typesToRecurse) { super(resource, childRelation, typesToRecurse); } @Override public void perform(AsyncReadGraph graph, final AsyncProcedure procedure) { try { Set types = graph.getTypes(parameter); if (!Collections.disjoint(parameter3, types)) { checkChildren(graph, procedure); } else { procedure.execute(graph, null); } } catch (DatabaseException e) { procedure.exception(graph, e); } } protected void checkChildren(AsyncReadGraph graph, final AsyncProcedure procedure) { AsyncReadResult maxSeverity = new AsyncReadResult(procedure, new AtomicReference()); try { Collection children = graph.getObjects(parameter, parameter2); for(Resource child : children) { maxSeverity.inc(); graph.asyncRequest(new MaxIssueSeverityRecursive(child, parameter2, parameter3), new AsyncProcedure() { @Override public void execute(AsyncReadGraph graph, Severity severity) { if (severity != null) { synchronized (maxSeverity) { maxSeverity.set(graph, Severity.moreSevere(maxSeverity.resultRef.get(), severity)); } } else { maxSeverity.dec(graph); } } @Override public void exception(AsyncReadGraph graph, Throwable throwable) { maxSeverity.except(graph, throwable); } }); } maxSeverity.dec(graph); } catch (DatabaseException e) { maxSeverity.except(graph, e); return; } } }