1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.modeling.ui.modelBrowser;
\r
14 import java.util.ArrayList;
\r
15 import java.util.Collection;
\r
16 import java.util.Collections;
\r
17 import java.util.HashSet;
\r
18 import java.util.Map;
\r
19 import java.util.Set;
\r
20 import java.util.function.Supplier;
\r
22 import org.eclipse.jface.resource.ImageDescriptor;
\r
23 import org.simantics.browsing.ui.BuiltinKeys;
\r
24 import org.simantics.browsing.ui.BuiltinKeys.ImagerKey;
\r
25 import org.simantics.browsing.ui.BuiltinKeys.LabelerKey;
\r
26 import org.simantics.browsing.ui.BuiltinKeys.ViewpointKey;
\r
27 import org.simantics.browsing.ui.DataSource;
\r
28 import org.simantics.browsing.ui.GraphExplorer.ModificationContext;
\r
29 import org.simantics.browsing.ui.NodeContext;
\r
30 import org.simantics.browsing.ui.PrimitiveQueryUpdater;
\r
31 import org.simantics.browsing.ui.common.ColumnKeys;
\r
32 import org.simantics.browsing.ui.common.EvaluatorData.Evaluator;
\r
33 import org.simantics.browsing.ui.common.EvaluatorImpl;
\r
34 import org.simantics.browsing.ui.common.comparators.AlphanumericComparatorFactory;
\r
35 import org.simantics.browsing.ui.common.imagers.ContainerImager;
\r
36 import org.simantics.browsing.ui.common.labelers.LabelerContent;
\r
37 import org.simantics.browsing.ui.common.labelers.LabelerStub;
\r
38 import org.simantics.browsing.ui.common.viewpoints.ViewpointStub;
\r
39 import org.simantics.browsing.ui.content.Imager;
\r
40 import org.simantics.browsing.ui.content.ImagerFactory;
\r
41 import org.simantics.browsing.ui.content.Labeler;
\r
42 import org.simantics.browsing.ui.content.LabelerFactory;
\r
43 import org.simantics.browsing.ui.content.Viewpoint;
\r
44 import org.simantics.browsing.ui.content.ViewpointFactory;
\r
45 import org.simantics.browsing.ui.graph.impl.LazyGraphLabeler;
\r
46 import org.simantics.browsing.ui.graph.impl.LazyViewpoint;
\r
47 import org.simantics.browsing.ui.graph.impl.MissingImageDescriptor;
\r
48 import org.simantics.browsing.ui.graph.impl.StringRepresentationLabelerFactory;
\r
49 import org.simantics.browsing.ui.swt.OldAdapterImagerFactory;
\r
50 import org.simantics.db.ReadGraph;
\r
51 import org.simantics.db.Resource;
\r
52 import org.simantics.db.exception.DatabaseException;
\r
53 import org.simantics.layer0.Layer0;
\r
54 import org.simantics.modeling.ui.modelBrowser.model.IChildrenCallback;
\r
55 import org.simantics.modeling.ui.modelBrowser.model.IDisposable;
\r
56 import org.simantics.modeling.ui.modelBrowser.model.INode;
\r
57 import org.simantics.modeling.ui.modelBrowser.model.INode2;
\r
58 import org.simantics.modeling.ui.modelBrowser.model.IUpdateable;
\r
59 import org.simantics.ui.SimanticsUI;
\r
60 import org.simantics.utils.datastructures.UnaryFunction;
\r
63 * @author Hannu Niemistö
\r
64 * @author Tuukka Lehtonen
\r
67 public final class ModelEvaluators {
\r
69 public static UnaryFunction<Boolean, Object> passTester() {
\r
70 return new UnaryFunction<Boolean, Object>() {
\r
72 public Boolean call(Object arg) {
\r
73 return Boolean.TRUE;
\r
78 public static UnaryFunction<Boolean, Object> exactClassTester(final Class<?> ... classes) {
\r
79 final Set<Class<?>> classSet = new HashSet<Class<?>>();
\r
80 for(Class<?> clazz : classes) classSet.add(clazz);
\r
81 return new UnaryFunction<Boolean, Object>() {
\r
83 public Boolean call(Object arg) {
\r
84 if(classSet.contains(arg.getClass())) return Boolean.TRUE;
\r
85 return Boolean.FALSE;
\r
90 public static UnaryFunction<Boolean, Object> classTester(final Class<?> ... classes) {
\r
91 return new UnaryFunction<Boolean, Object>() {
\r
93 public Boolean call(Object arg) {
\r
94 for(Class<?> clazz : classes) {
\r
95 if(clazz.isInstance(arg)) return Boolean.TRUE;
\r
97 return Boolean.FALSE;
\r
104 * @param resourceManager
\r
105 * @param factoryHints
\r
108 public static Evaluator createResourceEvaluator() {
\r
109 Evaluator resourceEvaluator = new EvaluatorImpl();
\r
111 resourceEvaluator.addViewpoint(new ResourceViewpointFactory(), 1.0);
\r
112 resourceEvaluator.addComparator(new AlphanumericComparatorFactory(ColumnKeys.SINGLE), 2.0);
\r
113 resourceEvaluator.addLabeler(new StringRepresentationLabelerFactory(), 1.0);
\r
114 resourceEvaluator.addImager(new OldAdapterImagerFactory(), 1.0);
\r
116 return resourceEvaluator;
\r
121 * @param resourceManager
\r
122 * @param factoryHints
\r
126 public static Evaluator createResourceEvaluator(final UnaryFunction<Boolean, Object> tester) {
\r
127 Evaluator resourceEvaluator = new EvaluatorImpl();
\r
129 resourceEvaluator.addViewpoint(new ResourceViewpointFactoryWithTester(tester), 1.0);
\r
130 resourceEvaluator.addComparator(new AlphanumericComparatorFactory(ColumnKeys.SINGLE), 2.0);
\r
131 resourceEvaluator.addLabeler(new StringRepresentationLabelerFactory(), 1.0);
\r
132 resourceEvaluator.addImager(new OldAdapterImagerFactory(), 1.0);
\r
134 return resourceEvaluator;
\r
139 * @param resourceManager
\r
142 public static Evaluator createNodeEvaluator() {
\r
143 Evaluator nodeEvaluator = new EvaluatorImpl();
\r
145 nodeEvaluator.addViewpoint(new NodeViewpointFactory(), 1.0);
\r
146 nodeEvaluator.addComparator(new AlphanumericComparatorFactory(ColumnKeys.SINGLE), 2.0);
\r
147 nodeEvaluator.addLabeler(new NodeLabelerFactory(), 1.0);
\r
148 nodeEvaluator.addImager(new NodeImagerFactory(), 1.0);
\r
150 return nodeEvaluator;
\r
155 * @param resourceManager
\r
159 public static Evaluator createNodeEvaluator(final UnaryFunction<Boolean, Object> tester) {
\r
160 Evaluator nodeEvaluator = new EvaluatorImpl();
\r
162 nodeEvaluator.addViewpoint(new NodeViewpointFactoryWithTester(tester), 1.0);
\r
163 nodeEvaluator.addComparator(new AlphanumericComparatorFactory(ColumnKeys.SINGLE), 2.0);
\r
164 nodeEvaluator.addLabeler(new NodeLabelerFactory(), 1.0);
\r
165 nodeEvaluator.addImager(new NodeImagerFactory(), 1.0);
\r
167 return nodeEvaluator;
\r
172 * @param resourceManager
\r
175 public static Evaluator createNode2Evaluator() {
\r
176 Evaluator nodeEvaluator = new EvaluatorImpl();
\r
178 nodeEvaluator.addViewpoint(new Node2ViewpointFactory(), 1.0);
\r
179 nodeEvaluator.addComparator(new AlphanumericComparatorFactory(ColumnKeys.SINGLE), 2.0);
\r
180 nodeEvaluator.addLabeler(new Node2LabelerFactory(), 1.0);
\r
181 nodeEvaluator.addImager(new Node2ImagerFactory(), 1.0);
\r
183 return nodeEvaluator;
\r
188 abstract class BaseViewpointFactory implements ViewpointFactory {
\r
189 protected abstract class VPB extends LazyViewpoint implements Supplier<Boolean>, IChildrenCallback {
\r
190 public VPB(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
191 super(updater, context, key);
\r
195 public String toString() {
\r
196 return BaseViewpointFactory.this.toString();
\r
200 public Object getIdentity() {
\r
201 // This is necessary to give graph requests related to this
\r
202 // LazyViewpoint a unique-enough identity so that they don't collide
\r
203 // unexpectedly with other users of ModelEvaluators.
\r
204 // This makes requests created with different concrete classes of
\r
205 // BaseViewpointFactory unique.
\r
206 return BaseViewpointFactory.this.getClass();
\r
210 public Boolean get() {
\r
211 return Boolean.valueOf(updater.isDisposed());
\r
215 public void refreshChildren(Collection<?> newChildren) {
\r
216 NodeContext[] ncs = toContextsWithInput(newChildren);
\r
217 setHasChildren(ncs.length > 0);
\r
218 setChildren(updater, ncs);
\r
219 updater.scheduleReplace(context, key, this);
\r
223 public Boolean hasChildren(ReadGraph graph) throws DatabaseException {
\r
224 // hasChildren must do the same graph operations as children
\r
225 // since they both share the same PrimitiveQueryUpdater.
\r
226 return children(graph).length > 0;
\r
231 abstract class BaseViewpointFactoryWithTester extends BaseViewpointFactory {
\r
232 protected final UnaryFunction<Boolean, Object> tester;
\r
234 BaseViewpointFactoryWithTester(UnaryFunction<Boolean, Object> tester) {
\r
235 this.tester = tester;
\r
239 class ResourceViewpointFactory extends BaseViewpointFactory {
\r
241 public String toString() {
\r
242 return "Consists Of";
\r
245 class VP extends VPB {
\r
246 public VP(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
247 super(updater, context, key);
\r
251 public NodeContext[] children(ReadGraph graph) throws DatabaseException {
\r
252 return toContextsWithInput( getChildren(graph, (Resource) context.getConstant(BuiltinKeys.INPUT)) );
\r
255 protected Collection<?> getChildren(ReadGraph g, Resource r) throws DatabaseException {
\r
256 Layer0 b = Layer0.getInstance(g);
\r
257 Collection<Resource> resources = g.getObjects(r, b.ConsistsOf);
\r
258 ArrayList<Object> ret = new ArrayList<Object>(resources.size());
\r
259 for (Resource res : resources) {
\r
260 Object node = null;
\r
262 // node = g.adapt2(res, INode2.class));
\r
263 // } catch (AdaptionException e) {
\r
264 node = g.getPossibleAdapter(res, INode.class);
\r
265 if (node != null) {
\r
266 if (node instanceof IDisposable)
\r
267 ((IDisposable) node).setDisposedCallable(this);
\r
268 // if (node instanceof IUpdateable)
\r
269 // ((IUpdateable) node).setChildrenCallback(this);
\r
279 public Viewpoint create(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
280 return new VP(updater, context, key);
\r
284 class ResourceViewpointFactoryWithTester extends BaseViewpointFactoryWithTester {
\r
286 ResourceViewpointFactoryWithTester(UnaryFunction<Boolean, Object> tester) {
\r
291 public String toString() {
\r
292 return "Consists Of";
\r
295 class VP extends VPB {
\r
296 public VP(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
297 super(updater, context, key);
\r
301 public NodeContext[] children(ReadGraph graph) throws DatabaseException {
\r
302 return toContextsWithInput( getChildren(graph, (Resource) context.getConstant(BuiltinKeys.INPUT)) );
\r
305 protected Collection<?> getChildren(ReadGraph g, Resource r) throws DatabaseException {
\r
306 Layer0 b = Layer0.getInstance(g);
\r
307 Collection<Resource> resources = g.getObjects(r, b.ConsistsOf);
\r
308 ArrayList<Object> ret = new ArrayList<Object>(resources.size());
\r
309 for (Resource res : resources) {
\r
310 Object node = null;
\r
312 // node = g.adapt2(res, INode2.class));
\r
313 // } catch (AdaptionException e) {
\r
314 node = g.getPossibleAdapter(res, INode.class);
\r
315 if (node != null) {
\r
316 if (tester.call(node)) {
\r
317 if (node instanceof IDisposable)
\r
318 ((IDisposable) node).setDisposedCallable(this);
\r
319 // if (node instanceof IUpdateable)
\r
320 // ((IUpdateable) node).setChildrenCallback(this);
\r
331 public Viewpoint create(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
332 return new VP(updater, context, key);
\r
336 class NodeViewpointFactory extends BaseViewpointFactory {
\r
338 public String toString() {
\r
342 class VP extends VPB {
\r
343 public VP(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
344 super(updater, context, key);
\r
348 public NodeContext[] children(ReadGraph graph) throws DatabaseException {
\r
349 INode node = (INode) context.getConstant(BuiltinKeys.INPUT);
\r
350 if (node instanceof IUpdateable)
\r
351 ((IUpdateable) node).setChildrenCallback(this);
\r
353 Collection<?> children = node.getChildren(graph);
\r
354 for (Object child : children) {
\r
355 if (child instanceof IDisposable)
\r
356 ((IDisposable) child).setDisposedCallable(this);
\r
358 return toContextsWithInput(children);
\r
363 public Viewpoint create(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
364 return new VP(updater, context, key);
\r
368 class NodeViewpointFactoryWithTester extends BaseViewpointFactoryWithTester {
\r
370 NodeViewpointFactoryWithTester(final UnaryFunction<Boolean, Object> tester) {
\r
375 public String toString() {
\r
379 class VP extends VPB {
\r
380 public VP(PrimitiveQueryUpdater updater, NodeContext context, ViewpointKey key) {
\r
381 super(updater, context, key);
\r
385 public NodeContext[] children(ReadGraph graph) throws DatabaseException {
\r
386 INode node = (INode) context.getConstant(BuiltinKeys.INPUT);
\r
387 if (node instanceof IUpdateable)
\r
388 ((IUpdateable) node).setChildrenCallback(this);
\r
390 ArrayList<Object> result = new ArrayList<Object>();
\r
391 for (Object child : node.getChildren(graph)) {
\r
392 if (tester.call(child)) {
\r
394 if (child instanceof IDisposable)
\r
395 ((IDisposable) child).setDisposedCallable(this);
\r
398 return toContextsWithInput(result);
\r
403 public Viewpoint create(PrimitiveQueryUpdater updater,NodeContext context, ViewpointKey key) {
\r
404 return new VP(updater, context, key);
\r
409 class NodeLabelerFactory implements LabelerFactory {
\r
411 public Labeler create(PrimitiveQueryUpdater updater, final NodeContext context, LabelerKey key) {
\r
412 return new LazyGraphLabeler(updater, context, key) {
\r
414 public Object getIdentity(LabelerKey key) {
\r
415 return NodeLabelerFactory.this.getClass();
\r
419 public Map<String, String> labels(ReadGraph graph) throws DatabaseException {
\r
420 return Collections.singletonMap(ColumnKeys.SINGLE,
\r
421 ((INode) context.getConstant(BuiltinKeys.INPUT)).getLabel(graph));
\r
425 public Modifier getModifier(ModificationContext sourcePart, String key) {
\r
426 return ((INode) context.getConstant(BuiltinKeys.INPUT)).getModifier(SimanticsUI.getSession(), key);
\r
430 public int category(ReadGraph graph) throws DatabaseException {
\r
431 return ((INode) context.getConstant(BuiltinKeys.INPUT)).getCategory(graph);
\r
437 class NodeImagerFactory implements ImagerFactory {
\r
440 public Imager create(final PrimitiveQueryUpdater updater, final NodeContext context, final ImagerKey key) {
\r
441 final ContainerImager<ImageDescriptor> result = new ContainerImager<ImageDescriptor>();
\r
442 result.setImage(MissingImageDescriptor.getInstance());
\r
444 DataSource<ReadGraph> source = updater.getDataSource(ReadGraph.class);
\r
446 source.schedule(g -> {
\r
448 ImageDescriptor descriptor = ((INode)context.getConstant(BuiltinKeys.INPUT)).getImage(g);
\r
449 result.setImage(descriptor);
\r
450 updater.scheduleReplace(context, key, result);
\r
451 } catch (DatabaseException e) {
\r
452 e.printStackTrace();
\r
461 class Node2ViewpointFactory implements ViewpointFactory {
\r
464 public String toString() {
\r
469 public Viewpoint create(final PrimitiveQueryUpdater updater, final NodeContext context, final ViewpointKey key) {
\r
470 class V extends ViewpointStub implements Runnable, Supplier<Boolean> {
\r
472 public void run() {
\r
473 updater.scheduleReplace(context, key, V.this);
\r
477 public Boolean get() {
\r
478 return Boolean.valueOf(updater.isDisposed());
\r
482 public NodeContext[] getChildren() {
\r
483 Collection<?> children = ((INode2) context.getConstant(BuiltinKeys.INPUT)).getChildren(this, context);
\r
484 for (Object child : children) {
\r
485 if (child instanceof IDisposable)
\r
486 ((IDisposable) child).setDisposedCallable(this);
\r
488 return toContextsWithInput(children);
\r
492 public Boolean getHasChildren() {
\r
493 return ((INode2) context.getConstant(BuiltinKeys.INPUT)).hasChildren(this, context);
\r
501 class Node2LabelerFactory implements LabelerFactory {
\r
504 public Labeler create(final PrimitiveQueryUpdater updater, final NodeContext context, final LabelerKey key) {
\r
506 class L extends LabelerStub implements Runnable {
\r
508 public Modifier getModifier(ModificationContext sourcePart, String key) {
\r
509 return ((INode2)context.getConstant(BuiltinKeys.INPUT)).getModifier(key);
\r
512 public void run() {
\r
513 String label = ((INode2) context.getConstant(BuiltinKeys.INPUT)).getLabel(this, context);
\r
514 int category = ((INode2) context.getConstant(BuiltinKeys.INPUT)).getCategory(this, context);
\r
515 setContent(new LabelerContent(category, Collections.singletonMap(ColumnKeys.SINGLE, label)));
\r
516 updater.scheduleReplace(context, key, this);
\r
520 L result = new L();
\r
522 String label = ((INode2) context.getConstant(BuiltinKeys.INPUT)).getLabel(result, context);
\r
523 int category = ((INode2) context.getConstant(BuiltinKeys.INPUT)).getCategory(result, context);
\r
524 result.setContent(new LabelerContent(category, Collections.singletonMap(ColumnKeys.SINGLE, label)));
\r
531 class Node2ImagerFactory implements ImagerFactory {
\r
534 public Imager create(final PrimitiveQueryUpdater updater, final NodeContext context, final ImagerKey key) {
\r
535 assert(updater != null);
\r
536 assert(context != null);
\r
538 final ContainerImager<ImageDescriptor> result = new ContainerImager<ImageDescriptor>();
\r
540 Runnable callback = new Runnable() {
\r
542 public void run() {
\r
543 ImageDescriptor desc = ((INode2) context.getConstant(BuiltinKeys.INPUT)).getImage(this, context);
\r
544 result.setImage(desc);
\r
545 updater.scheduleReplace(context, key, result);
\r
549 ImageDescriptor desc = ((INode2) context.getConstant(BuiltinKeys.INPUT)).getImage(callback, context);
\r
550 result.setImage(desc);
\r