]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.network.ui/src/org/simantics/district/network/ui/function/Functions.java
627de3a62171b46eebe4b2407edb3285b5da5d73
[simantics/district.git] / org.simantics.district.network.ui / src / org / simantics / district / network / ui / function / Functions.java
1 package org.simantics.district.network.ui.function;
2
3 import java.util.Collection;
4 import java.util.Collections;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Set;
10 import java.util.stream.Collectors;
11
12 import org.eclipse.jface.dialogs.Dialog;
13 import org.eclipse.jface.layout.GridDataFactory;
14 import org.eclipse.swt.SWT;
15 import org.eclipse.swt.events.SelectionAdapter;
16 import org.eclipse.swt.events.SelectionEvent;
17 import org.eclipse.swt.layout.GridData;
18 import org.eclipse.swt.layout.GridLayout;
19 import org.eclipse.swt.widgets.Combo;
20 import org.eclipse.swt.widgets.Composite;
21 import org.eclipse.swt.widgets.Control;
22 import org.eclipse.swt.widgets.Group;
23 import org.eclipse.swt.widgets.Label;
24 import org.eclipse.swt.widgets.Shell;
25 import org.eclipse.ui.PlatformUI;
26 import org.eclipse.ui.dialogs.SelectionStatusDialog;
27 import org.simantics.NameLabelUtil;
28 import org.simantics.Simantics;
29 import org.simantics.browsing.ui.common.modifiers.EnumeratedValue;
30 import org.simantics.browsing.ui.common.modifiers.Enumeration;
31 import org.simantics.browsing.ui.graph.impl.GraphEnumerationModifier;
32 import org.simantics.databoard.Bindings;
33 import org.simantics.db.ReadGraph;
34 import org.simantics.db.Resource;
35 import org.simantics.db.Session;
36 import org.simantics.db.WriteGraph;
37 import org.simantics.db.common.request.IndexRoot;
38 import org.simantics.db.common.request.IndexRoots;
39 import org.simantics.db.common.request.ObjectsWithType;
40 import org.simantics.db.common.request.ReadRequest;
41 import org.simantics.db.common.request.WriteRequest;
42 import org.simantics.db.exception.DatabaseException;
43 import org.simantics.db.exception.RuntimeDatabaseException;
44 import org.simantics.db.exception.ServiceException;
45 import org.simantics.db.layer0.variable.Variable;
46 import org.simantics.db.layer0.variable.Variables.Role;
47 import org.simantics.db.procedure.Procedure;
48 import org.simantics.diagram.stubs.DiagramResource;
49 import org.simantics.district.network.ontology.DistrictNetworkResource;
50 import org.simantics.layer0.Layer0;
51 import org.simantics.modeling.ModelingResources;
52 import org.simantics.modeling.ModelingUtils;
53 import org.simantics.modeling.adapters.NewCompositeActionFactory;
54 import org.simantics.modeling.typicals.TypicalUtil;
55 import org.simantics.scl.reflection.annotations.SCLValue;
56 import org.simantics.ui.workbench.action.DefaultActions;
57 import org.simantics.utils.ui.SWTUtils;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60
61 public class Functions {
62
63     private static final Logger LOGGER = LoggerFactory.getLogger(Functions.class);
64     
65     private Functions() {
66     }
67
68     private static class HasMappingEnumerationModifier extends GraphEnumerationModifier {
69
70         public HasMappingEnumerationModifier(Session session, Resource subject, Resource relation, Enumeration<Resource> enumeration, Resource value) {
71             super(session, subject, relation, enumeration, value);
72         }
73
74     }
75
76     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
77     public static Object defaultEdgeMappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
78         Resource diagram = resolveElement(graph, context);
79         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
80         return baseMappingModifier(graph, diagram, DN.EdgeDefaultMapping, DN.Mapping_EdgeMapping, context);
81     }
82     
83     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
84     public static Object defaultVertexMappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
85         System.out.println(graph.getURI(resource));
86         System.out.println(context.getURI(graph));
87         
88         Resource diagram = resolveElement(graph, context);
89         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
90         return baseMappingModifier(graph, diagram, DN.VertexDefaultMapping, DN.Mapping_VertexMapping, context);
91     }
92     
93     @SCLValue(type = "ReadGraph -> Resource -> Variable -> b")
94     public static Object mappingModifier(ReadGraph graph, Resource resource, final Variable context) throws DatabaseException {
95         
96         Resource element = resolveElement(graph, context);
97         Resource mappingType = resolveMappingType(graph, element);
98         return baseMappingModifier(graph, element, DistrictNetworkResource.getInstance(graph).HasMapping, mappingType, context);
99     }
100
101     public static Map<String, Resource> getVertexMappings(ReadGraph graph, Resource resource) throws DatabaseException {
102         Map<String, Resource> second = getNetworkMappingsByType(graph, resource , DistrictNetworkResource.getInstance(graph).Mapping_VertexMapping);
103         return second;
104     }
105
106     public static Map<String, Resource> getEdgeMappings(ReadGraph graph, Resource resource) throws DatabaseException {
107         Map<String, Resource> second = getNetworkMappingsByType(graph, resource , DistrictNetworkResource.getInstance(graph).Mapping_EdgeMapping);
108         return second;
109     }
110     
111     public static Map<String, Resource> getCRSs(ReadGraph graph, Resource resource) throws DatabaseException {
112         Map<String, Resource> result = getNetworkMappingsByType(graph, resource, DistrictNetworkResource.getInstance(graph).SpatialRefSystem);
113         return result;
114         
115     }
116
117     public static Map<String, Resource> getNetworkMappingsByType(ReadGraph graph, Resource element, Resource mappingType) throws DatabaseException {
118         Resource indexRoot = graph.sync(new IndexRoot(element));
119         List<Resource> mappings = ModelingUtils.searchByType(graph, indexRoot, mappingType);
120         Map<String, Resource> result = new HashMap<>(mappings.size());
121         Layer0 L0 = Layer0.getInstance(graph);
122         mappings.forEach(mapping -> {
123             try {
124                 String name = graph.getRelatedValue2(mapping, L0.HasName);
125                 result.put(name, mapping);
126             } catch (DatabaseException e) {
127                 e.printStackTrace();
128             }
129         });
130         return result;
131     }
132     
133     private static Object baseMappingModifier(ReadGraph graph, Resource element, Resource property, Resource mappingType, Variable context) throws DatabaseException {
134         Resource indexRoot = graph.sync(new IndexRoot(element));
135         List<Resource> mappings = ModelingUtils.searchByType(graph, indexRoot, mappingType);
136         Enumeration<Resource> enums = Enumeration
137                 .make(mappings.stream().map(m -> createEnumeratedValue(graph, m)).collect(Collectors.toList()));
138         
139         Resource currentMapping = graph.getSingleObject(element, property);
140         
141         return new HasMappingEnumerationModifier(Simantics.getSession(), element, property, enums, currentMapping);
142     }
143     
144     private static Resource resolveMappingType(ReadGraph graph, Resource element) throws DatabaseException {
145         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
146         if (graph.isInstanceOf(element, DN.Edge))
147             return DN.Mapping_EdgeMapping;
148         else if (graph.isInstanceOf(element, DN.Vertex))
149             return DN.Mapping_VertexMapping;
150         throw new IllegalStateException("No mapping type found for element " + element + " : " + graph.getPossibleURI(element));
151     }
152
153     private static Resource resolveElement(ReadGraph graph, Variable variable) throws DatabaseException {
154         Role role = variable.getPossibleRole(graph);
155         if (role.equals(Role.PROPERTY))
156             return resolveElement(graph, variable.getParent(graph));
157         else
158             return variable.getRepresents(graph);
159     }
160
161     private static EnumeratedValue<Resource> createEnumeratedValue(ReadGraph graph, Resource resource) {
162         try {
163             String label = NameLabelUtil.modalName(graph, resource);
164             return new EnumeratedValue<Resource>(label, resource);
165         } catch (DatabaseException e) {
166             throw new RuntimeDatabaseException(e);
167         }
168     }
169     
170     @SCLValue(type = "ReadGraph -> Resource -> a -> b")
171     public static Object enumerationValues(ReadGraph graph, Resource resource, Object context) throws DatabaseException {
172         Variable var = (Variable) context;
173         System.out.println(graph.getURI(resource));
174         System.out.println(var.getURI(graph));
175         return Collections.emptyList();
176     }
177     
178     @SCLValue(type = "ReadGraph -> Resource -> a -> b")
179     public static Object convertToValue(ReadGraph graph, Resource resource, Object context) throws DatabaseException {
180         return graph.getRelatedValue2(resource, Layer0.getInstance(graph).HasName, Bindings.STRING);
181 //        return null;
182     }
183     
184     
185     @SCLValue(type = "Resource -> String -> Resource -> Resource")
186     public static Resource compositeInstantiator(final Resource compositeType, final String defaultName, final Resource target) throws DatabaseException {
187         
188         return TypicalUtil.syncExec(procedure -> {
189             if (!SWTUtils.asyncExec(PlatformUI.getWorkbench().getDisplay(), () -> {
190                 try {
191                     queryInitialValuesAndCreateComposite(compositeType, target, defaultName, procedure);
192                 } catch (Throwable t) {
193                     procedure.exception(t);
194                 }
195             })) {
196                 procedure.execute(null);
197             }
198         });
199     }
200
201     private static class DefaultMappingsDialog extends SelectionStatusDialog {
202
203         private Combo vertexMappingCombo;
204         private Combo edgeMappingCombo;
205         private Combo crsCombo;
206         private Composite composite;
207         
208         private Resource configuration;
209         private Map<String, Resource> vertexMappings = new HashMap<>();
210         private Map<String, Resource> edgeMappings = new HashMap<>();
211         private Map<String, Resource> composites = new HashMap<>();
212         private Map<String, Resource> crss = new HashMap<>();
213         private Map<String, Map<String, Resource>> components = new HashMap<>();
214         
215         private Resource defaultVertexMapping;
216         private Resource defaultEdgeMapping;
217         private Resource defaultCRS;
218         
219         private Combo compositeMappingCombo;
220         private Combo componentMappingCombo;
221
222         protected DefaultMappingsDialog(Shell parentShell, Resource configuration) {
223             super(parentShell);
224             this.configuration = configuration;
225             setTitle("Select mappings for new DN diagram");
226         }
227
228         public Resource getDefaultVertexMapping() {
229             return defaultVertexMapping;
230         }
231
232         public Resource getDefaultEdgeMapping() {
233             return defaultEdgeMapping;
234         }
235
236         @Override
237         protected Control createDialogArea(Composite parent) {
238             composite = (Composite) super.createDialogArea(parent);
239             
240             createMappingsGroup(composite);
241             createExistingCompositeGroup(composite);
242             createCRSSettingsGroup(composite);
243             
244             // compute default values
245             Simantics.getSession().asyncRequest(new ReadRequest() {
246
247                 @Override
248                 public void run(ReadGraph graph) throws DatabaseException {
249                     
250                     vertexMappings = getVertexMappings(graph, configuration);
251                     edgeMappings = getEdgeMappings(graph, configuration);
252                     
253                     composites = getComposites(graph, configuration);
254                     if (composites.size() > 0) {
255                         components = getComponents(graph, composites.get(0));
256                     }
257                     
258                     crss = getCRSs(graph, configuration);
259                     
260                     composite.getDisplay().asyncExec(() -> {
261                         
262                         vertexMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()]));
263                         edgeMappingCombo.setItems(edgeMappings.keySet().toArray(new String[edgeMappings.size()]));
264                         
265                         crsCombo.setItems(crss.keySet().toArray(new String[crss.size()]));
266                         
267                         compositeMappingCombo.setItems(composites.keySet().toArray(new String[composites.size()]));
268                         vertexMappingCombo.select(0);
269                         edgeMappingCombo.select(0);
270                         
271                         crsCombo.select(0);
272                         
273                         if (!composites.isEmpty())
274                             compositeMappingCombo.select(0);
275                     }); 
276                     
277                 }
278             });
279             return composite;
280         }
281         
282         protected Map<String, Map<String, Resource>> getComponents(ReadGraph graph, Resource resource) {
283             // TODO Auto-generated method stub
284             return null;
285         }
286
287         protected Map<String, Resource> getComposites(ReadGraph graph, Resource element) throws DatabaseException {
288             
289             Resource indexRoot = graph.sync(new IndexRoot(element));
290             List<Resource> diagrams = ModelingUtils.searchByType(graph, indexRoot, DiagramResource.getInstance(graph).Diagram);
291             
292             List<Resource> nonDistrictComposites = composites.values().stream().filter(comp -> {
293                 try {
294                     return !graph.isInstanceOf(comp, DistrictNetworkResource.getInstance(graph).Composite);
295                 } catch (ServiceException e1) {
296                     LOGGER.error("Could not check if composite " + comp + " is instanceOf DistrictNetwork.composite");
297                     return false;
298                 }
299             }).collect(Collectors.toList());
300             Map<String, Resource> result = new HashMap<>(nonDistrictComposites.size());
301             Layer0 L0 = Layer0.getInstance(graph);
302             nonDistrictComposites.forEach(mapping -> {
303                 try {
304                     String name = graph.getRelatedValue2(mapping, L0.HasName);
305                     result.put(name, mapping);
306                 } catch (DatabaseException e) {
307                     LOGGER.error("Could not read name of " + mapping, e);
308                 }
309             });
310             return result;
311         }
312
313         private void createMappingsGroup(Composite parent) {
314             Group group= new Group(parent, SWT.NONE);
315             group.setFont(parent.getFont());
316             group.setText("Default mappings");
317             GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
318             group.setLayout(new GridLayout(1, false));
319             
320             Composite cmposite = new Composite(group, SWT.NONE);
321             cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
322             cmposite.setLayout(new GridLayout(2, false));
323             
324             Label vertexMappingLabel = new Label(cmposite, SWT.NONE);
325             vertexMappingLabel.setText("Default vertex mapping");
326
327             vertexMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
328             GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo);
329             
330             Label edgeMappingLabel = new Label(cmposite, SWT.NONE);
331             edgeMappingLabel.setText("Default edge mapping");
332
333             edgeMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
334             GridDataFactory.fillDefaults().grab(true, false).applyTo(edgeMappingCombo);
335         }
336         
337         private void createExistingCompositeGroup(Composite parent) {
338             Group group= new Group(parent, SWT.NONE);
339             group.setFont(parent.getFont());
340             group.setText("Mapped composite");
341             GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
342             group.setLayout(new GridLayout(1, false));
343             
344             Composite cmposite = new Composite(group, SWT.NONE);
345             cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
346             cmposite.setLayout(new GridLayout(2, false));
347             
348             Label compositeMappingLabel = new Label(cmposite, SWT.NONE);
349             compositeMappingLabel.setText("Select composite");
350
351             compositeMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
352             GridDataFactory.fillDefaults().grab(true, false).applyTo(compositeMappingCombo);
353             compositeMappingCombo.addSelectionListener(new SelectionAdapter() {
354                 
355                 @Override
356                 public void widgetSelected(SelectionEvent e) {
357                     super.widgetSelected(e);
358                     recalculateMappapleComponents();
359                 }
360             });
361             
362             Label compojnentMappingLabel = new Label(cmposite, SWT.NONE);
363             compojnentMappingLabel.setText("Select component");
364             
365             componentMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
366             GridDataFactory.fillDefaults().grab(true, false).applyTo(componentMappingCombo);
367         }
368         
369         protected void recalculateMappapleComponents() {
370             Simantics.getSession().asyncRequest(new ReadRequest() {
371                 
372                 @Override
373                 public void run(ReadGraph graph) throws DatabaseException {
374                     
375                     
376                     composite.getDisplay().asyncExec(() -> {
377                         
378                     }); 
379                 }
380             });
381         }
382
383         private void createCRSSettingsGroup(Composite parent) {
384             Group group= new Group(parent, SWT.NONE);
385             group.setFont(parent.getFont());
386             group.setText("CRS settings");
387             GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
388             group.setLayout(new GridLayout(1, false));
389             
390             Composite cmposite = new Composite(group, SWT.NONE);
391             cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
392             cmposite.setLayout(new GridLayout(2, false));
393             
394             Label vertexMappingLabel = new Label(cmposite, SWT.NONE);
395             vertexMappingLabel.setText("Default CRS");
396
397             crsCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
398             GridData textData = new GridData(SWT.FILL, SWT.CENTER, true, false);
399             crsCombo.setLayoutData(textData);
400         }
401         
402
403         @Override
404         protected void computeResult() {
405             defaultVertexMapping = vertexMappings.get(vertexMappingCombo.getItem(vertexMappingCombo.getSelectionIndex()));
406             defaultEdgeMapping = edgeMappings.get(edgeMappingCombo.getItem(edgeMappingCombo.getSelectionIndex()));
407             defaultCRS = crss.get(crsCombo.getItem(crsCombo.getSelectionIndex()));
408         }
409
410         public Resource getCRS() {
411             return defaultCRS;
412         }
413         
414     }
415     
416     private static void queryInitialValuesAndCreateComposite(final Resource compositeType, final Resource target,
417             String defaultName, final Procedure<Resource> procedure) {
418         DefaultMappingsDialog dialog = new DefaultMappingsDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), target);
419
420         if (dialog.open() != Dialog.OK) {
421             procedure.execute(null);
422             return;
423         }
424         Simantics.getSession().asyncRequest(
425                 NewCompositeActionFactory.createCompositeRequest(target, defaultName, compositeType),
426                 new Procedure<Resource>() {
427                     @Override
428                     public void execute(Resource composite) {
429                         Simantics.getSession().asyncRequest(new WriteRequest() {
430                             
431                             @Override
432                             public void perform(WriteGraph graph) throws DatabaseException {
433                                 DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
434                                 Resource diagram = graph.getSingleObject(composite, ModelingResources.getInstance(graph).CompositeToDiagram);
435                                 graph.claim(diagram, DN.EdgeDefaultMapping, dialog.getDefaultEdgeMapping());
436                                 graph.claim(diagram, DN.VertexDefaultMapping, dialog.getDefaultVertexMapping());
437                                 graph.claim(diagram, DN.HasSpatialRefSystem, dialog.getCRS());
438                             }
439                         });
440                         DefaultActions.asyncPerformDefaultAction(Simantics.getSession(), composite, false, false, true);
441                         procedure.execute(composite);
442                     }
443
444                     @Override
445                     public void exception(Throwable t) {
446                         LOGGER.error("Failed to create composite, see exception for details.", t);
447                         procedure.exception(t);
448                     }
449                 });
450     }
451
452     public static Collection<Resource> getDistrictDiagrams(ReadGraph graph) throws DatabaseException {
453         Layer0 L0 = Layer0.getInstance(graph);
454         Collection<Resource> indexRoots = graph.sync(new ObjectsWithType(Simantics.getProjectResource(), L0.ConsistsOf, L0.IndexRoot));
455         DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
456         Set<Resource> results = new HashSet<>();
457         for (Resource indexRoot : indexRoots) {
458             Collection<Resource> diagrams = ModelingUtils.searchByType(graph, indexRoot, DN.Diagram);
459             results.addAll(diagrams);
460         }
461         return results;
462     }
463 }