1 /*******************************************************************************
2 * Copyright (c) 2007, 2011 Association for Decentralized Information Management in
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.issues.common;
14 import java.util.Collection;
15 import java.util.Collections;
17 import java.util.concurrent.atomic.AtomicInteger;
18 import java.util.concurrent.atomic.AtomicReference;
20 import org.simantics.db.AsyncReadGraph;
21 import org.simantics.db.Resource;
22 import org.simantics.db.common.request.TernaryAsyncRead;
23 import org.simantics.db.exception.DatabaseException;
24 import org.simantics.db.procedure.AsyncProcedure;
25 import org.simantics.issues.Severity;
28 * @author Tuukka Lehtonen
30 public class ChildMaxIssueSeverity extends TernaryAsyncRead<Resource, Resource, Set<Resource>, Severity> {
32 static class AsyncReadResult<T> {
33 private AtomicReference<T> resultRef;
34 private Throwable throwable;
35 private AtomicInteger counter = new AtomicInteger(1);
36 private AsyncProcedure<T> procedure;
37 AsyncReadResult(AsyncProcedure<T> procedure, AtomicReference<T> resultRef) {
38 this.procedure = procedure;
39 this.resultRef = resultRef;
41 void except(AsyncReadGraph graph, Throwable throwable) {
42 this.throwable = throwable;
45 void set(AsyncReadGraph graph, T result) {
46 resultRef.set(result);
50 counter.incrementAndGet();
52 void dec(AsyncReadGraph graph) {
53 if(counter.decrementAndGet() == 0) {
55 procedure.exception(graph, throwable);
57 procedure.execute(graph, resultRef.get());
63 public ChildMaxIssueSeverity(Resource resource, Resource childRelation, Set<Resource> typesToRecurse) {
64 super(resource, childRelation, typesToRecurse);
68 public void perform(AsyncReadGraph graph, final AsyncProcedure<Severity> procedure) {
71 Set<Resource> types = graph.getTypes(parameter);
72 if (!Collections.disjoint(parameter3, types)) {
73 checkChildren(graph, procedure);
75 procedure.execute(graph, null);
77 } catch (DatabaseException e) {
78 procedure.exception(graph, e);
83 protected void checkChildren(AsyncReadGraph graph, final AsyncProcedure<Severity> procedure) {
85 AsyncReadResult<Severity> maxSeverity = new AsyncReadResult<Severity>(procedure, new AtomicReference<Severity>());
88 Collection<Resource> children = graph.getObjects(parameter, parameter2);
89 for(Resource child : children) {
91 graph.asyncRequest(new MaxIssueSeverityRecursive(child, parameter2, parameter3), new AsyncProcedure<Severity>() {
93 public void execute(AsyncReadGraph graph, Severity severity) {
94 if (severity != null) {
95 synchronized (maxSeverity) {
96 maxSeverity.set(graph, Severity.moreSevere(maxSeverity.resultRef.get(), severity));
99 maxSeverity.dec(graph);
103 public void exception(AsyncReadGraph graph, Throwable throwable) {
104 maxSeverity.except(graph, throwable);
108 maxSeverity.dec(graph);
109 } catch (DatabaseException e) {
110 maxSeverity.except(graph, e);