]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.charts/src/org/simantics/charts/ui/SubscriptionDropActionFactory.java
Sync git svn branch with SVN repository r33406.
[simantics/platform.git] / bundles / org.simantics.charts / src / org / simantics / charts / ui / SubscriptionDropActionFactory.java
1 /*******************************************************************************\r
2  * Copyright (c) 2014 Association for Decentralized Information Management in\r
3  * 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
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.charts.ui;\r
13 \r
14 import java.util.Collections;\r
15 import java.util.HashSet;\r
16 import java.util.List;\r
17 import java.util.Optional;\r
18 import java.util.Set;\r
19 \r
20 import org.simantics.Simantics;\r
21 import org.simantics.browsing.ui.common.ErrorLogger;\r
22 import org.simantics.charts.internal.JsonUtils;\r
23 import org.simantics.databoard.type.Datatype;\r
24 import org.simantics.databoard.util.ObjectUtils;\r
25 import org.simantics.db.ReadGraph;\r
26 import org.simantics.db.Resource;\r
27 import org.simantics.db.WriteGraph;\r
28 import org.simantics.db.common.request.WriteRequest;\r
29 import org.simantics.db.exception.DatabaseException;\r
30 import org.simantics.db.layer0.SelectionHints;\r
31 import org.simantics.db.layer0.adapter.DropActionFactory;\r
32 import org.simantics.db.layer0.request.PossibleActiveVariableFromVariable;\r
33 import org.simantics.db.layer0.request.PossibleModel;\r
34 import org.simantics.db.layer0.variable.RVI;\r
35 import org.simantics.db.layer0.variable.Variable;\r
36 import org.simantics.db.layer0.variable.VariableReference;\r
37 import org.simantics.db.layer0.variable.Variables;\r
38 import org.simantics.layer0.Layer0;\r
39 import org.simantics.modeling.ModelingResources;\r
40 import org.simantics.modeling.PropertyVariables;\r
41 import org.simantics.modeling.PropertyVariablesImpl;\r
42 import org.simantics.modeling.utils.VariableReferences;\r
43 import org.simantics.utils.ui.ISelectionUtils;\r
44 \r
45 /**\r
46  * @author Tuukka Lehtonen\r
47  */\r
48 public class SubscriptionDropActionFactory implements DropActionFactory {\r
49 \r
50     @Override\r
51     public Runnable create(ReadGraph g, Object target, Object source, int operation) throws DatabaseException {\r
52         //System.out.println("DROP: " + source + " -> " + target);\r
53 \r
54         final Resource subscription = ISelectionUtils.getSinglePossibleKey(target, SelectionHints.KEY_MAIN, Resource.class);\r
55         if (subscription == null)\r
56             return null;\r
57         Resource targetModel = g.syncRequest(new PossibleModel(subscription));\r
58 \r
59         if(source instanceof RVI) {\r
60             RVI rvi = (RVI)source;\r
61             List<VariableReference> refs = Collections.singletonList(new VariableReference(rvi, getDatatype(g, targetModel, rvi), null));\r
62             return addSubscriptions(g, subscription, refs, Collections.<Resource>emptySet());\r
63         }\r
64 \r
65         List<PropertyVariables> vars = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, PropertyVariables.class);\r
66         if (!vars.isEmpty()) {\r
67             // FIXME: this is a hack for indexed value support\r
68             vars = PropertyVariablesImpl.resolve(g, vars);\r
69             List<VariableReference> references = g.syncRequest(VariableReferences.toReferences(targetModel, vars));\r
70             if (!references.isEmpty())\r
71                 return addSubscriptions(g, subscription, references, Collections.<Resource>emptySet());\r
72         } else {\r
73             List<Resource> srcs = ISelectionUtils.getPossibleKeys(source, SelectionHints.KEY_MAIN, Resource.class);\r
74             ModelingResources MOD = ModelingResources.getInstance(g);\r
75             Set<Resource> movedItems = new HashSet<>();\r
76             for (Resource src : srcs) {\r
77                 if (g.isInstanceOf(src, MOD.Subscription_Item)) {\r
78                     Resource model = g.syncRequest(new PossibleModel(src));\r
79                     if (ObjectUtils.objectEquals(targetModel, model))\r
80                         movedItems.add(src);\r
81                 }\r
82             }\r
83             if (!movedItems.isEmpty())\r
84                 return addSubscriptions(g, subscription, Collections.emptyList(), movedItems);\r
85         }\r
86 \r
87         if (source instanceof String) {\r
88             // JSON ?\r
89             Optional<Variable> v = JsonUtils.tryParseJsonPropertyVariable(g, (String) source);\r
90             if (v.isPresent()) {\r
91                 List<VariableReference> references = g.syncRequest(VariableReferences.variablesToReferences(targetModel, Collections.singletonList(v.get())));\r
92                 return addSubscriptions(g, subscription, references, Collections.emptySet());\r
93             }\r
94         }\r
95 \r
96         return null;\r
97     }\r
98 \r
99     private Runnable addSubscriptions(ReadGraph graph, Resource subscription, List<VariableReference> references,\r
100             Set<Resource> movedSubscriptionItems) throws DatabaseException {\r
101         AddVariableToChartAction action = new AddVariableToChartAction(null, subscription, references).init(graph);\r
102         return () -> {\r
103             action.run();\r
104             if(!movedSubscriptionItems.isEmpty()) {\r
105                 Simantics.getSession().asyncRequest(new WriteRequest() {\r
106                     @Override\r
107                     public void perform(WriteGraph graph) throws DatabaseException {\r
108                         Layer0 L0 = Layer0.getInstance(graph);\r
109                         for (Resource item : movedSubscriptionItems) {\r
110                             graph.deny(item, L0.PartOf);\r
111                             graph.claim(subscription, L0.ConsistsOf, item);\r
112                         }\r
113                     }\r
114                 }, e -> {\r
115                     if (e != null)\r
116                         ErrorLogger.defaultLogError(e);\r
117                 });\r
118             }\r
119         };\r
120     }\r
121 \r
122     static Datatype getDatatype(ReadGraph graph, Resource resource, RVI rvi) throws DatabaseException {\r
123         Variable configuration = Variables.getConfigurationContext(graph, resource);\r
124         Variable active = graph.syncRequest(new PossibleActiveVariableFromVariable(configuration));\r
125         Variable var = rvi.resolve(graph, active != null ? active : configuration);\r
126         return var.getDatatype(graph);\r
127     }\r
128 \r
129 }\r