]> gerrit.simantics Code Review - simantics/platform.git/blob
91aeb9c5d4539b5e2e4e189fc703b5f2bdd6cb03
[simantics/platform.git] /
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 java.util.function.Consumer;
15
16 import org.simantics.browsing.ui.BuiltinKeys;
17 import org.simantics.browsing.ui.DataSource;
18 import org.simantics.browsing.ui.NodeContext;
19 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
20 import org.simantics.browsing.ui.common.viewpoints.ViewpointStub;
21 import org.simantics.browsing.ui.content.Viewpoint;
22 import org.simantics.browsing.ui.graph.impl.request.ParametrizedResourceQuery;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.exception.DatabaseException;
25 import org.simantics.db.procedure.Listener;
26 import org.simantics.utils.datastructures.Pair;
27
28 /**
29  * Implement {@link #children(ReadGraph)} and {@link #hasChildren(ReadGraph)}.
30  * 
31  * @author Tuukka Lehtonen
32  */
33 public abstract class LazyParametrizedViewpoint extends ViewpointStub {
34
35         /**
36          * Needed for separating childQuery and hasChildQuery from each other in the
37          * equals sense.
38          */
39         private static final Object                              CHILDREN     = new Object();
40         private static final Object                              HAS_CHILDREN = new Object();
41
42         private final ParametrizedResourceQuery<NodeContext[]> childQuery;
43         private final ParametrizedResourceQuery<Boolean>        hasChildQuery;
44
45     private final Listener<NodeContext[]>              childQueryProcedure;
46     private final Listener<Boolean>                     hasChildQueryProcedure;
47
48     private final PrimitiveQueryUpdater                      updater;
49     private final NodeContext                               context;
50     private final BuiltinKeys.ViewpointKey                   key;
51
52         /**
53          * @return
54          */
55         public abstract NodeContext[] children(ReadGraph graph) throws DatabaseException;
56
57         /**
58          * @param graph
59          * @return
60          */
61         public abstract Boolean hasChildren(ReadGraph graph) throws DatabaseException;
62
63
64         public LazyParametrizedViewpoint(PrimitiveQueryUpdater updater, NodeContext context, BuiltinKeys.ViewpointKey key, Object... parameters) {
65                 assert updater != null;
66                 assert context != null;
67                 assert key != null;
68
69                 this.updater = updater;
70                 this.context = context;
71                 this.key = key;
72
73                 this.childQuery = new ParametrizedResourceQuery<NodeContext[]>(Pair.make(getClass(), CHILDREN), context, parameters) {
74
75                         @Override
76                         public NodeContext[] perform(ReadGraph graph) throws DatabaseException {
77                                 return  children(graph);
78                         }
79
80                 };
81
82                 this.childQueryProcedure = new Listener<NodeContext[]>() {
83
84                         @Override
85                         public void execute(NodeContext[] result) {
86                                 replaceChildrenResult(result);
87                         }
88
89                         @Override
90                         public boolean isDisposed() {
91                                 return LazyParametrizedViewpoint.this.updater.isDisposed();
92                         }
93
94                         public void exception(Throwable t) {
95                                 System.out.print("LazyParametrizedViewpoint2.childQuery failed: ");
96                                 t.printStackTrace();
97                         }
98
99                 };
100
101                 this.hasChildQuery = new ParametrizedResourceQuery<Boolean>(Pair.make(getClass(), HAS_CHILDREN), context, parameters) {
102
103                         @Override
104                         public Boolean perform(ReadGraph graph) throws DatabaseException {
105                                 return hasChildren(graph);
106                         }
107
108                 };
109
110                 this.hasChildQueryProcedure = new Listener<Boolean>() {
111
112                         @Override
113                         public void execute(Boolean result) {
114                                 replaceHasChildrenResult(result);
115                         }
116
117                         @Override
118                         public boolean isDisposed() {
119                                 return LazyParametrizedViewpoint.this.updater.isDisposed();
120                         }
121
122                         public void exception(Throwable t) {
123                                 System.out.print("LazyParametrizedViewpoint2.hasChildQuery failed: ");
124                                 t.printStackTrace();
125                         }
126
127                 };
128
129         }
130
131         public NodeContext getContext() {
132                 return context;
133         }
134
135         @Override
136         public NodeContext[] getChildren() {
137                 if (children == Viewpoint.PENDING_CHILDREN) {
138                         DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
139                         if (source != null) {
140                                 source.schedule(graph -> graph.asyncRequest(childQuery, childQueryProcedure));
141                         }
142                 }
143
144                 return children;
145         }
146
147         @Override
148         public Boolean getHasChildren() {
149                 if (hasChildren == Viewpoint.PENDING_HAS_CHILDREN) {
150                         DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
151                         if (source != null) {
152                                 source.schedule(new Consumer<ReadGraph>() {
153                                         @Override
154                                         public void accept(ReadGraph source) {
155                                                 source.asyncRequest(hasChildQuery, hasChildQueryProcedure);
156                                         }
157                                 });
158                         }
159                 }
160
161                 return hasChildren;
162         }
163
164         protected void replaceChildrenResult(NodeContext[] result) {
165                 setChildren(updater, result);
166                 updater.scheduleReplace(context, key, this);
167         }
168
169         protected void replaceHasChildrenResult(Boolean result) {
170                 setHasChildren(result);
171                 updater.scheduleReplace(context, key, this);
172         }
173
174         /**
175          * @param <T>
176          * @param clazz
177          * @return input of the specified class
178          * @throws ClassCastException if the input class does not match the
179          *         specified class
180          * @throws NullPointerException if the input is null
181          */
182          protected <T> T getInput(Class<T> clazz) throws ClassCastException {
183                  Object o = context.getConstant(BuiltinKeys.INPUT);
184                  if (o == null)
185                          throw new NullPointerException("null input");
186                  return clazz.cast(o);
187          }
188
189          /**
190           * @param <T>
191           * @param clazz
192           * @return <code>null</code> if input is <code>null</code> or if the class does not match
193           */
194          protected <T> T tryGetInput(Class<T> clazz) {
195                  Object o = context.getConstant(BuiltinKeys.INPUT);
196                  if (o != null && clazz.isInstance(o))
197                          return clazz.cast(o);
198                  return null;
199          }
200
201 }