]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.graph.impl/src/org/simantics/browsing/ui/graph/impl/LazyResourceQueryContainer.java
Merge "Multiple reader thread support for db client"
[simantics/platform.git] / bundles / org.simantics.browsing.ui.graph.impl / src / org / simantics / browsing / ui / graph / impl / LazyResourceQueryContainer.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.browsing.ui.graph.impl;
13
14 import org.simantics.browsing.ui.DataSource;
15 import org.simantics.browsing.ui.NodeContext;
16 import org.simantics.browsing.ui.NodeContext.PrimitiveQueryKey;
17 import org.simantics.browsing.ui.PrimitiveQueryProcessor;
18 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
19 import org.simantics.browsing.ui.graph.impl.request.ResourceQuery;
20 import org.simantics.db.AsyncReadGraph;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.exception.DatabaseException;
23 import org.simantics.db.procedure.Listener;
24 import org.simantics.utils.Container;
25
26 public abstract class LazyResourceQueryContainer<Result> implements Container<Result> {
27
28     final private ResourceQuery<Result> query;
29
30     final private PrimitiveQueryUpdater updater;
31
32     private final Listener<Result> procedure;
33
34     final protected NodeContext        context;
35
36     private Result                      result;
37
38     private boolean                     computed = false;
39
40     /**
41      * Computes the graph query result. This will get called asynchronously.
42      * 
43      * @param graph
44      * @return
45      */
46     protected abstract Result compute(ReadGraph graph) throws DatabaseException;
47
48     /**
49      * Needed for retrieving the actual primitive query key that is used to with
50      * {@link PrimitiveQueryUpdater#scheduleReplace(NodeContext, PrimitiveQueryKey, Object)}
51      * inside the {@link #query} that is initialized in the constructor
52      * {@link #LazyResourceQueryContainer(PrimitiveQueryUpdater, NodeContext, Object, Object)}
53      * .
54      * 
55      * <p>
56      * This key should originally be received by the actual
57      * {@link PrimitiveQueryProcessor} that has been invoked to compute the
58      * result that will be stored in this {@link LazyResourceQueryContainer}.
59      * 
60      * @return
61      */
62     protected abstract PrimitiveQueryKey<Container<Result>> getKey();
63
64     public LazyResourceQueryContainer(final PrimitiveQueryUpdater updater, final NodeContext context, Result initial) {
65
66         this.updater = updater;
67         this.context = context;
68         this.result = initial;
69
70         this.query = new ResourceQuery<Result>(getKey(), context) {
71
72             @Override
73             public Result perform(ReadGraph graph) throws DatabaseException {
74                 return compute(graph);
75             }
76
77         };
78
79         procedure = new Listener<Result>() {
80
81             @Override
82             public void execute(Result result) {
83                 setResult(result);
84                 updater.scheduleReplace(context, getKey(), LazyResourceQueryContainer.this);
85             }
86
87             @Override
88             public boolean isDisposed() {
89                 return updater.isDisposed();
90             }
91
92             public void exception(Throwable t) {
93                 System.out.print("LazyResourceQueryContainer2.request failed: ");
94                 t.printStackTrace();
95             }
96
97         };
98
99     }
100
101     protected PrimitiveQueryUpdater getUpdater() {
102         return updater;
103     }
104
105     private void setResult(Result result) {
106         this.result = result;
107         computed = true;
108     }
109
110     @Override
111     public Result get() {
112
113         if (!computed) {
114
115             final DataSource<AsyncReadGraph> source = updater.getDataSource(AsyncReadGraph.class);
116             assert(source != null);
117
118             source.schedule(graph -> graph.asyncRequest(query, procedure));
119
120         }
121
122         return result;
123
124     }
125
126 }