View for used SCL expressions 68/668/2
authorjsimomaa <jani.simomaa@gmail.com>
Fri, 30 Jun 2017 10:30:57 +0000 (13:30 +0300)
committerjsimomaa <jani.simomaa@gmail.com>
Fri, 30 Jun 2017 11:26:02 +0000 (14:26 +0300)
refs #7344

Change-Id: Ic2e902fc9742afce80e1ead764528e8eb35704a6

bundles/org.simantics.modeling.ui/icons/arrow_refresh.png [new file with mode: 0644]
bundles/org.simantics.modeling.ui/plugin.xml
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/Activator.java
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionItemFilter.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionTableEntry.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionView.java [new file with mode: 0644]
bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/UsedSCLExpressionsRequest.java [new file with mode: 0644]

diff --git a/bundles/org.simantics.modeling.ui/icons/arrow_refresh.png b/bundles/org.simantics.modeling.ui/icons/arrow_refresh.png
new file mode 100644 (file)
index 0000000..0de2656
Binary files /dev/null and b/bundles/org.simantics.modeling.ui/icons/arrow_refresh.png differ
index c6596a7b0c73749a619ce2baa827bc621576778f..64d39a0e2b8190edc26891ea37d6f43212dbcd79 100644 (file)
    </extension>
    <extension
          point="org.eclipse.ui.views">
+      <view
+            allowMultiple="false"
+            category="org.simantics.scl.ui.category"
+            class="org.simantics.modeling.ui.scl.expressions.SCLExpressionView"
+            id="org.simantics.modeling.ui.scl.expressionsView"
+            name="Used SCL Expressions"
+            restorable="true">
+      </view>
       <view
             name="Diagram Tools"
             icon="platform:/plugin/com.famfamfam.silk/icons/wrench.png"
