Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Bundle-ActivationPolicy: lazy
Export-Package: org.simantics.interop.browsing,
- org.simantics.interop.issues,
org.simantics.interop.stubs,
org.simantics.interop.test,
org.simantics.interop.utils
name="Comparator"\r
restorable="true">\r
</view>\r
- <view\r
- class="org.simantics.interop.ui.IssuesViewPart"\r
- icon="platform:/plugin/com.famfamfam.silk/icons/building_error.png"\r
- id="org.simantics.interop.issues"\r
- name="Issues"\r
- restorable="true">\r
- </view>\r
</extension>\r
<extension\r
point="org.eclipse.ui.importWizards">\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.eclipse.swt.widgets.Display;\r
-\r
-public abstract class AbstractIssue implements Issue{\r
- \r
- private String description;\r
- private List<IssueListener> listeners = new ArrayList<IssueListener>();\r
- \r
- @Override\r
- public String getDescription() {\r
- return description;\r
- }\r
- \r
- public void setDescription(String description) {\r
- this.description = description;\r
- fireUpdated();\r
- }\r
- \r
- protected void fireUpdated() {\r
- Display.getDefault().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- synchronized (listeners) {\r
- for (IssueListener l : listeners) {\r
- l.updated(AbstractIssue.this);\r
- } \r
- }\r
- \r
- }\r
- });\r
- }\r
- \r
- protected void fireDisposed() {\r
- Display.getDefault().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- List<IssueListener> list = new ArrayList<IssueListener>();\r
- list.addAll(listeners);\r
- for (IssueListener l : list) {\r
- l.disposed(AbstractIssue.this);\r
- }\r
- listeners.clear();\r
- }\r
- });\r
- }\r
- \r
- @Override\r
- public void addListener(IssueListener listener) {\r
- synchronized(listeners) {\r
- listeners.add(listener);\r
- }\r
- }\r
- \r
- @Override\r
- public void removeListener(IssueListener listener) {\r
- synchronized(listeners) {\r
- listeners.remove(listener);\r
- }\r
- }\r
- \r
- @Override\r
- public void dispose() {\r
- fireDisposed();\r
- }\r
-\r
-}\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.request.Read;\r
-\r
-/**\r
- * AndRead can be used to combine multiple requests into single one. If all reads return true or null, this returns true.\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class AndRead implements Read<Boolean>{\r
-\r
- private Read<Boolean> reads[];\r
- \r
- public AndRead(Read<Boolean>... reads) {\r
- this.reads = reads;\r
- }\r
- \r
- @Override\r
- public Boolean perform(ReadGraph graph) throws DatabaseException {\r
- Boolean b = null;\r
- for (Read<Boolean> r : reads) {\r
- b = r.perform(graph);\r
- if(b != null && !b)\r
- return false;\r
- }\r
- return true;\r
- }\r
-}\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-/**\r
- * Basic, static issue.\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class BasicIssue extends AbstractIssue {\r
-\r
- \r
- public BasicIssue(String description) {\r
- setDescription(description);\r
- }\r
- \r
- @Override\r
- public void showInEditor() {\r
- \r
- }\r
- \r
- @Override\r
- public boolean supportsEditor() {\r
- return false;\r
- }\r
- \r
- \r
-}\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-import org.simantics.db.AsyncReadGraph;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.procedure.AsyncListener;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.utils.ui.ErrorLogger;\r
-\r
-/**\r
- * An issue whose state can be updated with an query\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class GraphIssue extends AbstractIssue {\r
- \r
- private boolean disposed = false;\r
- \r
- /**\r
- * Creates an new Graph Issue\r
- * @param g access to graph\r
- * @param request Request that returns true if issue is still valid. If the request returns false, the issue is disposed.\r
- * @param description\r
- */\r
- public GraphIssue(ReadGraph g, Read<Boolean> request, String description) {\r
- setDescription(description);\r
- IssueReporter.getInstance().addIssue(this);\r
- setRequest(g, request);\r
- }\r
- \r
- public GraphIssue(String description) {\r
- setDescription(description);\r
- IssueReporter.getInstance().addIssue(this);\r
- }\r
- \r
- public void setRequest(ReadGraph g, Read<Boolean> request) {\r
- g.asyncRequest(request,new AsyncListener<Boolean>() {\r
- @Override\r
- public void execute(AsyncReadGraph graph, Boolean result) {\r
- if (result == null)\r
- return;\r
- \r
- if (!result) {\r
- dispose();\r
- }\r
- }\r
- \r
- @Override\r
- public void exception(AsyncReadGraph graph, Throwable throwable) {\r
- ErrorLogger.defaultLogError("Error in GraphIssue handling, disposing issue \"" + getDescription()+"\"", throwable);\r
- dispose(); \r
- }\r
- \r
- @Override\r
- public boolean isDisposed() {\r
- return disposed;\r
- }\r
- });\r
- }\r
- \r
- @Override\r
- public void showInEditor() {\r
- \r
- }\r
- \r
- @Override\r
- public boolean supportsEditor() {\r
- return false;\r
- }\r
- \r
- @Override\r
- public void dispose() {\r
- this.disposed = true;\r
- super.dispose();\r
- }\r
-\r
-}\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-/**\r
- * Interface for an issue\r
- * \r
- * TODO: grouping, severity?\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public interface Issue {\r
- \r
- /**\r
- * Prints description\r
- * @return\r
- */\r
- public String getDescription();\r
- \r
- /**\r
- * Returns true if this issue can be highlighted in an editor\r
- * @return\r
- */\r
- public boolean supportsEditor();\r
- \r
- /**\r
- * Opens and highlights the reason of the issue in an editor\r
- */\r
- public void showInEditor();\r
- \r
- /**\r
- * Disposes the issue.\r
- */\r
- public void dispose();\r
- \r
- public void addListener(IssueListener listenr);\r
- public void removeListener(IssueListener listener);\r
-\r
-}\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-/**\r
- * Interface for listening changes in issues.\r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public interface IssueListener {\r
- \r
- /**\r
- * Issues is updated\r
- * @param issue\r
- */\r
- public void updated(Issue issue);\r
- \r
- /**\r
- * Issue is disposed (not valid anymore);\r
- * @param issue\r
- */\r
- public void disposed(Issue issue);\r
-\r
-}\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.List;\r
-\r
-import org.eclipse.swt.widgets.Display;\r
-\r
-/**\r
- * IssueReporter is singleton class that handles collecting issues.\r
- * \r
- * TODO: how to store issues when the application is closed? Memento-based?\r
- * \r
- * @author Marko Luukkainen <marko.luukkainen@vtt.fi>\r
- *\r
- */\r
-public class IssueReporter implements IssueListener{\r
- \r
- private static IssueReporter INSTANCE;\r
- \r
- private List<Issue> issues = new ArrayList<Issue>();\r
- private List<IssueReporterListener> listeners = new ArrayList<IssueReporterListener>();\r
- \r
- \r
- private IssueReporter() {\r
- \r
- }\r
- \r
- public static IssueReporter getInstance() {\r
- if (INSTANCE == null)\r
- INSTANCE = new IssueReporter();\r
- return INSTANCE;\r
- }\r
- \r
- /**\r
- * Retuns list of issues.\r
- * @return\r
- */\r
- public List<Issue> getIssues() {\r
- return Collections.unmodifiableList(issues);\r
- }\r
- \r
- public void addIssue(Issue issue) {\r
- issues.add(issue);\r
- issue.addListener(this);\r
- fireAdded(issue);\r
- }\r
- \r
- public void removeIssue(Issue issue) {\r
- issue.removeListener(this);\r
- issues.remove(issue);\r
- fireRemoved(issue);\r
- }\r
- \r
- @Override\r
- public void updated(Issue issue) {\r
- fireUpdated(issue);\r
- }\r
- \r
- @Override\r
- public void disposed(Issue issue) {\r
- issue.removeListener(this);\r
- issues.remove(issue);\r
- fireRemoved(issue);\r
- }\r
- \r
- \r
- public void addListener(IssueReporterListener listener) {\r
- listeners.add(listener);\r
- }\r
- \r
- public void removeListener(IssueReporterListener listener) {\r
- listeners.remove(listener);\r
- }\r
- \r
- protected void fireAdded(final Issue issue) {\r
- Display.getDefault().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- for (IssueReporterListener l : listeners)\r
- l.added(issue);\r
- }\r
- });\r
- }\r
- \r
- protected void fireRemoved(final Issue issue) {\r
- Display.getDefault().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- for (IssueReporterListener l : listeners)\r
- l.removed(issue);\r
- }\r
- });\r
- }\r
- \r
- protected void fireUpdated(final Issue issue) {\r
- Display.getDefault().asyncExec(new Runnable() {\r
- @Override\r
- public void run() {\r
- for (IssueReporterListener l : listeners)\r
- l.updated(issue);\r
- }\r
- });\r
- }\r
- \r
-\r
-}\r
+++ /dev/null
-package org.simantics.interop.issues;\r
-\r
-public interface IssueReporterListener {\r
- \r
- public void added(Issue issue);\r
- public void removed(Issue issue);\r
- public void updated(Issue issue);\r
-\r
-}\r
+++ /dev/null
-package org.simantics.interop.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.List;\r
-\r
-import org.eclipse.jface.viewers.ILabelProviderListener;\r
-import org.eclipse.jface.viewers.IStructuredContentProvider;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.jface.viewers.ITableLabelProvider;\r
-import org.eclipse.jface.viewers.TableViewer;\r
-import org.eclipse.jface.viewers.Viewer;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.events.SelectionAdapter;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.graphics.Image;\r
-import org.eclipse.swt.layout.FillLayout;\r
-import org.eclipse.swt.layout.GridData;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Button;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.ui.part.ViewPart;\r
-import org.simantics.interop.issues.Issue;\r
-import org.simantics.interop.issues.IssueReporter;\r
-import org.simantics.interop.issues.IssueReporterListener;\r
-\r
-public class IssuesViewPart extends ViewPart {\r
-\r
- private Composite parent;\r
- private TableViewer viewer;\r
- \r
- \r
- public IssuesViewPart() {\r
- // TODO Auto-generated constructor stub\r
- }\r
-\r
- @Override\r
- public void createPartControl(Composite parent) {\r
- this.parent = parent;\r
- this.parent.setLayout(new GridLayout(1,false));\r
- viewer = new TableViewer(parent);\r
- viewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));\r
- viewer.setContentProvider(new IssueContentProvider());\r
- viewer.setLabelProvider(new IssueLabelProvider());\r
- \r
- viewer.setInput(IssueReporter.getInstance().getIssues());\r
- \r
- Composite buttonComposite = new Composite(parent, SWT.BORDER);\r
- buttonComposite.setLayout(new FillLayout(SWT.HORIZONTAL));\r
- Button clearButton = new Button(buttonComposite, SWT.PUSH);\r
- clearButton.setText("Clear all");\r
- clearButton.addSelectionListener(new SelectionAdapter() {\r
- @Override\r
- public void widgetSelected(SelectionEvent e) {\r
- Collection<Issue> issues = IssueReporter.getInstance().getIssues();\r
- for (Issue i : issues)\r
- i.dispose();\r
- }\r
- });\r
- \r
- Button showButton = new Button(buttonComposite, SWT.PUSH);\r
- showButton.setText("Show in editor");\r
- showButton.addSelectionListener(new SelectionAdapter() {\r
- @Override\r
- public void widgetSelected(SelectionEvent e) {\r
- IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();\r
- if (sel.isEmpty())\r
- return;\r
- Issue i = (Issue)sel.getFirstElement();\r
- if (i.supportsEditor())\r
- i.showInEditor();\r
- }\r
- });\r
- \r
- \r
- }\r
-\r
- @Override\r
- public void setFocus() {\r
- parent.setFocus();\r
- }\r
- \r
- \r
- private class IssueContentProvider implements IStructuredContentProvider {\r
- private IssueReporterListener listener;\r
- private Viewer viewer;\r
- \r
- public IssueContentProvider() {\r
- listener = new IssueReporterListener() {\r
- \r
- @Override\r
- public void updated(Issue issue) {\r
- viewer.refresh();\r
- }\r
- \r
- @Override\r
- public void removed(Issue issue) {\r
- viewer.setInput(IssueReporter.getInstance().getIssues());\r
- }\r
- \r
- @Override\r
- public void added(Issue issue) {\r
- viewer.setInput(IssueReporter.getInstance().getIssues());\r
- }\r
- };\r
- IssueReporter.getInstance().addListener(listener);\r
- }\r
- \r
- \r
- @SuppressWarnings("unchecked")\r
- @Override\r
- public Object[] getElements(Object inputElement) {\r
- Collection<Issue> issues = (Collection<Issue>)inputElement;\r
- return issues.toArray();\r
- }\r
- \r
- @Override\r
- public void dispose() {\r
- IssueReporter.getInstance().removeListener(listener);\r
- }\r
- \r
- @Override\r
- public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {\r
- this.viewer = viewer;\r
- }\r
- }\r
- \r
- private class IssueLabelProvider implements ITableLabelProvider {\r
- \r
- private List<ILabelProviderListener> listeners = new ArrayList<ILabelProviderListener>();\r
- \r
- @Override\r
- public Image getColumnImage(Object element, int columnIndex) {\r
- return null;\r
- }\r
- \r
- @Override\r
- public String getColumnText(Object element, int columnIndex) {\r
- Issue issue = (Issue)element;\r
- if (columnIndex == 0)\r
- return issue.getDescription();\r
- return null;\r
- }\r
- \r
- @Override\r
- public boolean isLabelProperty(Object element, String property) {\r
- return true;\r
- }\r
- \r
- @Override\r
- public void addListener(ILabelProviderListener listener) {\r
- listeners.add(listener);\r
- }\r
- \r
- @Override\r
- public void removeListener(ILabelProviderListener listener) {\r
- listeners.remove(listener);\r
- }\r
- \r
- @Override\r
- public void dispose() {\r
- \r
- }\r
- }\r
-\r
-}\r
--- /dev/null
+package org.simantics.interop.utils;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.LinkedHashMap;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.Map.Entry;\r
+\r
+import org.simantics.utils.datastructures.BijectionMap;\r
+\r
+public class LinkedBijectionMap<L, R> {\r
+ /** The keys of tableLeft are left-side-values and\r
+ * values are right-side-values */\r
+ private final Map<L, R> tableLeft = new LinkedHashMap<L, R>();\r
+ /** The keys of tableRight are right-side-values and\r
+ * values on it are left-side-values */\r
+ private final Map<R, L> tableRight = new LinkedHashMap<R, L>();\r
+\r
+ /** The keys of tableLeft are left-side-values and\r
+ * values are right-side-values */\r
+ private final Map<L, R> imTableLeft = Collections.unmodifiableMap(tableLeft);\r
+ /** The keys of tableRight are right-side-values and\r
+ * values on it are left-side-values */\r
+ private final Map<R, L> imTableRight = Collections.unmodifiableMap(tableRight);\r
+\r
+ private final Set<L> imLeftSet = Collections.unmodifiableSet(tableLeft.keySet());\r
+ private final Set<R> imRightSet = Collections.unmodifiableSet(tableRight.keySet());\r
+\r
+ public LinkedBijectionMap() {\r
+\r
+ }\r
+\r
+ public LinkedBijectionMap(LinkedBijectionMap<L, R> copyFrom) {\r
+ this.tableLeft.putAll(copyFrom.tableLeft);\r
+ this.tableRight.putAll(copyFrom.tableRight);\r
+ }\r
+\r
+ public void addAll(BijectionMap<L, R> map)\r
+ {\r
+ for (Entry<L, R> e : map.getEntries())\r
+ map(e.getKey(), e.getValue());\r
+ }\r
+\r
+ public boolean retainAllLeft(Collection<L> values)\r
+ {\r
+ boolean result = false;\r
+ Collection<L> remove = new ArrayList<L>(size());\r
+ for (L lValue : imLeftSet) {\r
+ if (!values.contains(lValue)) {\r
+ remove.add(lValue);\r
+ result = true;\r
+ }\r
+ }\r
+ if (!remove.isEmpty()) {\r
+ for (L lValue : remove)\r
+ removeWithLeft(lValue);\r
+ }\r
+ return result;\r
+ }\r
+\r
+ public boolean retainAllRight(Collection<R> values)\r
+ {\r
+ boolean result = false;\r
+ Collection<R> remove = new ArrayList<R>(size());\r
+ for (R rValue : imRightSet) {\r
+ if (!values.contains(rValue)) {\r
+ remove.add(rValue);\r
+ result = true;\r
+ }\r
+ }\r
+ if (!remove.isEmpty()) {\r
+ for (R rValue : remove)\r
+ removeWithRight(rValue);\r
+ }\r
+ return result;\r
+ }\r
+\r
+ public Set<Entry<L, R>> getEntries()\r
+ {\r
+ return tableLeft.entrySet();\r
+ }\r
+\r
+ public boolean containsLeft(L leftValue)\r
+ {\r
+ return tableLeft.containsKey(leftValue);\r
+ }\r
+\r
+ public boolean containsRight(R rightValue)\r
+ {\r
+ return tableRight.containsKey(rightValue);\r
+ }\r
+\r
+ public boolean contains(L leftValue, R rightValue)\r
+ {\r
+ if (leftValue==null || rightValue==null) return false;\r
+ return rightValue.equals(tableLeft.get(leftValue));\r
+ }\r
+\r
+ public void map(L leftValue, R rightValue)\r
+ {\r
+ if (leftValue == null || rightValue == null)\r
+ throw new NullPointerException();\r
+ // Remove possible old mapping\r
+ R oldRight = tableLeft.remove(leftValue);\r
+ if (oldRight != null) {\r
+ tableRight.remove(oldRight);\r
+ } else {\r
+ L oldLeft = tableRight.remove(rightValue);\r
+ if (oldLeft != null) {\r
+ tableLeft.remove(oldLeft);\r
+ }\r
+ }\r
+\r
+ tableLeft.put(leftValue, rightValue);\r
+ tableRight.put(rightValue, leftValue);\r
+ }\r
+\r
+ public boolean isEmpty() {\r
+ return tableLeft.isEmpty();\r
+ }\r
+\r
+ public int size()\r
+ {\r
+ return tableLeft.size();\r
+ }\r
+\r
+ public L getLeft(R rightValue) {\r
+ return tableRight.get(rightValue);\r
+ }\r
+\r
+ public R getRight(L leftValue) {\r
+ return tableLeft.get(leftValue);\r
+ }\r
+\r
+ public R removeWithLeft(L leftValue) {\r
+ R rightValue = tableLeft.remove(leftValue);\r
+ if (rightValue!=null)\r
+ tableRight.remove(rightValue);\r
+ return rightValue;\r
+ }\r
+\r
+ public L removeWithRight(R rightValue) {\r
+ L leftValue = tableRight.remove(rightValue);\r
+ if (leftValue!=null)\r
+ tableLeft.remove(leftValue);\r
+ return leftValue;\r
+ }\r
+\r
+ /**\r
+ * Get set of left values\r
+ *\r
+ * @return read-only set\r
+ */\r
+ public Set<L> getLeftSet() {\r
+ return imLeftSet;\r
+ }\r
+\r
+ /**\r
+ * Get set of right values\r
+ *\r
+ * @return read-only set\r
+ */\r
+ public Set<R> getRightSet() {\r
+ return imRightSet;\r
+ }\r
+\r
+ /**\r
+ * Get left-to-right map\r
+ *\r
+ * @return read only map\r
+ */\r
+ public Map<L, R> getLeftToRightMap() {\r
+ return imTableLeft;\r
+ }\r
+\r
+ /**\r
+ * Get right-to-left map\r
+ *\r
+ * @return read only map\r
+ */\r
+ public Map<R, L> getRightToLeftMap() {\r
+ return imTableRight;\r
+ }\r
+\r
+ public void clear() {\r
+ tableLeft.clear();\r
+ tableRight.clear();\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ int count = 0;\r
+ StringBuilder sb = new StringBuilder();\r
+ sb.append("[");\r
+ for (Entry<L, R> e : tableLeft.entrySet())\r
+ {\r
+ if (count++>0) sb.append(", ");\r
+ sb.append(e.getKey().toString());\r
+ sb.append("=");\r
+ sb.append(e.getValue().toString());\r
+ }\r
+ sb.append("]");\r
+ return sb.toString();\r
+ }\r
+\r
+ @Override\r
+ public LinkedBijectionMap<L, R> clone() {\r
+ return new LinkedBijectionMap<L, R>(this);\r
+ }\r
+}\r