ff0f7b685f1d25e751b0a72061b336a47c38f05e
[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.simantics.databoard.Bindings;
21 import org.simantics.db.ReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.WriteGraph;
24 import org.simantics.db.WriteOnlyGraph;
25 import org.simantics.db.common.request.WriteRequest;
26 import org.simantics.db.common.utils.ListUtils;
27 import org.simantics.db.exception.DatabaseException;
28 import org.simantics.db.layer0.adapter.impl.DefaultCopyHandler;
29 import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
30 import org.simantics.db.layer0.util.ClipboardUtils;
31 import org.simantics.db.layer0.util.SimanticsClipboard;
32 import org.simantics.db.layer0.util.SimanticsClipboardImpl;
33 import org.simantics.db.layer0.util.SimanticsKeys;
34 import org.simantics.db.layer0.variable.Variable;
35 import org.simantics.db.service.VirtualGraphSupport;
36 import org.simantics.diagram.stubs.DiagramResource;
37 import org.simantics.graph.db.TransferableGraphs;
38 import org.simantics.graph.representation.Root;
39 import org.simantics.graph.representation.TransferableGraph1;
40 import org.simantics.layer0.Layer0;
41 import org.simantics.modeling.ModelingResources;
42 import org.simantics.simulation.ontology.SimulationResource;
43 import org.simantics.utils.datastructures.Arrays;
44
45 /**
46  * @author Tuukka Lehtonen
47  */
48 public class Profiles {
49
50     public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries)
51             throws DatabaseException {
52         Layer0 L0 = Layer0.getInstance(graph);
53         DiagramResource DIA = DiagramResource.getInstance(graph);
54
55         ArrayList<Resource> ee = new ArrayList<Resource>();
56         Arrays.addAll(ee, entries);
57         Resource list = ListUtils.create(graph, DIA.Profile, ee);
58
59         // TODO : DIA.Profile is a list, but why it is used in the container?
60         //Resource profile = graph.newResource();
61         //graph.claim(profile, L0.InstanceOf, null, DIA.Profile);
62         
63         Resource profile = ListUtils.create(graph, DIA.Profile);
64         
65         graph.claimLiteral(profile, L0.HasName, profileName);
66         graph.claim(profile, DIA.HasEntries, null, list);
67
68         return profile;
69     }
70
71     public static Resource createEntry(WriteGraph graph, String name, Resource style, Resource group)
72             throws DatabaseException {
73         Layer0 L0 = Layer0.getInstance(graph);
74         DiagramResource DIA = DiagramResource.getInstance(graph);
75
76         Resource entry = graph.newResource();
77         graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry);
78         graph.claimLiteral(entry, L0.HasName, name);
79         graph.claimLiteral(entry, L0.HasLabel, name);
80         graph.claim(entry, DIA.ProfileEntry_HasStyle, style);
81         graph.claim(entry, DIA.ProfileEntry_HasGroup, group);
82
83         return entry;
84     }
85
86     public static Resource createContainerProfile(WriteGraph graph, String name, Resource... children)
87             throws DatabaseException {
88         Layer0 L0 = Layer0.getInstance(graph);
89         DiagramResource DIA = DiagramResource.getInstance(graph);
90
91         Resource profile = graph.newResource();
92         graph.claim(profile, L0.InstanceOf, null, DIA.Profile);
93         graph.claim(profile, L0.Abstract, profile);
94         graph.claimLiteral(profile, L0.HasName, name);
95         graph.claimLiteral(profile, L0.HasLabel, name);
96         ArrayList<Resource> cd = new ArrayList<Resource>();
97         Arrays.addAll(cd, children);
98         graph.claim(profile, DIA.HasEntries, null, ListUtils.create(graph, DIA.Profile, cd));
99
100         return profile;
101     }
102     
103     public static Variable getMappedVariable(ReadGraph graph, Resource runtimeDiagram, Resource element) throws DatabaseException {
104         
105                 DiagramResource DIA = DiagramResource.getInstance(graph);
106                 ModelingResources MOD = ModelingResources.getInstance(graph);
107
108                 String variableURI = graph.getPossibleRelatedValue(runtimeDiagram, DIA.RuntimeDiagram_HasVariable, Bindings.STRING);
109                 Variable activeVariable = org.simantics.db.layer0.variable.Variables.getVariable(graph, variableURI);
110                 
111                 Resource module = graph.getPossibleObject(element, MOD.ElementToComponent);
112                 if (module == null)
113                         return null;
114
115                 return activeVariable.browse(graph, module);
116         
117     }
118     
119     public static Resource[] getProfileEntries(ReadGraph graph, Resource profile) throws DatabaseException {
120                 DiagramResource DIA = DiagramResource.getInstance(graph);
121
122                 Resource list = graph.getSingleObject(profile, DIA.HasEntries);
123                 List<Resource> entries = ListUtils.toList(graph, list);
124                 return entries.toArray(new Resource[entries.size()]);
125         }
126         
127         /**
128          * Copies profiles from an ontology definition to a model.
129          * 
130          * @param graph
131          * @param model
132          * @param sourceProfile
133          * @throws DatabaseException
134          */
135         public static void addProfiles(WriteGraph graph, Resource model, Resource sourceProfile) throws DatabaseException {
136                 Layer0 L0 = Layer0.getInstance(graph);
137                 DiagramResource DIA = DiagramResource.getInstance(graph);
138                 Resource profile = null;
139
140                 if (graph.isInstanceOf(sourceProfile, DIA.ConfigurableProfile))
141                         profile = copyProfiles(graph, model, sourceProfile);
142                 else
143                         profile = initProfiles(graph, model, sourceProfile);
144
145                 // connect profile to model
146                 graph.claim(model, DIA.HasProfile, profile);
147                 graph.claim(model, L0.ConsistsOf, profile);
148                 graph.claim(model, DIA.HasActiveProfile, profile);
149
150         }
151         
152         public static void addProfiles(WriteGraph graph, Resource model, String name, Resource... profileEntries) throws DatabaseException {
153                 Layer0 L0 = Layer0.getInstance(graph);
154                 DiagramResource DIA = DiagramResource.getInstance(graph);
155                 Resource profile = null;
156
157                 profile = initProfiles(graph, model, name, profileEntries);
158
159                 // connect profile to model
160                 graph.claim(model, DIA.HasProfile, profile);
161                 graph.claim(model, L0.ConsistsOf, profile);
162                 graph.claim(model, DIA.HasActiveProfile, profile);
163
164         }
165
166         private static Resource initProfiles(WriteGraph graph, Resource model, Resource profile) throws DatabaseException {
167                 Layer0 L0 = Layer0.getInstance(graph);
168
169                 Resource entries[] = getProfileEntries(graph, profile);
170
171                 String name = "Profile";
172                 String label = graph.getPossibleRelatedValue(profile, L0.HasLabel, Bindings.STRING);
173                 if (label != null && label.length() > 0)
174                         name = label;
175
176                 return initProfiles(graph, model, name, entries);
177         }
178
179         private static Resource initProfiles(WriteGraph graph, Resource model, String name, Resource entries[])
180                         throws DatabaseException {
181                 DiagramResource DIA = DiagramResource.getInstance(graph);
182                 for (int i = 0; i < entries.length; i++) {
183                         Resource entry = entries[i];
184                         if (graph.isInstanceOf(entry, DIA.ConfigurableProfile)) {
185                                 entries[i] = copyProfiles(graph, model, entry);
186                         }
187                 }
188
189                 return createProfile2(graph, name, entries);
190         }
191
192         private static Resource createProfile2(WriteGraph graph, String name, Resource[] entries) throws DatabaseException {
193                 DiagramResource DIA = DiagramResource.getInstance(graph);
194
195                 Resource profile = Profiles.createProfile(graph, name, entries);
196
197                 final List<Resource> enabled = new ArrayList<Resource>();
198                 for (Resource r : entries) {
199                         if (graph.hasStatement(r, DIA.Profile_defaultEnabled)) {
200                                 enabled.add(r);
201                         }
202                 }
203
204                 if (enabled.size() > 0) {
205                         final Resource p = profile;
206                         VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
207                         graph.syncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {
208
209                                 @Override
210                                 public void perform(WriteGraph graph) throws DatabaseException {
211                                         SimulationResource SIM = SimulationResource.getInstance(graph);
212                                         for (Resource r : enabled) {
213                                                 graph.claim(p, SIM.IsActive, r);
214                                         }
215                                 }
216                         });
217                 }
218
219                 return profile;
220         }
221
222         private static Resource copyProfiles(WriteGraph graph, Resource model, Resource profile) throws DatabaseException {
223                 Layer0 L0 = Layer0.getInstance(graph);
224                 DiagramResource DIA = DiagramResource.getInstance(graph);
225
226                 Resource entries[] = getProfileEntries(graph, profile);
227
228                 Map<Resource, Resource> groupMap = new HashMap<Resource, Resource>();
229                 for (int i = 0; i < entries.length; i++) {
230                         Resource entry = entries[i];
231                         if (graph.isInstanceOf(entry, DIA.Profile)) {
232                                 entries[i] = initProfiles(graph, model, entry);
233                         } else if (graph.isInstanceOf(entry, DIA.ConfigurableProfile)) {
234                                 entries[i] = copyProfiles(graph, model, entry);
235                         } else if (graph.isInstanceOf(entry, DIA.ProfileEntry)) {
236                                 entries[i] = copyProfileEntry(graph, entry, groupMap);
237                         }
238                 }
239                 String name = "Profile";
240                 String label = graph.getPossibleRelatedValue(profile, L0.HasLabel, Bindings.STRING);
241                 if (label != null && label.length() > 0)
242                         name = label;
243
244                 return createProfile2(graph, name, entries);
245         }
246
247         private static Resource copyProfileEntry(WriteGraph graph, Resource entry, Map<Resource, Resource> groupMap)
248                         throws DatabaseException {
249                 Layer0 L0 = Layer0.getInstance(graph);
250                 DiagramResource DIA = DiagramResource.getInstance(graph);
251
252                 String name = graph.getPossibleRelatedValue(entry, L0.HasLabel, Bindings.STRING);
253                 Resource group = graph.getSingleObject(entry, DIA.ProfileEntry_HasGroup);
254                 Resource copyGroup = groupMap.get(group);
255                 if (copyGroup == null) {
256                         copyGroup = copyProfileGroup(graph, group);
257                         groupMap.put(group, copyGroup);
258                 }
259                 Resource style = graph.getSingleObject(entry, DIA.ProfileEntry_HasStyle);
260                 if (!graph.isInstanceOf(style, DIA.Style)) {
261                         style = createProfileStyle(graph, style);
262                 }
263                 Resource instance = Profiles.createEntry(graph, name, style, copyGroup);
264                 graph.claim(instance, L0.InstanceOf, entry);
265                 Double priority = graph.getPossibleRelatedValue(entry, DIA.ProfileEntry_HasPriority, Bindings.DOUBLE);
266                 if (priority != null) {
267                         graph.claimLiteral(instance, DIA.ProfileEntry_HasPriority, priority, Bindings.DOUBLE);
268                 }
269                 for (Resource template : graph.getObjects(entry, DIA.HasTemplate)) {
270                         SimanticsClipboardImpl builder = new SimanticsClipboardImpl();
271                         DefaultCopyHandler handler = new DefaultCopyHandler(template);
272                         DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(instance) {
273                                 @Override
274                                 public Resource createRoot(WriteOnlyGraph graph, Root root, Resource resource)
275                                                 throws DatabaseException {
276                                         Layer0 l0 = graph.getService(Layer0.class);
277                                         DiagramResource DIA = graph.getService(DiagramResource.class);  
278                                         
279                                         if(resource == null) resource = graph.newResource();
280                                         
281                                         graph.claim(library, DIA.HasTemplate, DIA.HasTemplate_Inverse, resource);
282                                         
283                                         String newName = getName(root);
284                                         graph.addLiteral(resource, l0.HasName, l0.NameOf, l0.String, newName, Bindings.STRING);
285                                         
286                                         addRootInfo(root, newName, resource);
287                                         
288                                         return resource;
289                                 }
290                         };
291                         handler.copyToClipboard(graph, builder);
292                         for(Set<SimanticsClipboard.Representation> object : builder.getContents()) {
293                     TransferableGraph1 tg = ClipboardUtils.accept(graph, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
294                     TransferableGraphs.importGraph1(graph, tg, advisor);
295                 }
296                          
297                 }
298                 return instance;
299         }
300
301         private static Resource copyProfileGroup(WriteGraph graph, Resource group) throws DatabaseException {
302                 Layer0 L0 = Layer0.getInstance(graph);
303                 DiagramResource DIA = DiagramResource.getInstance(graph);
304
305                 Resource instance = graph.newResource();
306                 for (Resource type : graph.getObjects(group, L0.InstanceOf)) {
307                         graph.claim(instance, L0.InstanceOf, type);
308                 }
309                 Resource referredType = graph.getPossibleObject(group, DIA.TypeGroup_HasType);
310                 if (referredType != null)
311                         graph.claim(instance, DIA.TypeGroup_HasType, referredType);
312
313                 return instance;
314         }
315
316         private static Resource createProfileStyle(WriteGraph graph, Resource style) throws DatabaseException {
317                 Layer0 L0 = Layer0.getInstance(graph);
318
319                 Resource instance = graph.newResource();
320                 graph.claim(instance, L0.InstanceOf, style);
321                 return instance;
322         }
323
324 }