]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Profiles.java
Fixed multiple issues causing dangling references to discarded queries
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / profile / Profiles.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in
3  * 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.diagram.profile;
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19
20 import org.eclipse.core.runtime.NullProgressMonitor;
21 import org.simantics.databoard.Bindings;
22 import org.simantics.databoard.binding.mutable.Variant;
23 import org.simantics.db.ReadGraph;
24 import org.simantics.db.RequestProcessor;
25 import org.simantics.db.Resource;
26 import org.simantics.db.VirtualGraph;
27 import org.simantics.db.WriteGraph;
28 import org.simantics.db.WriteOnlyGraph;
29 import org.simantics.db.common.request.WriteRequest;
30 import org.simantics.db.common.utils.ListUtils;
31 import org.simantics.db.exception.DatabaseException;
32 import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;
33 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
34 import org.simantics.db.layer0.util.ClipboardUtils;
35 import org.simantics.db.layer0.util.SimanticsClipboard;
36 import org.simantics.db.layer0.util.SimanticsClipboardImpl;
37 import org.simantics.db.layer0.util.SimanticsKeys;
38 import org.simantics.db.layer0.variable.Variable;
39 import org.simantics.db.service.VirtualGraphSupport;
40 import org.simantics.diagram.profile.ProfileActivityBean.Profile;
41 import org.simantics.diagram.stubs.DiagramResource;
42 import org.simantics.graph.db.TransferableGraphs;
43 import org.simantics.graph.representation.Root;
44 import org.simantics.graph.representation.TransferableGraph1;
45 import org.simantics.layer0.Layer0;
46 import org.simantics.modeling.ModelingResources;
47 import org.simantics.simulation.ontology.SimulationResource;
48 import org.simantics.utils.datastructures.Arrays;
49
50 /**
51  * @author Tuukka Lehtonen
52  */
53 public class Profiles {
54
55     public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries)
56             throws DatabaseException {
57         Layer0 L0 = Layer0.getInstance(graph);
58         DiagramResource DIA = DiagramResource.getInstance(graph);
59
60         ArrayList<Resource> ee = new ArrayList<Resource>();
61         Arrays.addAll(ee, entries);
62         Resource list = ListUtils.create(graph, DIA.Profile, ee);
63
64         // TODO : DIA.Profile is a list, but why it is used in the container?
65         //Resource profile = graph.newResource();
66         //graph.claim(profile, L0.InstanceOf, null, DIA.Profile);
67         
68         Resource profile = ListUtils.create(graph, DIA.Profile);
69         
70         graph.claimLiteral(profile, L0.HasName, profileName);
71         graph.claim(profile, DIA.HasEntries, null, list);
72
73         return profile;
74     }
75
76     public static Resource createEntry(WriteGraph graph, String name, Resource style, Resource group)
77             throws DatabaseException {
78         Layer0 L0 = Layer0.getInstance(graph);
79         DiagramResource DIA = DiagramResource.getInstance(graph);
80
81         Resource entry = graph.newResource();
82         graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry);
83         graph.claimLiteral(entry, L0.HasName, name);
84         graph.claimLiteral(entry, L0.HasLabel, name);
85         graph.claim(entry, DIA.ProfileEntry_HasStyle, style);
86         graph.claim(entry, DIA.ProfileEntry_HasGroup, group);
87
88         return entry;
89     }
90
91     public static Resource createContainerProfile(WriteGraph graph, String name, Resource... children)
92             throws DatabaseException {
93         Layer0 L0 = Layer0.getInstance(graph);
94         DiagramResource DIA = DiagramResource.getInstance(graph);
95
96         Resource profile = graph.newResource();
97         graph.claim(profile, L0.InstanceOf, null, DIA.Profile);
98         graph.claim(profile, L0.Abstract, profile);
99         graph.claimLiteral(profile, L0.HasName, name);
100         graph.claimLiteral(profile, L0.HasLabel, name);
101         ArrayList<Resource> cd = new ArrayList<Resource>();
102         Arrays.addAll(cd, children);
103         graph.claim(profile, DIA.HasEntries, null, ListUtils.create(graph, DIA.Profile, cd));
104
105         return profile;
106     }
107     
108     public static Variable getMappedVariable(ReadGraph graph, Resource runtimeDiagram, Resource element) throws DatabaseException {
109         
110                 DiagramResource DIA = DiagramResource.getInstance(graph);
111                 ModelingResources MOD = ModelingResources.getInstance(graph);
112
113                 String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable, Bindings.STRING);
114                 Variable activeVariable = org.simantics.db.layer0.variable.Variables.getVariable(graph, variableURI);
115                 
116                 Resource module = graph.getPossibleObject(element, MOD.ElementToComponent);
117                 if (module == null)
118                         return null;
119
120                 return activeVariable.browse(graph, module);
121         
122     }
123     
124     public static Resource[] getProfileEntries(ReadGraph graph, Resource profile) throws DatabaseException {
125                 DiagramResource DIA = DiagramResource.getInstance(graph);
126
127                 Resource list = graph.getSingleObject(profile, DIA.HasEntries);
128                 List<Resource> entries = ListUtils.toList(graph, list);
129                 return entries.toArray(new Resource[entries.size()]);
130         }
131         
132         /**
133          * Copies profiles from an ontology definition to a model.
134          * 
135          * @param graph
136          * @param model
137          * @param sourceProfile
138          * @throws DatabaseException
139          */
140         public static void addProfiles(WriteGraph graph, Resource model, Resource sourceProfile) throws DatabaseException {
141                 Layer0 L0 = Layer0.getInstance(graph);
142                 DiagramResource DIA = DiagramResource.getInstance(graph);
143                 Resource profile = null;
144
145                 if (graph.isInstanceOf(sourceProfile, DIA.ConfigurableProfile))
146                         profile = copyProfiles(graph, model, sourceProfile);
147                 else
148                         profile = initProfiles(graph, model, sourceProfile);
149
150                 // connect profile to model
151                 graph.claim(model, DIA.HasProfile, profile);
152                 graph.claim(model, L0.ConsistsOf, profile);
153                 graph.claim(model, DIA.HasActiveProfile, profile);
154
155         }
156         
157         public static void addProfiles(WriteGraph graph, Resource model, String name, Resource... profileEntries) throws DatabaseException {
158                 Layer0 L0 = Layer0.getInstance(graph);
159                 DiagramResource DIA = DiagramResource.getInstance(graph);
160                 Resource profile = null;
161
162                 profile = initProfiles(graph, model, name, profileEntries);
163
164                 // connect profile to model
165                 graph.claim(model, DIA.HasProfile, profile);
166                 graph.claim(model, L0.ConsistsOf, profile);
167                 graph.claim(model, DIA.HasActiveProfile, profile);
168
169         }
170
171         private static Resource initProfiles(WriteGraph graph, Resource model, Resource profile) throws DatabaseException {
172                 Layer0 L0 = Layer0.getInstance(graph);
173
174                 Resource entries[] = getProfileEntries(graph, profile);
175
176                 String name = "Profile";
177                 String label = graph.getPossibleRelatedValue(profile, L0.HasLabel, Bindings.STRING);
178                 if (label != null && label.length() > 0)
179                         name = label;
180
181                 return initProfiles(graph, model, name, entries);
182         }
183
184         private static Resource initProfiles(WriteGraph graph, Resource model, String name, Resource entries[])
185                         throws DatabaseException {
186                 DiagramResource DIA = DiagramResource.getInstance(graph);
187                 for (int i = 0; i < entries.length; i++) {
188                         Resource entry = entries[i];
189                         if (graph.isInstanceOf(entry, DIA.ConfigurableProfile)) {
190                                 entries[i] = copyProfiles(graph, model, entry);
191                         }
192                 }
193
194                 return createProfile2(graph, name, entries);
195         }
196
197         private static Resource createProfile2(WriteGraph graph, String name, Resource[] entries) throws DatabaseException {
198                 DiagramResource DIA = DiagramResource.getInstance(graph);
199
200                 Resource profile = Profiles.createProfile(graph, name, entries);
201
202                 final List<Resource> enabled = new ArrayList<Resource>();
203                 for (Resource r : entries) {
204                         if (graph.hasStatement(r, DIA.Profile_defaultEnabled)) {
205                                 enabled.add(r);
206                         }
207                 }
208
209                 if (enabled.size() > 0) {
210                         final Resource p = profile;
211                         VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
212                         graph.syncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {
213
214                                 @Override
215                                 public void perform(WriteGraph graph) throws DatabaseException {
216                                         SimulationResource SIM = SimulationResource.getInstance(graph);
217                                         for (Resource r : enabled) {
218                                                 graph.claim(p, SIM.IsActive, r);
219                                         }
220                                 }
221                         });
222                 }
223
224                 return profile;
225         }
226
227         private static Resource copyProfiles(WriteGraph graph, Resource model, Resource profile) throws DatabaseException {
228                 Layer0 L0 = Layer0.getInstance(graph);
229                 DiagramResource DIA = DiagramResource.getInstance(graph);
230
231                 Resource entries[] = getProfileEntries(graph, profile);
232
233                 Map<Resource, Resource> groupMap = new HashMap<Resource, Resource>();
234                 for (int i = 0; i < entries.length; i++) {
235                         Resource entry = entries[i];
236                         if (graph.isInstanceOf(entry, DIA.Profile)) {
237                                 entries[i] = initProfiles(graph, model, entry);
238                         } else if (graph.isInstanceOf(entry, DIA.ConfigurableProfile)) {
239                                 entries[i] = copyProfiles(graph, model, entry);
240                         } else if (graph.isInstanceOf(entry, DIA.ProfileEntry)) {
241                                 entries[i] = copyProfileEntry(graph, entry, groupMap);
242                         }
243                 }
244                 String name = "Profile";
245                 String label = graph.getPossibleRelatedValue(profile, L0.HasLabel, Bindings.STRING);
246                 if (label != null && label.length() > 0)
247                         name = label;
248
249                 return createProfile2(graph, name, entries);
250         }
251
252         private static Resource copyProfileEntry(WriteGraph graph, Resource entry, Map<Resource, Resource> groupMap)
253                         throws DatabaseException {
254                 Layer0 L0 = Layer0.getInstance(graph);
255                 DiagramResource DIA = DiagramResource.getInstance(graph);
256
257                 String name = graph.getPossibleRelatedValue(entry, L0.HasLabel, Bindings.STRING);
258                 Resource group = graph.getSingleObject(entry, DIA.ProfileEntry_HasGroup);
259                 Resource copyGroup = groupMap.get(group);
260                 if (copyGroup == null) {
261                         copyGroup = copyProfileGroup(graph, group);
262                         groupMap.put(group, copyGroup);
263                 }
264                 Resource style = graph.getSingleObject(entry, DIA.ProfileEntry_HasStyle);
265                 if (!graph.isInstanceOf(style, DIA.Style)) {
266                         style = createProfileStyle(graph, style);
267                 }
268                 Resource instance = Profiles.createEntry(graph, name, style, copyGroup);
269                 graph.claim(instance, L0.InstanceOf, entry);
270                 Double priority = graph.getPossibleRelatedValue(entry, DIA.ProfileEntry_HasPriority, Bindings.DOUBLE);
271                 if (priority != null) {
272                         graph.claimLiteral(instance, DIA.ProfileEntry_HasPriority, priority, Bindings.DOUBLE);
273                 }
274                 for (Resource template : graph.getObjects(entry, DIA.HasTemplate)) {
275                         SimanticsClipboardImpl builder = new SimanticsClipboardImpl();
276                         DefaultCopyHandler handler = new DefaultCopyHandler(template);
277                         DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(instance) {
278                                 @Override
279                                 public Resource createRoot(WriteOnlyGraph graph, Root root, Resource resource)
280                                                 throws DatabaseException {
281                                         Layer0 l0 = graph.getService(Layer0.class);
282                                         DiagramResource DIA = graph.getService(DiagramResource.class);  
283                                         
284                                         if(resource == null) resource = graph.newResource();
285                                         
286                                         graph.claim(library, DIA.HasTemplate, DIA.HasTemplate_Inverse, resource);
287                                         
288                                         String newName = getName(root);
289                                         graph.addLiteral(resource, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING);
290                                         
291                                         addRootInfo(root, newName, resource);
292                                         
293                                         return resource;
294                                 }
295                         };
296                         handler.copyToClipboard(graph, builder, new NullProgressMonitor());
297                         for(Set<SimanticsClipboard.Representation> object : builder.getContents()) {
298                     TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
299                     TransferableGraphs.importGraph1(graph, tg, advisor);
300                 }
301                          
302                 }
303                 return instance;
304         }
305
306         private static Resource copyProfileGroup(WriteGraph graph, Resource group) throws DatabaseException {
307                 Layer0 L0 = Layer0.getInstance(graph);
308                 DiagramResource DIA = DiagramResource.getInstance(graph);
309
310                 Resource instance = graph.newResource();
311                 for (Resource type : graph.getObjects(group, L0.InstanceOf)) {
312                         graph.claim(instance, L0.InstanceOf, type);
313                 }
314                 Resource referredType = graph.getPossibleObject(group, DIA.TypeGroup_HasType);
315                 if (referredType != null)
316                         graph.claim(instance, DIA.TypeGroup_HasType, referredType);
317
318                 return instance;
319         }
320
321         private static Resource createProfileStyle(WriteGraph graph, Resource style) throws DatabaseException {
322                 Layer0 L0 = Layer0.getInstance(graph);
323
324                 Resource instance = graph.newResource();
325                 graph.claim(instance, L0.InstanceOf, style);
326                 return instance;
327         }
328
329         public static ProfileActivityBean readProfileActivity(
330                         RequestProcessor processor,
331                         Resource root)
332                                         throws DatabaseException
333         {
334                 return processor.syncRequest(new ProfileActivityBeanRequest(root));
335         }
336
337         public static ProfileActivityBean readProfileActivity(
338                         RequestProcessor processor,
339                         Resource root,
340                         Map<String, Variant> writeToMap)
341                                         throws DatabaseException
342         {
343                 ProfileActivityBean pab = readProfileActivity(processor, root);
344                 if (pab != null && writeToMap != null)
345                         writeToMap.put(ProfileActivityBean.EXTENSION_KEY, new Variant(ProfileActivityBean.BINDING, pab));
346                 return pab;
347         }
348
349         public static void writeProfileActivity(
350                         RequestProcessor processor,
351                         Resource root,
352                         ProfileActivityBean bean)
353                                         throws DatabaseException
354         {
355                 VirtualGraph vg = processor.getService(VirtualGraphSupport.class).getWorkspacePersistent("profiles");
356                 processor.syncRequest(new WriteRequest(vg) {
357                         @Override
358                         public void perform(WriteGraph graph) throws DatabaseException {
359                                 writeProfileActivity(graph, root, bean);
360                         }
361                 });
362         }
363
364         private static void writeProfileActivity(
365                         WriteGraph graph,
366                         Resource root,
367                         ProfileActivityBean bean)
368                                         throws DatabaseException
369         {
370                 String rootUri = graph.getPossibleURI(root);
371                 if (rootUri == null)
372                         return;
373
374                 SimulationResource SIMU = SimulationResource.getInstance(graph);
375                 for (Profile p : bean.topLevelProfiles.values()) {
376                         Resource pr = resolveRelativeUri(graph, rootUri, p.relativeUri);
377                         if (pr == null)
378                                 continue;
379                         for (String active : p.activeEntries) {
380                                 Resource ar = resolveRelativeUri(graph, rootUri, active);
381                                 if (ar != null)
382                                         graph.claim(pr, SIMU.IsActive, ar);
383                         }
384                 }
385
386                 Resource activeProfile = resolveRelativeUri(graph, rootUri, bean.activeProfile);
387                 if (activeProfile != null) {
388                         DiagramResource DIA = DiagramResource.getInstance(graph);
389                         graph.claim(root, DIA.HasActiveProfile, DIA.HasActiveProfile_Inverse, activeProfile);
390                 }
391         }
392
393         static String possiblyRelativeUri(ReadGraph graph, String rootUri, Resource r) throws DatabaseException {
394                 if (r == null)
395                         return null;
396                 String uri = graph.getPossibleURI(r);
397                 if (rootUri != null && uri != null && uri.startsWith(rootUri))
398                         return uri.substring(rootUri.length());
399                 return uri;
400         }
401
402         static Resource resolveRelativeUri(ReadGraph graph, String rootUri, String possiblyRelativeUri) throws DatabaseException {
403                 return possiblyRelativeUri != null
404                                 ? graph.getPossibleResource( resolveRelativeUri(rootUri, possiblyRelativeUri) )
405                                 : null;
406         }
407
408         private static String resolveRelativeUri(String rootUri, String possiblyRelativeUri) {
409                 return possiblyRelativeUri.startsWith("http:/")
410                                 ? possiblyRelativeUri
411                                 : rootUri + possiblyRelativeUri;
412         }
413
414 }