]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.common/src/org/simantics/db/common/procedure/single/wrapper/DeepSingleOrErrorProcedure.java
b1de8c25de531ed06548e2e20dc429ba94916244
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / procedure / single / wrapper / DeepSingleOrErrorProcedure.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.common.procedure.single.wrapper;
13
14 import java.util.concurrent.atomic.AtomicBoolean;
15 import java.util.concurrent.atomic.AtomicInteger;
16
17 import org.simantics.db.AsyncReadGraph;
18 import org.simantics.db.common.utils.Logger;
19 import org.simantics.db.exception.NoSingleResultException;
20 import org.simantics.db.procedure.AsyncProcedure;
21
22 final public class DeepSingleOrErrorProcedure<Result> {
23     
24         private Result result = null;
25         final AsyncProcedure<Result> procedure;
26     final AtomicBoolean done = new AtomicBoolean(false);
27     final AtomicBoolean found = new AtomicBoolean(false);
28     final AtomicInteger ready = new AtomicInteger(1);
29     
30     public DeepSingleOrErrorProcedure(AsyncProcedure<Result> procedure) {
31         
32         this.procedure = procedure;
33         
34     }
35     
36     public void inc() {
37         
38         ready.incrementAndGet();
39         
40     }
41     
42     public void dec(AsyncReadGraph graph) {
43
44         if(ready.decrementAndGet() == 0) {
45                         // Shall fire exactly once!
46             if(done.compareAndSet(false, true)) {
47                 try {
48                         if(found.compareAndSet(false, true)) {
49                                         procedure.exception(graph, new NoSingleResultException("No results."));
50                         } else {
51                                         procedure.execute(graph, result);
52                         }
53                 } catch (Throwable t) {
54                         Logger.defaultLogError(t);
55                 }
56             }
57         }
58         
59     }
60
61     public void offer(AsyncReadGraph graph, Result result) {
62         
63                 if(found.compareAndSet(false, true)) {
64                         this.result = result;
65                 } else {
66                         // Shall fire exactly once!
67                         if(done.compareAndSet(false, true)) {
68                                 try {
69                                         procedure.exception(graph, new NoSingleResultException(this.result + " and " + result));
70                                 } catch (Throwable t) {
71                                 Logger.defaultLogError(t);
72                                 }
73                         }
74                 }
75         
76     }
77     
78     public void exception(AsyncReadGraph graph, Throwable t) {
79                 // Shall fire exactly once!
80                 if(done.compareAndSet(false, true)) {
81                         try {
82                                 procedure.exception(graph, t);
83                         } catch (Throwable t2) {
84                         Logger.defaultLogError(t2);
85                         }
86                 }
87     }
88         
89 }