index c4146d6f2394f550199ccd69b37a0cf730ff8ac6..788615ae08e3bed0b3167a263fc7b2955c86f8d5 100644 (file)
@@ -92,6 +92,8 @@ public class Activator extends AbstractUIPlugin {
     public static ImageDescriptor POINTER_MODE;
     public static ImageDescriptor CONNECT_MODE;
 
+    public static ImageDescriptor ARROW_REFRESH;
+
     @Override
     public void start(BundleContext context) throws Exception {
         super.start(context);
@@ -169,6 +171,8 @@ public class Activator extends AbstractUIPlugin {
         POINTER_MODE = ImageDescriptor.createFromURL(bundle.getResource("icons/pointertool.png"));
         CONNECT_MODE = ImageDescriptor.createFromURL(bundle.getResource("icons/connecttool.png"));
         
+        ARROW_REFRESH = ImageDescriptor.createFromURL(bundle.getResource("icons/arrow_refresh.png"));
+        
         Hashtable<String, String> properties = new Hashtable<String, String>();
         context.registerService(SCLConsoleListener.class,
                 new SCLConsoleListener() {
@@ -202,6 +206,7 @@ public class Activator extends AbstractUIPlugin {
         reg.put("arrowDown", ARROW_DOWN_ICON);
         reg.put("showProfileMonitors", SHOW_PROFILE_MONITOR_ICON);
         reg.put("hideProfileMonitors", HIDE_PROFILE_MONITOR_ICON);
+        reg.put("arrow_refresh", ARROW_REFRESH);
     }
 
     /*
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionItemFilter.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionItemFilter.java
new file mode 100644 (file)
index 0000000..bcc8b02
--- /dev/null
@@ -0,0 +1,24 @@
+package org.simantics.modeling.ui.scl.expressions;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+public class SCLExpressionItemFilter extends ViewerFilter {
+
+    private String searchString;
+
+    public void setSearchText(String s) {
+        // ensure that the value can be used for matching
+        this.searchString = (".*" + s + ".*").toLowerCase();
+    }
+
+    @Override
+    public boolean select(Viewer viewer, Object parentElement, Object element) {
+        if (searchString == null || searchString.length() == 0)
+            return true;
+        SCLExpressionTableEntry entry = (SCLExpressionTableEntry) element;
+        if (entry.getContent().toLowerCase().matches(searchString))
+            return true;
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionTableEntry.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionTableEntry.java
new file mode 100644 (file)
index 0000000..6cfb460
--- /dev/null
@@ -0,0 +1,34 @@
+package org.simantics.modeling.ui.scl.expressions;
+
+import org.simantics.db.Resource;
+
+public class SCLExpressionTableEntry implements Comparable<SCLExpressionTableEntry> {
+
+    private final String content;
+    private final String location;
+    private final Resource resource;
+
+    public SCLExpressionTableEntry(String content, String position, Resource resource) {
+        this.content = content;
+        this.location = position;
+        this.resource = resource;
+    }
+
+    public String getContent() {
+        return content;
+    }
+
+    public String getLocation() {
+        return location;
+    }
+
+    public Resource getResource() {
+        return resource;
+    }
+
+    @Override
+    public int compareTo(SCLExpressionTableEntry o) {
+        return o.getContent().compareTo(content);
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionView.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/SCLExpressionView.java
new file mode 100644 (file)
index 0000000..d9bf77e
--- /dev/null
@@ -0,0 +1,192 @@
+package org.simantics.modeling.ui.scl.expressions;
+
+import java.util.Collection;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.action.Action;
+import org.eclipse.jface.action.IAction;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.KeyAdapter;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Text;
+import org.eclipse.ui.IMemento;
+import org.eclipse.ui.IViewSite;
+import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.part.ViewPart;
+import org.simantics.DatabaseJob;
+import org.simantics.Simantics;
+import org.simantics.db.Resource;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.modeling.ui.Activator;
+import org.simantics.ui.workbench.action.ChooseActionRequest;
+import org.simantics.utils.ui.workbench.WorkbenchUtils;
+
+public class SCLExpressionView extends ViewPart {
+
+    private TableViewer tableViewer;
+    private TableViewerColumn expressionColumn;
+    private TableViewerColumn locationColumn;
+
+    private ImageRegistry imageRegistry;
+    private IStructuredContentProvider expressionContentProvider;
+    private SCLExpressionItemFilter expressionFilter;
+
+    public SCLExpressionView() {
+        imageRegistry = Activator.getDefault().getImageRegistry();
+        expressionContentProvider = ArrayContentProvider.getInstance();
+    }
+
+    @Override
+    public void init(IViewSite site, IMemento memento) throws PartInitException {
+        super.init(site, memento);
+        IAction action = new Action("Refresh") {
+            @Override
+            public void run() {
+                scheduleUpdateEntries();
+            }
+        };
+        action.setImageDescriptor(imageRegistry.getDescriptor("arrow_refresh"));
+        site.getActionBars().getToolBarManager().add(action);
+    }
+
+    private void createFilter(Composite parent) {
+        expressionFilter = new SCLExpressionItemFilter();
+
+        Text searchText = new Text(parent, SWT.BORDER | SWT.SEARCH);
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(searchText);
+        searchText.addKeyListener(new KeyAdapter() {
+
+            @Override
+            public void keyReleased(KeyEvent e) {
+                expressionFilter.setSearchText(searchText.getText());
+                tableViewer.refresh();
+            }
+        });
+    }
+
+    @Override
+    public void createPartControl(Composite parent) {
+        parent.setLayout(new GridLayout(1, false));
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(parent);
+        createFilter(parent);
+
+        Composite tableParent = new Composite(parent, SWT.NONE);
+        GridDataFactory.fillDefaults().grab(true, true).applyTo(tableParent);
+
+        tableViewer = new TableViewer(tableParent,
+                SWT.FULL_SELECTION | SWT.SINGLE | SWT.V_SCROLL | SWT.H_SCROLL | SWT.VIRTUAL);
+        ColumnViewerToolTipSupport.enableFor(tableViewer);
+        tableViewer.setContentProvider(expressionContentProvider);
+        tableViewer.addFilter(expressionFilter);
+
+        Table table = tableViewer.getTable();
+        table.setHeaderVisible(true);
+        table.setLinesVisible(true);
+
+        TableColumnLayout layout = new TableColumnLayout();
+        tableParent.setLayout(layout);
+
+        expressionColumn = new TableViewerColumn(tableViewer, SWT.NONE);
+        expressionColumn.getColumn().setText("Expression");
+        expressionColumn.getColumn().setResizable(true);
+        expressionColumn.setLabelProvider(new ColumnLabelProvider() {
+            @Override
+            public String getText(Object element) {
+                SCLExpressionTableEntry entry = (SCLExpressionTableEntry) element;
+                return entry.getContent();
+            }
+        });
+
+        layout.setColumnData(expressionColumn.getColumn(), new ColumnWeightData(100));
+
+        locationColumn = new TableViewerColumn(tableViewer, SWT.NONE);
+        locationColumn.getColumn().setText("Location");
+        locationColumn.getColumn().setResizable(false);
+        locationColumn.setLabelProvider(new ColumnLabelProvider() {
+            @Override
+            public String getText(Object element) {
+                SCLExpressionTableEntry entry = (SCLExpressionTableEntry) element;
+                if (entry.getLocation() != null)
+                    return entry.getLocation();
+                return "null";
+            }
+        });
+
+        layout.setColumnData(locationColumn.getColumn(), new ColumnWeightData(100));
+        tableViewer.addDoubleClickListener(new IDoubleClickListener() {
+            @Override
+            public void doubleClick(DoubleClickEvent event) {
+                IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+                SCLExpressionTableEntry entry = (SCLExpressionTableEntry) selection.getFirstElement();
+
+                openResource(tableViewer.getControl().getDisplay().getActiveShell(), entry.getResource());
+            }
+        });
+        scheduleUpdateEntries();
+    }
+
+    private void scheduleUpdateEntries() {
+        Job updateJob = new DatabaseJob("Update used SCL expressions") {
+
+            @Override
+            protected IStatus run(IProgressMonitor monitor) {
+                try {
+                    Collection<SCLExpressionTableEntry> result = Simantics.getSession()
+                            .syncRequest(new UsedSCLExpressionsRequest());
+                    tableViewer.getTable().getDisplay().asyncExec(() -> {
+                        tableViewer.setInput(result);
+                    });
+                    return Status.OK_STATUS;
+                } catch (DatabaseException e) {
+                    e.printStackTrace();
+                    return new Status(IStatus.ERROR, Activator.PLUGIN_ID, "Could not update SCL expressions", e);
+                }
+            }
+        };
+        updateJob.schedule();
+    }
+
+    private static void openResource(Shell shell, Resource resource) {
+        try {
+            ISelection input = new StructuredSelection(resource);
+            String perspectiveId = WorkbenchUtils.getCurrentPerspectiveId();
+            // Try the doubleClick-extensions
+            Simantics.getSession().asyncRequest(new ChooseActionRequest(shell, input, perspectiveId, false, true));
+        } catch (NumberFormatException e) {
+            return;
+        }
+    }
+
+    @Override
+    public void setFocus() {
+        tableViewer.getControl().setFocus();
+    }
+
+    @Override
+    public void dispose() {
+        super.dispose();
+    }
+
+}
diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/UsedSCLExpressionsRequest.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/scl/expressions/UsedSCLExpressionsRequest.java
new file mode 100644 (file)
index 0000000..4e62af2
--- /dev/null
@@ -0,0 +1,90 @@
+package org.simantics.modeling.ui.scl.expressions;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.ModelingUtils;
+import org.simantics.structural.stubs.StructuralResource2;
+
+public class UsedSCLExpressionsRequest extends UniqueRead<Collection<SCLExpressionTableEntry>> {
+
+    @Override
+    public Collection<SCLExpressionTableEntry> perform(ReadGraph graph) throws DatabaseException {
+        Collection<SCLExpressionTableEntry> result = new ArrayList<>();
+        Layer0 L0 = Layer0.getInstance(graph);
+        
+        Set<Resource> indexRoots = new TreeSet<Resource>();
+        for(Resource ontology : Layer0Utils.listOntologies(graph)) {
+            if (graph.isInstanceOf(ontology, L0.SharedOntology)) {
+                indexRoots.add(ontology);
+            }
+        }
+        
+        for(Resource child : graph.getObjects(Simantics.getProjectResource(), L0.ConsistsOf)) {
+            if (graph.isInstanceOf(child, L0.IndexRoot)) {
+                indexRoots.add(child);
+            }
+        }
+
+        for (Resource ontology : indexRoots) {
+//            List<Resource> modules = ModelingUtils.searchByTypeShallow(graph, ontology, L0.SCLModule);
+//            for (Resource module : modules) {
+//                String definition = graph.getPossibleRelatedValue2(module, L0.SCLModule_definition);
+//                Matcher matcher = pattern.matcher(definition);
+//                while (matcher.find()) {
+//                    int index = matcher.start();
+//                    int line = 1;
+//                    int pos = 0;
+//                    while ((pos = definition.indexOf("\n", pos) + 1) > 0 && pos <= index) {
+//                        line++;
+//                    }
+//                    String position = graph.getPossibleURI(module) + ":" + line;
+//                    int lineBeginIndex = definition.lastIndexOf("\n", index);
+//                    if (lineBeginIndex == -1) lineBeginIndex = 0;
+//                    int lineEndIndex = definition.indexOf("\n", index);
+//                    if (lineEndIndex <= 0) lineEndIndex = definition.length();
+//                    String content = definition.substring(lineBeginIndex, lineEndIndex).trim();
+//
+//                    result.add(new SCLExpressionTableEntry(content, position));
+//                }
+//            }
+            
+            StructuralResource2 STR = StructuralResource2.getInstance(graph);
+            
+            List<Resource> components = ModelingUtils.searchByTypeShallow(graph, ontology, STR.Component);
+            for (Resource component : components) {
+                for (Statement propertyStatement : graph.getStatements(component, L0.HasProperty)) {
+                    if (graph.isInstanceOf(propertyStatement.getObject(), L0.SCLValue)) {
+                        Resource sclValue = propertyStatement.getObject();
+                        String expression = graph.getPossibleRelatedValue2(sclValue, L0.SCLValue_expression);
+                        Resource source = graph.getPossibleObject(sclValue, L0.PropertyOf);
+                        if (source != null) {
+                            String uri = graph.getPossibleURI(source);
+                            String pred = graph.getRelatedValue2(propertyStatement.getPredicate(), L0.HasName);
+
+                            if (uri != null) {
+//                                SCLReporting.print();
+//                                SCLReporting.printError(expression + "\n");
+                                
+                                result.add(new SCLExpressionTableEntry(expression, uri + "#" + pred, source));
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+}