package org.simantics.district.network.ui.contributions;
+import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
import javax.inject.Named;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
-import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.SelectionStatusDialog;
+import org.eclipse.ui.progress.UIJob;
import org.simantics.DatabaseJob;
import org.simantics.Simantics;
import org.simantics.db.ReadGraph;
import org.simantics.db.Resource;
import org.simantics.db.WriteGraph;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.IndexRoot;
import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.UniqueRead;
import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.NameUtils;
import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.db.exception.ValidationException;
import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.procedure.Procedure;
import org.simantics.db.request.Read;
import org.simantics.district.network.ontology.DistrictNetworkResource;
import org.simantics.district.network.ui.function.Functions;
import org.simantics.district.network.ui.internal.Activator;
-import org.simantics.layer0.Layer0;
import org.simantics.utils.ui.ISelectionUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
public class ChangeMappingTypeHandler {
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(ChangeMappingTypeHandler.class);
+
@CanExecute
public boolean canExecute(@Named(IServiceConstants.ACTIVE_SELECTION) ISelection selection) {
List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
@Override
public Boolean perform(ReadGraph graph) throws DatabaseException {
- Layer0 L0 = Layer0.getInstance(graph);
- Resource instanceOf = null;
- for (Resource element : elements) {
- if (instanceOf == null) {
- instanceOf = graph.getSingleObject(element, L0.InstanceOf);
- } else {
- Resource currentInstanceOf = graph.getSingleObject(element, L0.InstanceOf);
- if (!currentInstanceOf.equals(instanceOf)) {
- return false;
- }
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+ for (Resource selection : elements) {
+ if (!graph.isInstanceOf(selection, DN.Element)) {
+ return false;
}
}
return true;
}
});
} catch (DatabaseException e) {
- e.printStackTrace();
+ LOGGER.error("Could not evaluate if mapping can be changed for selection {}", elements, e);
return false;
}
}
-
+
@Execute
public void execute(@Named(IServiceConstants.ACTIVE_SELECTION) Object selection) {
final List<Resource> elements = ISelectionUtils.getPossibleKeys(selection, SelectionHints.KEY_MAIN, Resource.class);
- if (elements.size() < 1)
- return;
+// if (elements.size() < 1)
+// return;
- SelectMappingDialog dialog = new SelectMappingDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), elements);
- if (dialog.open() != Dialog.OK)
- return;
-
- Resource mapping = dialog.getDefaultVertexMapping();
- Job job = new DatabaseJob("Join selected vertices") {
+ CompletableFuture<Map<NamedResource, Collection<NamedResource>>> result = new CompletableFuture<>();
+ Simantics.getSession().asyncRequest(new UniqueRead<Map<NamedResource, Collection<NamedResource>>>() {
@Override
- protected IStatus run(IProgressMonitor monitor) {
- try {
- Simantics.getSession().syncRequest(new WriteRequest() {
-
- @Override
- public void perform(WriteGraph graph) throws DatabaseException {
- DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
- for (Resource element : elements) {
- graph.deny(element, DN.HasMapping);
- graph.claim(element, DN.HasMapping, mapping);
- }
+ public Map<NamedResource, Collection<NamedResource>> perform(ReadGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ Map<NamedResource, Collection<NamedResource>> currents = new HashMap<>();
+ for (Resource element : elements) {
+ Resource currentMapping = graph.getPossibleObject(element, DN.HasMapping);
+ NamedResource mapping = new NamedResource(NameUtils.getSafeName(graph, currentMapping), currentMapping);
+ currents.compute(mapping, (t, u) -> {
+ if (u == null)
+ u = new HashSet<>();
+ try {
+ u.add(new NamedResource(NameUtils.getSafeName(graph, element), element));
+ } catch (ValidationException | ServiceException e) {
+ LOGGER.error("Could not compute name for {}", element, e);
}
+ return u;
});
- } catch (DatabaseException e) {
- return new Status(IStatus.ERROR, Activator.PLUGIN_ID, getName() + " failed.", e);
}
+ return currents;
+ }
+ }, new Procedure<Map<NamedResource, Collection<NamedResource>>>() {
+
+ @Override
+ public void execute(Map<NamedResource, Collection<NamedResource>> results) {
+ result.complete(results);
+ }
+
+ @Override
+ public void exception(Throwable t) {
+ LOGGER.error("Could not compute mappings for selection {}", elements, t);
+ result.completeExceptionally(t);
+ }
+ });
+
+ UIJob uiJob = new UIJob("Change mappings..") {
+
+ @Override
+ public IStatus runInUIThread(IProgressMonitor monitor) {
+ SelectMappingDialog dialog = new SelectMappingDialog(getDisplay().getActiveShell(), result);
+ if (dialog.open() != Dialog.OK)
+ return Status.OK_STATUS;
+
+ Map<Resource, Collection<NamedResource>> results = dialog.getResults();
+ Job job = new DatabaseJob("Join selected vertices") {
+
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ try {
+ Simantics.getSession().syncRequest(new WriteRequest() {
+
+ @Override
+ public void perform(WriteGraph graph) throws DatabaseException {
+ DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
+
+ for (Map.Entry<Resource, Collection<NamedResource>> entry : results.entrySet()) {
+ Resource newMapping = entry.getKey();
+ Collection<NamedResource> elements = entry.getValue();
+ for (NamedResource element : elements) {
+ graph.deny(element.getResource(), DN.HasMapping);
+ graph.claim(element.getResource(), DN.HasMapping, newMapping);
+ }
+ }
+ }
+ });
+ } catch (DatabaseException e) {
+ return new Status(IStatus.ERROR, Activator.PLUGIN_ID, getName() + " failed.", e);
+ }
+ return Status.OK_STATUS;
+ }
+ };
+ job.setUser(true);
+ job.schedule();
return Status.OK_STATUS;
}
};
- job.setUser(true);
- job.schedule();
+ uiJob.setUser(true);
+ uiJob.schedule();
}
private static class SelectMappingDialog extends SelectionStatusDialog {
- private Combo vertexMappingCombo;
+ private Map<NamedResource, Combo> mappingCombos = new HashMap<>();
private Composite composite;
- private List<Resource> elements;
- private Map<String, Resource> vertexMappings = new HashMap<>();
+ private CompletableFuture<Map<NamedResource, Collection<NamedResource>>> elements;
- private Resource defaultVertexMapping;
-
- protected SelectMappingDialog(Shell parentShell, List<Resource> elements) {
+ private Map<NamedResource, Map<String, Resource>> possibleMappings = new HashMap<>();
+
+ protected SelectMappingDialog(Shell parentShell, CompletableFuture<Map<NamedResource, Collection<NamedResource>>> elements) {
super(parentShell);
this.elements = elements;
- setTitle("Select mappings for new DN diagram");
- }
-
- public Resource getDefaultVertexMapping() {
- return defaultVertexMapping;
+ setTitle("Change mappings");
}
@Override
@Override
public void run(ReadGraph graph) throws DatabaseException {
DistrictNetworkResource DN = DistrictNetworkResource.getInstance(graph);
- Resource element = elements.get(0);
- if (graph.isInstanceOf(element, DN.Vertex)) {
- vertexMappings = Functions.getVertexMappings(graph, element);
- } else if (graph.isInstanceOf(element, DN.Edge)) {
- vertexMappings = Functions.getEdgeMappings(graph, element);
+ try {
+ for (Map.Entry<NamedResource, Collection<NamedResource>> entry : elements.get().entrySet()) {
+ NamedResource currentMapping = entry.getKey();
+ Resource resource = entry.getValue().iterator().next().getResource();
+ Resource indexRoot = graph.sync(new IndexRoot(resource));
+ if (graph.isInstanceOf(currentMapping.getResource(), DN.Mapping_VertexMapping)) {
+ possibleMappings.put(currentMapping, Functions.getVertexMappings(graph, indexRoot));
+ } else if (graph.isInstanceOf(currentMapping.getResource(), DN.Mapping_EdgeMapping)) {
+ possibleMappings.put(currentMapping, Functions.getEdgeMappings(graph, indexRoot));
+ }
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
}
composite.getDisplay().asyncExec(() -> {
- vertexMappingCombo.setItems(vertexMappings.keySet().toArray(new String[vertexMappings.size()]));
- vertexMappingCombo.select(0);
- });
-
+ for (Map.Entry<NamedResource, Map<String, Resource>> entry : possibleMappings.entrySet()) {
+ NamedResource key = entry.getKey();
+ Map<String, Resource> value = entry.getValue();
+ Combo combo = mappingCombos.get(key);
+ combo.setItems(value.keySet().toArray(new String[value.size()]));
+ combo.select(0);
+ }
+ });
}
});
return composite;
}
+ private Map<Resource, Collection<NamedResource>> results = new HashMap<>();
+
@Override
protected void computeResult() {
- defaultVertexMapping = vertexMappings.get(vertexMappingCombo.getItem(vertexMappingCombo.getSelectionIndex()));
+ Map<NamedResource, Collection<NamedResource>> currentElements = null;
+ try {
+ currentElements = elements.get();
+ } catch (InterruptedException | ExecutionException e) {
+ LOGGER.error("Could not get currentElements", e);
+ throw new RuntimeException("Could not get currentElements", e);
+ }
+ for (Map.Entry<NamedResource, Combo> combos : mappingCombos.entrySet()) {
+ NamedResource resource = combos.getKey();
+ Combo c = combos.getValue();
+ String item = c.getItem(c.getSelectionIndex());
+ Collection<NamedResource> collection = currentElements.get(resource);
+ Map<String, Resource> map = possibleMappings.get(resource);
+ Resource newMapping = map.get(item);
+ results.compute(newMapping, (t, u) -> {
+ if (u == null) {
+ u = new HashSet<>();
+ }
+ u.addAll(collection);
+ return u;
+ });
+ }
}
-
+
+ public Map<Resource, Collection<NamedResource>> getResults() {
+ return results;
+ }
+
private void createMappingsGroup(Composite parent) {
- Group group= new Group(parent, SWT.NONE);
- group.setFont(parent.getFont());
- group.setText("Default mappings");
- GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
- group.setLayout(new GridLayout(1, false));
-
- Composite cmposite = new Composite(group, SWT.NONE);
- cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
- cmposite.setLayout(new GridLayout(2, false));
-
- Label vertexMappingLabel = new Label(cmposite, SWT.NONE);
- vertexMappingLabel.setText("Default vertex mapping");
+ try {
+ for (Map.Entry<NamedResource, Collection<NamedResource>> entry : elements.get().entrySet()) {
+
+ NamedResource currentMapping = entry.getKey();
+
+ Collection<NamedResource> mappedElements = entry.getValue();
+
+ Group group= new Group(parent, SWT.NONE);
+ group.setFont(parent.getFont());
+ group.setText(currentMapping.getName() + " currently mapped to " + mappedElements.size() + " elements");
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(group);
+ group.setLayout(new GridLayout(1, false));
+
+ Composite cmposite = new Composite(group, SWT.NONE);
+ cmposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
+ cmposite.setLayout(new GridLayout(2, false));
+
+ Label vertexMappingLabel = new Label(cmposite, SWT.NONE);
+ vertexMappingLabel.setText("New mapping type");
- vertexMappingCombo = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
- GridDataFactory.fillDefaults().grab(true, false).applyTo(vertexMappingCombo);
-
+ Combo c = new Combo(cmposite, SWT.READ_ONLY | SWT.BORDER);
+ GridDataFactory.fillDefaults().grab(true, false).applyTo(c);
+ mappingCombos.put(entry.getKey(), c);
+ }
+ } catch (InterruptedException | ExecutionException e) {
+ e.printStackTrace();
+ }
}
}
}