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