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