--- /dev/null
+package org.simantics.db.layer0.variable;
+
+/**
+ * Java interface for StructuredProperty SCL value type.
+ *
+ * @author Tuukka Lehtonen
+ * @since 1.36.0
+ */
+public interface StructuredProperty {
+}
\ No newline at end of file
if (!changed)
return;
- at.setTransform(at.getScaleX(), at.getShearX(), at.getShearY(), at.getScaleY(), x, y);
+ at.setTransform(at.getScaleX(), at.getShearY(), at.getShearX(), at.getScaleY(), x, y);
DiagramGraphUtil.setTransform(graph, element, at);
CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
-import org.eclipse.swt.widgets.Widget;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPartSite;
import org.simantics.g2d.canvas.ICanvasContext;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.datastructures.hints.IHintListener;
import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.ui.SWTDPIUtil;
/**
* A participant that initializes an SWT pop-up menu and registers it with the
* @param newValue
* @thread canvas-thread (AWT)
*/
- protected void showPopup(Point2D newValue) {
- final Point2D cp = (Point2D) newValue;
+ protected void showPopup(Point2D cp) {
setHint(DiagramHints.POPUP_MENU_CONTROL_POSITION, cp);
setHint(DiagramHints.POPUP_MENU_CANVAS_POSITION, trUtil.controlToCanvas(cp, null));
- display.asyncExec(new Runnable() {
- @Override
- public void run() {
- if (control == null || control.isDisposed())
- return;
-
- Point p = control.toDisplay((int) cp.getX(), (int) cp.getY());
- menuManager.getMenu().setLocation(p);
- menuManager.getMenu().setVisible(true);
- }
+ display.asyncExec(() -> {
+ if (control == null || control.isDisposed())
+ return;
+ Point p = control.toDisplay( SWTDPIUtil.downscaleSwtToInteger(cp) );
+ menuManager.getMenu().setLocation(p);
+ menuManager.getMenu().setVisible(true);
});
}
import java.awt.geom.Point2D;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
-import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
-import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
-import org.eclipse.e4.ui.model.application.ui.menu.MPopupMenu;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IMenuListener2;
import org.eclipse.jface.action.IMenuManager;
import org.simantics.utils.datastructures.hints.IHintContext.Key;
import org.simantics.utils.datastructures.hints.IHintListener;
import org.simantics.utils.datastructures.hints.IHintObservable;
+import org.simantics.utils.ui.SWTDPIUtil;
/**
* A participant that initializes an SWT pop-up menu and registers it with the
* @param newValue
* @thread canvas-thread (AWT)
*/
- protected void showPopup(Point2D newValue) {
- final Point2D cp = (Point2D) newValue;
+ protected void showPopup(Point2D cp) {
setHint(DiagramHints.POPUP_MENU_CONTROL_POSITION, cp);
setHint(DiagramHints.POPUP_MENU_CANVAS_POSITION, trUtil.controlToCanvas(cp, null));
- display.asyncExec(new Runnable() {
- @Override
- public void run() {
- if (control == null || control.isDisposed())
- return;
- Point p = control.toDisplay((int) cp.getX(), (int) cp.getY());
- menuManager.getMenu().setLocation(p);
- menuManager.getMenu().setVisible(true);
- }
+ display.asyncExec(() -> {
+ if (control == null || control.isDisposed())
+ return;
+ Point p = control.toDisplay( SWTDPIUtil.downscaleSwtToInteger(cp) );
+ menuManager.getMenu().setLocation(p);
+ menuManager.getMenu().setVisible(true);
});
}
categoryId="org.simantics.g2d"
id="org.simantics.gallery.itemfont"
label="Symbol Font"
- value="Tahoma-regular-8">
+ value="Tahoma-regular-12">
<description>
The symbol font is used for labels of symbols in the symbol library view.
</description>
/**
* A Hint for other participants to use for showing the context menu at the
- * contol position specified by the Point2D argument.
+ * control position specified by the Point2D argument.
*/
public static final Key SHOW_POPUP_MENU = new KeyOf(Point2D.class, "SHOW_POPUP_MENU_CMD");
import org.simantics.scenegraph.g2d.events.MouseEvent.MouseMovedEvent;
import org.simantics.scenegraph.g2d.events.MouseEvent.MouseWheelMovedEvent;
import org.simantics.scenegraph.g2d.events.adapter.AbstractEventAdapter;
+import org.simantics.utils.ui.SWTDPIUtil;
public class SWTMouseEventAdapter extends AbstractEventAdapter implements MouseListener, MouseMoveListener, MouseTrackListener, MouseWheelListener {
private Point2D getControlPosition(MouseEvent e)
{
- return new Point2D.Double(e.x, e.y);
+ return new Point2D.Double(SWTDPIUtil.upscaleSwt(e.x), SWTDPIUtil.upscaleSwt(e.y));
}
private Point2D getScreenPosition(MouseEvent e)
{
- Point p = e.display.getCursorLocation();
+ Point p = SWTDPIUtil.upscaleSwt(e.display.getCursorLocation());
return new Point2D.Double(p.x, p.y);
}
import org.simantics.utils.threads.logger.ThreadLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.simantics.utils.ui.SWTDPIUtil;
/**
* @author Toni Kalajainen <toni.kalajainen@vtt.fi>
chassis = new SWTChassis(composite, style) {
@Override
public Point computeSize(int wHint, int hHint, boolean changed) {
-// System.out.println("chassis compute size: " + wHint + ", " + hHint + ", " + changed);
-
if (diagram == null)
return super.computeSize(wHint, hHint, changed);
+ // Note: This code must take into account that FlowLayout expects to
+ // receive pixel coordinates, not SWT API coordinates.
+
Rectangle2D rect;
// if (!changed) {
// rect = ElementUtils.getSurroundingElementBoundsOnDiagram(diagram.getSnapshot());
// }
// else
{
- Double wH = wHint==SWT.DEFAULT ? null : (double) wHint-vMargin-vMargin;
- Double hH = hHint==SWT.DEFAULT ? null : (double) hHint-hMargin-hMargin;
+ Double wH = wHint==SWT.DEFAULT ? null : (double) SWTDPIUtil.upscaleSwt(wHint)-hMargin*2;
+ Double hH = hHint==SWT.DEFAULT ? null : (double) SWTDPIUtil.upscaleSwt(hHint)-vMargin*2;
rect = fl.computeSize(diagram, wH, hH);
+ SWTDPIUtil.downscaleSwt(rect, rect);
}
- return new Point((int)rect.getMaxX()+hMargin*2, (int)rect.getMaxY()+vMargin*2);
+ return new Point((int)rect.getWidth()+hMargin*2, (int)rect.getHeight()+vMargin*2);
}
};
hintCtx.setHint(DiagramHints.KEY_DIAGRAM, diagram);
// Force layout
- ThreadUtils.asyncExec(swtThread, new Runnable() {
- @Override
- public void run() {
- resized(false);
- }
- });
+ ThreadUtils.asyncExec(swtThread, () -> resized(false));
});
chassis.addControlListener(new ControlListener() {
fontRegistry.removeListener(fontRegistryListener);
// Prevent memory leaks.
- ThreadUtils.asyncExec(ctx.getThreadAccess(), new Runnable() {
- @Override
- public void run() {
- chassis.getAWTComponent().setCanvasContext(null);
- ctx.dispose();
- }
+ ThreadUtils.asyncExec(ctx.getThreadAccess(), () -> {
+ chassis.getAWTComponent().setCanvasContext(null);
+ ctx.dispose();
});
}
});
currentItemFont = FontHelper.toAwt(fdn);
itemClass.getSingleItem(GalleryItemSGNode.class).setFont(currentItemFont);
// FIXME: a bug exists in this case. The group size will not be refreshed even though the sizes of the gallery items are recalculated and changed.
- ThreadUtils.asyncExec(swtThread, new Runnable() {
- @Override
- public void run() {
- resized(true);
- }
- });
+ ThreadUtils.asyncExec(swtThread, () -> resized(true));
}
};
//System.out.println(this + ".resized(" + refreshElementSizes + ")");
if (chassis.isDisposed())
return;
- org.eclipse.swt.graphics.Rectangle b = chassis.getBounds();
+ org.eclipse.swt.graphics.Rectangle b = SWTDPIUtil.upscaleSwt(chassis.getBounds());
+ //System.out.println("chassis bounds: " + b);
final Rectangle2D bounds = new Rectangle2D.Double(hMargin, vMargin, b.width-hMargin*2, b.height-vMargin*2);
- ctx.getThreadAccess().asyncExec(new Runnable() {
- @Override
- public void run() {
- if (ctx.isDisposed())
- return;
- if (diagram == null)
- return;
- //System.out.println(this + ".resized(" + refreshElementSizes + ") AWT update");
- if (refreshElementSizes)
- refreshElementSizes();
- fl.layout(diagram, bounds);
-
- // Makes sure RTreeNode is marked dirty and everything is
- // properly repainted.
- if (itemPainter != null)
- itemPainter.updateAll();
- ctx.getContentContext().setDirty();
- }});
+ ctx.getThreadAccess().asyncExec(() -> {
+ if (ctx.isDisposed())
+ return;
+ if (diagram == null)
+ return;
+ //System.out.println(this + ".resized(" + refreshElementSizes + ") AWT update");
+ if (refreshElementSizes)
+ refreshElementSizes();
+ fl.layout(diagram, bounds);
+
+ // Makes sure RTreeNode is marked dirty and everything is
+ // properly repainted.
+ if (itemPainter != null)
+ itemPainter.updateAll();
+ ctx.getContentContext().setDirty();
+ });
}
/**
// wrong thread (SWT) for AWTChassis.
chassis.getAWTComponent().setCanvasContext(canvasContext);
- swtThread.asyncExec(new Runnable() {
- @Override
- public void run() {
- if (!chassis.isDisposed())
- chassis.setCanvasContext(canvasContext);
- }
+ swtThread.asyncExec(() -> {
+ if (!chassis.isDisposed())
+ chassis.setCanvasContext(canvasContext);
});
canvasContext.assertParticipantDependencies();
// 3. Calculate maximum vertical space needed by current diagram element texts
refreshElementSizes();
- ThreadUtils.asyncExec(swtThread, new Runnable() {
- @Override
- public void run() {
- resized(false);
- }
- });
+ ThreadUtils.asyncExec(swtThread, () -> resized(false));
// $AWT-Thread-End$
}
});
// Calculate maximum vertical space needed by current diagram element texts
FontMetrics metrics = awtComponent.getFontMetrics(currentItemFont);
int fontHeight = metrics.getHeight();
- int maxWidth = (int) itemSize.getWidth();
- Rectangle2D size = itemSize;
- java.awt.Point targetSize = new java.awt.Point((int) itemSize.getWidth(), (int) itemSize.getHeight());
+ Rectangle2D size = SWTDPIUtil.upscaleSwt(itemSize);
+ int maxWidth = (int) size.getWidth();
+ java.awt.Point targetSize = new java.awt.Point((int) size.getWidth(), (int) size.getHeight());
diagram.setHint(DiagramHints.KEY_ELEMENT_RASTER_TARGET_SIZE, targetSize);
int maxLinesNeeded = 0;
for (IElement el : diagram.getElements()) {
// for caching rendered images in the correct size only.
// NOTE: currently this is not used in GalleryItemPainter since the
// target size is now propagated through the element class loading
- // process through the diagram hint KEY_ELEMENT_RASTER_REFERENCE_SIZE.
+ // process through the diagram hint KEY_ELEMENT_RASTER_TARGET_SIZE.
el.setHint(GalleryItemSGNode.KEY_TARGET_IMAGE_SIZE, targetSize);
String text = ElementUtils.getText(el);
if (image != i)
continue;
- ctx.getThreadAccess().asyncExec(new Runnable() {
- @Override
- public void run() {
- //System.out.println(Thread.currentThread() + ": update scene graph(" + el + ")");
- // Update scene graph and repaint.
- el.getElementClass().getSingleItem(GalleryItemSGNode.class).update(el);
- ctx.getContentContext().setDirty();
- }
+ ctx.getThreadAccess().asyncExec(() -> {
+ //System.out.println(Thread.currentThread() + ": update scene graph(" + el + ")");
+ // Update scene graph and repaint.
+ el.getElementClass().getSingleItem(GalleryItemSGNode.class).update(el);
+ ctx.getContentContext().setDirty();
});
break;
}
if (ctx.getThreadAccess().currentThreadAccess()) {
ctx.add(p);
} else {
- ctx.getThreadAccess().asyncExec(new Runnable() {
- @Override
- public void run() {
- if (!ctx.isDisposed())
- ctx.add(p);
- }
+ ctx.getThreadAccess().asyncExec(() -> {
+ if (!ctx.isDisposed())
+ ctx.add(p);
});
}
}
if (ctx.getThreadAccess().currentThreadAccess()) {
ctx.add(p);
} else {
- ctx.getThreadAccess().asyncExec(new Runnable() {
- @Override
- public void run() {
- if (!ctx.isDisposed())
- ctx.add(p);
- }
+ ctx.getThreadAccess().asyncExec(() -> {
+ if (!ctx.isDisposed())
+ ctx.add(p);
});
}
}
package org.simantics.g2d.utils;
import java.awt.Font;
-import java.awt.Toolkit;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.ui.PlatformUI;
+import org.simantics.utils.ui.SWTDPIUtil;
public final class FontHelper {
}
public static java.awt.Font toAwt(FontData fd) {
- int resolution = Toolkit.getDefaultToolkit().getScreenResolution();
- int awtFontSize = (int) Math.round((double) fd.getHeight() * resolution / 72.0);
+ int awtFontSize = SWTDPIUtil.upscaleSwt(fd.getHeight());
// The style constants for SWT and AWT map exactly, and since they are int constants, they should
// never change. So, the SWT style is passed through as the AWT style.
Font font = new java.awt.Font(fd.getName(), fd.getStyle(), awtFontSize);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="output" path="bin"/>
+</classpath>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.simantics.jdbc.ontology</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.simantics.graph.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.simantics.graph.nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: http://www.simantics.org/JDBC-1.0
+Bundle-SymbolicName: org.simantics.jdbc.ontology
+Bundle-Version: 1.0.0.qualifier
+Bundle-Activator: org.simantics.jdbc.ontology.Activator
+Require-Bundle: org.eclipse.core.runtime,
+ org.simantics.layer0,
+ org.simantics.selectionview.ontology;bundle-version="1.2.0"
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ActivationPolicy: lazy
+Export-Package: org.simantics.jdbc
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ graph.tg
--- /dev/null
+L0 = <http://www.simantics.org/Layer0-1.1>
+SEL = <http://www.simantics.org/SelectionView-1.2>
+
+JDBC = <http://www.simantics.org/JDBC-1.0> : L0.Ontology
+ @L0.new
+ L0.HasResourceClass "org.simantics.jdbc.JDBCResource"
+
+JDBC.Session <T L0.Entity
+ >-- JDBC.Session.hasValue --> L0.Value <R L0.HasProperty : SEL.GenericParameterType
+
\ No newline at end of file
--- /dev/null
+package org.simantics.jdbc.ontology;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ private static BundleContext context;
+
+ static BundleContext getContext() {
+ return context;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext bundleContext) throws Exception {
+ Activator.context = bundleContext;
+ }
+
+ /*
+ * (non-Javadoc)
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext bundleContext) throws Exception {
+ Activator.context = null;
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<classpath>\r
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>\r
+ <classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>\r
+ <classpathentry kind="src" path="src"/>\r
+ <classpathentry kind="output" path="bin"/>\r
+</classpath>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.simantics.jdbc</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.simantics.graph.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.ManifestBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.pde.SchemaBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.PluginNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.simantics.graph.nature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
--- /dev/null
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Simantics JDBC support
+Bundle-SymbolicName: org.simantics.jdbc
+Bundle-Version: 1.0.0.qualifier
+Bundle-RequiredExecutionEnvironment: JavaSE-1.8
+Bundle-ClassPath: .
+Require-Bundle: org.eclipse.osgi,
+ org.simantics.simulator.toolkit,
+ org.simantics.databoard,
+ gnu.trove3;bundle-version="3.0.3",
+ org.slf4j.api;bundle-version="1.7.25",
+ org.simantics.db.layer0,
+ org.simantics.simulator.toolkit.db,
+ org.simantics,
+ org.simantics.jdbc.ontology,
+ io.netty.buffer;bundle-version="4.1.27",
+ io.netty.codec;bundle-version="4.1.27",
+ io.netty.common;bundle-version="4.1.27",
+ io.netty.handler;bundle-version="4.1.27",
+ io.netty.transport;bundle-version="4.1.27",
+ pgjdbc-ng;bundle-version="0.7.1"
+Export-Package: org.simantics.jdbc,
+ org.simantics.jdbc.variable
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<adapters>
+ <target interface="org.simantics.db.layer0.variable.VariableBuilder">
+ <type uri="http://www.simantics.org/JDBC-1.0/Session" class="org.simantics.jdbc.variable.JDBCVariableBuilder" />
+ </target>
+</adapters>
\ No newline at end of file
--- /dev/null
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .,\
+ adapters.xml,\
+ jdbc.properties
--- /dev/null
+simantics.jdbc.host=127.0.0.1
+simantics.jdbc.port=5432
+simantics.jdbc.user=simantics
+simantics.jdbc.password=simantics
+simantics.jdbc.database=simantics
\ No newline at end of file
--- /dev/null
+package org.simantics.jdbc;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.layer0.Layer0;
+
+/**
+ * Simantics JDBC facade.
+ *
+ * @author Jani Simomaa
+ */
+public class SimanticsJDBC {
+
+ public static final String PROP_SIMANTICS_JDBC_PROPERTYFILE = "simantics.jdbc.propertyfile";
+ public static final String PROP_SIMANTICS_JDBC_HOST = "simantics.jdbc.host";
+ public static final String PROP_SIMANTICS_JDBC_PORT = "simantics.jdbc.port";
+ public static final String PROP_SIMANTICS_JDBC_USER = "simantics.jdbc.user";
+ public static final String PROP_SIMANTICS_JDBC_PASSWORD = "simantics.jdbc.password";
+ public static final String PROP_SIMANTICS_JDBC_DATABASE = "simantics.jdbc.database";
+
+ public static String createJDBCSession(WriteGraph graph, String sessionGUID) throws DatabaseException {
+ Resource projects = graph.getResource("http://Projects");
+ Resource documentSessions = Layer0Utils.getPossibleChild(graph, projects, "DocumentSessions");
+ Layer0 L0 = Layer0.getInstance(graph);
+ Resource documentSession = Layer0Utils.getPossibleChild(graph, documentSessions, sessionGUID);
+
+ String sessionId = "http://Projects/DocumentSessions/" + sessionGUID + "/__jdbc__";
+
+ JDBCResource JDBC = JDBCResource.getInstance(graph);
+ Resource jdbcSession = graph.newResource();
+ graph.claim(jdbcSession, L0.InstanceOf, JDBC.Session);
+ graph.claimLiteral(jdbcSession, L0.HasName, L0.NameOf, L0.String, "__jdbc__", Bindings.STRING);
+ graph.claim(documentSession, L0.ConsistsOf, jdbcSession);
+
+ @SuppressWarnings("unused")
+ Variable jdbcState = Variables.getVariable(graph, jdbcSession);
+
+ return sessionId;
+ }
+}
--- /dev/null
+package org.simantics.jdbc.internal;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator {
+
+ @Override
+ public void start(BundleContext context) throws Exception {
+
+ }
+
+ @Override
+ public void stop(BundleContext context) throws Exception {
+
+ }
+
+}
--- /dev/null
+package org.simantics.jdbc.variable;
+
+import org.simantics.simulator.toolkit.StandardNode;
+
+public class JDBCNode implements StandardNode {
+
+ public String name;
+
+ public JDBCNode(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((name == null) ? 0 : name.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ JDBCNode other = (JDBCNode) obj;
+ if (name == null) {
+ if (other.name != null)
+ return false;
+ } else if (!name.equals(other.name))
+ return false;
+ return true;
+ }
+}
--- /dev/null
+package org.simantics.jdbc.variable;
+
+import java.util.Collections;
+import java.util.Set;
+
+import org.simantics.simulator.toolkit.StandardNodeManager;
+import org.simantics.simulator.toolkit.StandardRealm;
+import org.simantics.simulator.variable.exceptions.NodeManagerException;
+
+public class JDBCNodeManager extends StandardNodeManager<JDBCNode, JDBCNodeManagerSupport> {
+
+ public JDBCNodeManager(StandardRealm<JDBCNode, JDBCNodeManagerSupport> realm, JDBCNode root) {
+ super(realm, root);
+ }
+
+ @Override
+ public Set<String> getClassifications(JDBCNode node) throws NodeManagerException {
+ return Collections.emptySet();
+ }
+
+}
--- /dev/null
+package org.simantics.jdbc.variable;
+
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.simulator.toolkit.StandardNodeManagerSupport;
+import org.simantics.simulator.variable.exceptions.NodeManagerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.impossibl.postgres.api.jdbc.PGConnection;
+import com.impossibl.postgres.jdbc.PGDataSource;
+
+public class JDBCNodeManagerSupport implements StandardNodeManagerSupport<JDBCNode> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JDBCNodeManagerSupport.class);
+ @SuppressWarnings("unused")
+ private String id; // this might have some use later in the future?
+ private PGDataSource dataSource;
+ private String channelName;
+
+ public JDBCNodeManagerSupport(String id, PGDataSource dataSource, String channelName) {
+ this.id = id;
+ this.dataSource = dataSource;
+ this.channelName = channelName;
+ }
+
+ @Override
+ public Object getEngineValue(JDBCNode node) throws NodeManagerException {
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("Getting value for {}", node.getName());
+
+ try (PGConnection connection = (PGConnection) dataSource.getConnection()) {
+ // do get value
+ PreparedStatement ps = connection.prepareStatement("SELECT value->'value' FROM simantics_table WHERE key IN ('" + node.getName() + "');");
+ ResultSet rs = ps.executeQuery();
+ if (!rs.next()) {
+ if (LOGGER.isDebugEnabled()) {
+ LOGGER.debug("no value for query {}", ps.toString());
+ }
+ return null;
+ }
+ return rs.getObject(1);
+ } catch (Exception e) {
+ LOGGER.error("Failed to get value for {}", node.getName(), e);
+ throw new NodeManagerException("Failed to get value for " + node.getName(), e);
+ }
+ }
+
+ @Override
+ public Binding getEngineBinding(JDBCNode node) throws NodeManagerException {
+ return Bindings.OBJECT;
+ }
+
+ @Override
+ public void setEngineValue(JDBCNode node, Object value) throws NodeManagerException {
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("Setting value for {} to {}", node.getName(), value);
+
+ setValueImpl(node.getName(), value);
+ }
+
+ private void setValueImpl(String name, Object value) throws NodeManagerException {
+ try (PGConnection connection = (PGConnection) dataSource.getConnection()) {
+ // do set value
+ PreparedStatement statement = connection.prepareStatement("INSERT INTO simantics_table VALUES (?, ?::JSON) ON CONFLICT (key) DO UPDATE SET value= ?::JSON");
+ statement.setString(1, name);
+ statement.setObject(2, "{\"value\": " + value.toString() + "}");
+ statement.setObject(3, "{\"value\": " + value.toString() + "}");
+ statement.executeUpdate();
+
+ // notify others (including ourselves)
+ doNotify(connection, name);
+ } catch (Exception e) {
+ LOGGER.error("Failed to set value for {} to {}", name, value, e);
+ throw new NodeManagerException("Failed to set value for " + name + " to " + String.valueOf(value), e);
+ }
+ }
+
+ private void doNotify(PGConnection connection, String name) throws SQLException {
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("Notifying change {} to channel {}", name, this.channelName);
+ Statement statement = connection.createStatement();
+ String sql = "NOTIFY " + this.channelName + ", '" + name + "'";
+ statement.execute(sql);
+ statement.close();
+ }
+
+ @Override
+ public String getName(JDBCNode node) {
+ return node.getName();
+ }
+
+ @Override
+ public Map<String, JDBCNode> getChildren(JDBCNode node) {
+ return Collections.emptyMap();
+ }
+
+ @Override
+ public Map<String, JDBCNode> getProperties(JDBCNode node) {
+ HashMap<String, JDBCNode> properties = new HashMap<>();
+ try (PGConnection connection = (PGConnection) dataSource.getConnection()) {
+ Statement st = connection.createStatement();
+ ResultSet executeQuery = st.executeQuery("SELECT key FROM simantics_table");
+ while (executeQuery.next()) {
+ String key = executeQuery.getString(1);
+ properties.put(key, new JDBCNode(key));
+ }
+ } catch (Exception e) {
+ LOGGER.error("Could not read properties", e);
+ }
+
+ return properties;
+ }
+
+}
--- /dev/null
+package org.simantics.jdbc.variable;
+
+import org.simantics.simulator.toolkit.StandardNodeManager;
+import org.simantics.simulator.toolkit.StandardRealm;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class JDBCRealm extends StandardRealm<JDBCNode, JDBCNodeManagerSupport> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JDBCRealm.class);
+
+ protected JDBCRealm(JDBCNodeManagerSupport engine, String id) {
+ super(engine, id);
+ }
+
+ @Override
+ protected StandardNodeManager<JDBCNode, JDBCNodeManagerSupport> createManager() {
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("Creating {} for realm with id {}", JDBCNodeManager.class.getSimpleName(), getId());
+ return new JDBCNodeManager(this, new JDBCNode("ROOT"));
+ }
+
+ @Override
+ public Logger getLogger() {
+ return LOGGER;
+ }
+
+}
--- /dev/null
+package org.simantics.jdbc.variable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.nio.file.Paths;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Properties;
+import java.util.function.Function;
+
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.NodeSupport;
+import org.simantics.jdbc.SimanticsJDBC;
+import org.simantics.simulator.toolkit.StandardRealm;
+import org.simantics.simulator.toolkit.db.StandardSessionManager;
+import org.simantics.simulator.variable.exceptions.NodeManagerException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.impossibl.postgres.api.jdbc.PGConnection;
+import com.impossibl.postgres.api.jdbc.PGNotificationListener;
+import com.impossibl.postgres.jdbc.PGDataSource;
+
+public class JDBCSessionManager extends StandardSessionManager<JDBCNode, JDBCNodeManagerSupport> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(JDBCSessionManager.class);
+ private static JDBCSessionManager INSTANCE = new JDBCSessionManager();
+
+ private static final String VALUE_SIMANTICS_JDBC_HOST = "localhost";
+ private static final int VALUE_SIMANTICS_JDBC_PORT = 5432;
+ private static final String VALUE_SIMANTICS_JDBC_USER = "simantics";
+ private static final String VALUE_SIMANTICS_JDBC_PASSWORD = "simantics";
+ private static final String VALUE_SIMANTICS_JDBC_DATABASE = "simantics";
+
+ private String channelName;
+ private PGNotificationListener listener;
+
+ private PGDataSource dataSource;
+ private Connection connection;
+
+ private static Properties readProperties(InputStream s) throws IOException {
+ try (InputStream is = s) {
+ Properties props = new Properties();
+ props.load(is);
+ return props;
+ }
+ }
+
+ private static Properties safeReadProperties(URL url) {
+ try {
+ return readProperties(url.openStream());
+ } catch (IOException e) {
+ LOGGER.error("Could not read props from " + url, e);
+ return null;
+ }
+ }
+
+ private static Properties safeReadProperties(URI uri) {
+ try {
+ return safeReadProperties(uri.toURL());
+ } catch (MalformedURLException e) {
+ LOGGER.error("Could not read props from " + uri, e);
+ return null;
+ }
+ }
+
+ private static Properties safeReadProperties(String path) {
+ return safeReadProperties(Paths.get(path).toUri());
+ }
+
+ private static Properties readProperties() {
+ String propFile = System.getProperty(SimanticsJDBC.PROP_SIMANTICS_JDBC_PROPERTYFILE, null);
+ if (propFile != null) {
+ Properties p = safeReadProperties(propFile);
+ if (p != null)
+ return p;
+ }
+ // Read default settings from built-in file and override them with values in System properties
+ Properties p = safeReadProperties(JDBCSessionManager.class.getClassLoader().getResource("jdbc.properties"));
+ if (p != null) {
+ p.putAll(System.getProperties());
+ } else {
+ p = System.getProperties();
+ }
+ return p;
+ }
+
+ public JDBCSessionManager() {
+ this.channelName = "test";
+
+ Properties props = readProperties();
+ String host = props.getProperty(SimanticsJDBC.PROP_SIMANTICS_JDBC_HOST, VALUE_SIMANTICS_JDBC_HOST);
+ String port = props.getProperty(SimanticsJDBC.PROP_SIMANTICS_JDBC_PORT, "" + VALUE_SIMANTICS_JDBC_PORT);
+ String database = props.getProperty(SimanticsJDBC.PROP_SIMANTICS_JDBC_DATABASE, VALUE_SIMANTICS_JDBC_DATABASE);
+ String user = props.getProperty(SimanticsJDBC.PROP_SIMANTICS_JDBC_USER, VALUE_SIMANTICS_JDBC_USER);
+ String password = props.getProperty(SimanticsJDBC.PROP_SIMANTICS_JDBC_PASSWORD, VALUE_SIMANTICS_JDBC_PASSWORD);
+
+ try {
+ int portNumber = Integer.valueOf(port);
+
+ dataSource = new PGDataSource();
+ dataSource.setHost(host);
+ dataSource.setPort(portNumber);
+ dataSource.setDatabase(database);
+ dataSource.setUser(user);
+ dataSource.setPassword(password);
+
+ this.connection = dataSource.getConnection();
+ this.listener = new PGNotificationListener() {
+ @Override
+ public void notification(int processId, String channelName, String payload) {
+ if (LOGGER.isDebugEnabled())
+ LOGGER.debug("Received notification from processId={} channelName={} and payload={}", processId, channelName, payload);
+ Simantics.getSession().asyncRequest(new ReadRequest() {
+ @Override
+ public void run(ReadGraph graph) throws DatabaseException {
+ for (String realmId : INSTANCE.getRealms()) {
+ try {
+ JDBCRealm jdbcRealm = (JDBCRealm) INSTANCE.getOrCreateRealm(graph, realmId);
+ jdbcRealm.getNodeManager().refreshVariable(new JDBCNode(payload));
+ } catch (DatabaseException e) {
+ LOGGER.error("Could not refresh variable in realm {} with payload {}", realmId, payload, e);
+ }
+ }
+ }
+ });
+ }
+ };
+ createTable();
+ init();
+ } catch (SQLException e) {
+ LOGGER.error("Could not initialize JDBCSessionManager!", e);
+ }
+ }
+
+ private void createTable() throws SQLException {
+ Statement statement = connection.createStatement();
+ statement.execute("CREATE TABLE IF NOT EXISTS simantics_table (key VARCHAR UNIQUE, value JSON)");
+ statement.close();
+ }
+
+ protected void init() throws SQLException {
+ Statement statement = connection.createStatement();
+ statement.execute("LISTEN " + this.channelName);
+ statement.close();
+ ((PGConnection) connection).addNotificationListener(this.listener);
+ }
+
+ protected void destroy() throws SQLException {
+ try (PGConnection connection = (PGConnection) dataSource.getConnection()) {
+ Statement statement = connection.createStatement();
+ statement.execute("UNLISTEN " + this.channelName);
+ statement.close();
+ }
+ }
+
+
+ @Override
+ protected JDBCNodeManagerSupport createEngine(ReadGraph graph, String id) throws DatabaseException {
+ return new JDBCNodeManagerSupport(id, this.dataSource, this.channelName);
+ }
+
+ @Override
+ protected StandardRealm<JDBCNode, JDBCNodeManagerSupport> createRealm(JDBCNodeManagerSupport engine, String id) {
+ return new JDBCRealm(engine, id);
+ }
+
+ public static void setValue(ReadGraph graph, String id, String key, Object value) throws DatabaseException, NodeManagerException, BindingException, InterruptedException {
+ JDBCRealm realm = (JDBCRealm) INSTANCE.getOrCreateRealm(graph, id);
+ realm.asyncExec(() -> {
+ try {
+ realm.getNodeManager().setValue(new JDBCNode(key), key, value, Bindings.OBJECT);
+ } catch (NodeManagerException | BindingException e) {
+ LOGGER.error("Could not set value {} for {}", value, key, e);
+ }
+ });
+ }
+
+ public static NodeSupport<?> nodeSupport(ReadGraph graph, String sessionName) throws DatabaseException {
+ return INSTANCE.getOrCreateNodeSupport(graph, sessionName);
+ }
+
+ public static Object getValue(ReadGraph graph, String uri, String key) throws InterruptedException, DatabaseException {
+ JDBCRealm realm = (JDBCRealm) INSTANCE.getOrCreateRealm(graph, uri);
+ return realm.syncExec(new Function<Object, Object>() {
+
+ @Override
+ public Object apply(Object t) {
+ try {
+ return realm.getNodeManager().getValue(new JDBCNode(key), key).getValue();
+ } catch (NodeManagerException e) {
+ LOGGER.error("Could not get value for {}", key, e);
+ return null;
+ }
+ }
+ });
+ }
+
+}
--- /dev/null
+package org.simantics.jdbc.variable;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.variable.NodeManagerVariableBuilder;
+import org.simantics.db.layer0.variable.NodeSupport;
+
+public class JDBCVariableBuilder extends NodeManagerVariableBuilder {
+
+ @Override
+ protected NodeSupport<?> getNodeSupport(ReadGraph graph, String sessionName) throws DatabaseException {
+ return JDBCSessionManager.nodeSupport(graph, sessionName);
+ }
+
+ @Override
+ protected Object getRoot(ReadGraph graph, NodeSupport<?> support, String sessionName) throws DatabaseException {
+ JDBCNodeManager manager = (JDBCNodeManager) support.manager;
+ return manager.getRoot();
+ }
+
+}
>-- L0.identifier <R L0.HasProperty : L0.FunctionalRelation
L0.HasLabel "Identifier"
--> L0.GUID
+ ==> "GUID"
>-- L0.typeURI <R L0.HasProperty : L0.FunctionalRelation
L0.HasLabel "Type URI"
--> L0.String
@L0.assert L0.Entity.methods
_ : L0.Value
-L0.Entity.methods --> L0.Value <R L0.HasProperty : L0.FunctionalRelation
+L0.Entity.methods ==> "StructuredProperty" <R L0.HasProperty : L0.FunctionalRelation
L0.domainProperties L0.Functions.methodsPropertyDomainProperties
L0.Entity.method <R L0.HasProperty : L0.FunctionalRelation
L0.Literal.DoubleValidator <T L0.Value
L0.GUID <T L0.Literal
- @L0.assert L0.HasValueType "(Long,Long)"
+ @L0.assert L0.HasValueType "GUID"
@L0.assert L0.HasDataType ${ mostSigBits : Long, leastSigBits : Long }
L0.TypeWithIdentifier <T L0.Entity
// always clean up old items before drawing new items
cleanupStyleForNode(_node);
- int count = resultList.size();
- if (resultList == null || count < 2)
+ int count = resultList != null ? resultList.size() : 0;
+ if (count < 2)
return;
G2DParentNode parentNode = ProfileVariables.claimChild(_node, "", PARENT_NODE_NAME_PREFIX, G2DParentNode.class, observer);
* @param selectedObjects
* @throws DatabaseException
*/
- public static boolean openEditor(ReadGraph g, Resource r, final String editorId, final Collection<Object> selectedObjects) throws DatabaseException {
-
- final Resource diagram = getDiagram(g, r, selectedObjects);
- if (diagram == null)
- return false;
-
- final Resource configurationComposite = ComponentUtils.getPossibleDiagramComposite(g, diagram);
- if (configurationComposite == null)
- return false;
-
- Pair<Resource, RVI> modelAndRVI = getModelAndRVI(g, configurationComposite);
+ public static boolean openEditor(ReadGraph g, Resource r, String editorId, Collection<Object> selectedObjects) throws DatabaseException {
+ Resource diagram = getDiagram(g, r, selectedObjects);
+ Resource configurationComposite = diagram != null ? ComponentUtils.getPossibleDiagramComposite(g, diagram) : null;
+ Pair<Resource, RVI> modelAndRVI = configurationComposite != null ? getModelAndRVI(g, configurationComposite) : null;
//System.out.println("modelAndRVI: " + modelAndRVI);
if (modelAndRVI == null)
return false;
+ scheduleOpenEditor(editorId, diagram, modelAndRVI.first, modelAndRVI.second, selectedObjects);
+ return true;
+ }
+
+ /**
+ * @param g
+ * @param configurationComposite
+ * @param editorId
+ * @param selectedObjects
+ * @throws DatabaseException
+ */
+ public static boolean openEditor(ReadGraph g, Resource r, String editorId, Collection<Object> selectedObjects, Resource model, RVI rvi) throws DatabaseException {
+ Resource diagram = getDiagram(g, r, selectedObjects);
+ if (diagram == null)
+ return false;
+ scheduleOpenEditor(editorId, diagram, model, rvi, selectedObjects);
+ return true;
+ }
- final Runnable editorActivator = NavigateToTarget.editorActivator(editorId, diagram, modelAndRVI.first, modelAndRVI.second, part -> {
+ /**
+ * @param g
+ * @param configurationComposite
+ * @param editorId
+ * @param selectedObjects
+ * @throws DatabaseException
+ */
+ private static void scheduleOpenEditor(String editorId, Resource diagram, Resource model, RVI rvi, Collection<Object> selectedObjects) throws DatabaseException {
+ Runnable editorActivator = NavigateToTarget.editorActivator(editorId, diagram, model, rvi, part -> {
if (selectedObjects.isEmpty())
return;
-
- final ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class);
+ ICanvasContext openedCanvas = (ICanvasContext) part.getAdapter(ICanvasContext.class);
assert openedCanvas != null;
// CanvasContext-wide denial of initial zoom-to-fit on diagram open.
openedCanvas.getDefaultHintContext().setHint(DiagramHints.KEY_INITIAL_ZOOM_TO_FIT, Boolean.FALSE);
- //System.out.println("ASDF: " + element);
ThreadUtils.asyncExec(openedCanvas.getThreadAccess(),
NavigateToTarget.elementSelectorZoomer(openedCanvas, selectedObjects, false));
});
-
- PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
- @Override
- public void run() {
- editorActivator.run();
- }
- });
-
- return true;
+ PlatformUI.getWorkbench().getDisplay().asyncExec(editorActivator);
}
}
TYPE_MAP.put("ByteArray", Types.BYTE_ARRAY);
add((TCon)Types.RESOURCE);
+ add(Types.con("Simantics/GUID", "GUID")); // L0.GUID
+ add(Types.con("Simantics/Variables", "StructuredProperty")); // L0.methods
+ add(Types.con("Simantics/Variables", "ValueAccessor")); // L0.ValueAccessor
add(Types.con("Simantics/Variables", "VariableMap"));
}
private boolean isSynchronizedConnector(ReadGraph graph, Resource templateConnection, Resource instanceConnector) throws DatabaseException {
DiagramResource DIA = DiagramResource.getInstance(graph);
Resource instanceConnection = graph.getPossibleObject(instanceConnector, DIA.IsConnectorOf);
+ if (instanceConnection == null)
+ return false;
return graph.hasStatement(instanceConnection, MOD.HasElementSource, templateConnection)
// If the master connection has been removed, this is all that's left
// to identify a connection that at least was originally synchronized
--- /dev/null
+package org.simantics.scl.compiler.common.names;
+
+import java.io.StringReader;
+
+import org.simantics.scl.compiler.internal.parsing.Token;
+import org.simantics.scl.compiler.internal.parsing.parser.SCLLexer;
+import org.simantics.scl.compiler.internal.parsing.parser.SCLTerminals;
+
+import gnu.trove.set.hash.THashSet;
+
+public class SCLReservedWords {
+ public static final String[] RESERVED_WORDS_ARRAY = {
+ "as",
+ "by",
+ "do",
+ "if",
+ "in",
+ "edo",
+ "let",
+ "mdo",
+ "data",
+ "else",
+ "rule",
+ "then",
+ "type",
+ "when",
+ "with",
+ "class",
+ "infix",
+ "match",
+ "where",
+ "effect",
+ "forall",
+ "hiding",
+ "import",
+ "infixl",
+ "infixr",
+ "select",
+ "enforce",
+ "include",
+ "ruleset",
+ "deriving",
+ "instance",
+ "constraint",
+ "importJava",
+ "transformation",
+ };
+
+ public static final THashSet<String> RESERVED_WORDS_SET = new THashSet<>();
+
+ static {
+ for(String word : RESERVED_WORDS_ARRAY)
+ RESERVED_WORDS_SET.add(word);
+ }
+
+ public static boolean isReserved(String str) {
+ try {
+ SCLLexer lexer = new SCLLexer(new StringReader(str));
+ Token token = lexer.nextToken();
+ return token.id != SCLTerminals.ID;
+ } catch(Exception e) {
+ return true;
+ }
+ }
+}
importJava "org.simantics.db.layer0.variable.VariableMap" where
data VariableMap
+importJava "org.simantics.db.layer0.variable.StructuredProperty" where
+ data StructuredProperty
+
importJava "org.simantics.db.layer0.variable.ResourceCollectionVariableMap" where
@JavaName "<init>"
createVariableMap :: [Resource] -> VariableMap
final IExperimentActivationListener listener,
final Function2<WriteGraph, Resource, Object> externalWrite,
final Consumer<Resource> successCallback)
+ {
+ createRun(session, vg,
+ experimentResource, experiment, experimentRunTypeURI,
+ listener, externalWrite, successCallback, true);
+ }
+
+ /**
+ * Create new experiment run in a selected virtual graph.
+ *
+ * @param session
+ * @param vg
+ * @param experimentResource
+ * @param experiment
+ * @param experimentRunTypeURI
+ * @param listener
+ * @param successCallback if non-null invoked with the created run resource
+ * as an argument, just before invoking
+ * listener.onExperimentActivated(experiment)
+ * @param attachDeactivationListener <code>true</code> to run for the created run-resource
+ * {@link #attachStateListener(Session, IExperiment, Resource)}
+ */
+ public static void createRun(
+ Session session,
+ VirtualGraph vg,
+ Resource experimentResource,
+ IExperiment experiment,
+ String experimentRunTypeURI,
+ IExperimentActivationListener listener,
+ Function2<WriteGraph, Resource, Object> externalWrite,
+ Consumer<Resource> successCallback,
+ boolean attachDeactivationListener)
{
final AtomicReference<Resource> run = new AtomicReference<>();
session.asyncRequest(new WriteRequest(vg) {
else
ErrorLogger.defaultLogError(e);
} else {
- attachStateListener(session, experiment, run.get());
+ if (attachDeactivationListener)
+ attachStateListener(session, experiment, run.get());
if (successCallback != null)
successCallback.accept(run.get());
if (listener != null)
StructuralResource2 STR = StructuralResource2.getInstance(graph);
Resource type = graph.getPossibleType(component, STR.Component);
- return graph.syncRequest(new IsLeafType(type));
+ return type != null ? graph.syncRequest(new IsLeafType(type)) : false;
}
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
+import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.PartInitException;
+import org.eclipse.ui.internal.PartSite;
+import org.eclipse.ui.internal.e4.compatibility.CompatibilityEditor;
import org.eclipse.ui.part.EditorPart;
import org.simantics.Simantics;
import org.simantics.db.Resource;
* @param partName
*/
protected void safeSetPartName(String partName) {
- if (!disposed) {
+ if (!disposed && checkCompatibilityPartNotBeingDisposed()) { // this is to fix bug https://gitlab.simantics.org/simantics/platform/issues/117
setPartName(partName);
}
}
+ @SuppressWarnings("restriction")
+ private boolean checkCompatibilityPartNotBeingDisposed() {
+ IWorkbenchPartSite site = getSite();
+ if (site instanceof PartSite) {
+ PartSite partSite = (PartSite) getSite();
+ Object object = partSite.getModel().getObject();
+ if (object instanceof CompatibilityEditor) {
+ CompatibilityEditor editor = (CompatibilityEditor) object;
+ return !editor.isBeingDisposed();
+ }
+ }
+ return true;
+ }
+
/**
* Safely sets title tooltip for parts whose IEditorInput is not yet disposed (e.g.
* removed from database)
--- /dev/null
+package org.simantics.utils.ui;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.internal.DPIUtil;
+
+/**
+ * This class is needed to support {@link SWTAWTComponent} and HiDPI screens
+ * with different display zoom settings.
+ *
+ * <p>
+ * See {@link DPIUtil} for explanations on what downscaling and upscaling are in
+ * this context. If user has zoom > 100% in use in the system display settings,
+ * SWT's API coordinates will be "downscaled" from actual internal HiDPI
+ * coordinates (pixels).
+ *
+ * <p>
+ * This class contains methods to work around problems with e.g. opening context
+ * menu's in the correct location when using {@link SWTAWTComponent}. AWT always
+ * returns HiDPI pixel coordinates which need to be converted to SWT API
+ * coordinates before giving them to any SWT APIs.
+ *
+ * @author Tuukka Lehtonen
+ * @since 1.36.0
+ */
+@SuppressWarnings("restriction")
+public class SWTDPIUtil {
+
+ private static boolean initialized = false;
+ private static int swtZoom;
+ private static boolean hasSwtScale;
+
+ private static float fromSwtInternalScalingFactorF;
+ private static double fromSwtInternalScalingFactorD;
+ private static float toSwtInternalScalingFactorF;
+ private static double toSwtInternalScalingFactorD;
+
+ private static void initialize() {
+ if (initialized)
+ return;
+
+ swtZoom = DPIUtil.autoScaleUp(100);
+ hasSwtScale = swtZoom != 100;
+
+ fromSwtInternalScalingFactorD = 100.0 / (double) swtZoom;
+ toSwtInternalScalingFactorD = (double) swtZoom / 100.0;
+ fromSwtInternalScalingFactorF = (float) fromSwtInternalScalingFactorD;
+ toSwtInternalScalingFactorF = (float) toSwtInternalScalingFactorD;
+
+// System.out.format("SWTDPIUtil:%n\tswt zoom = %d%n\tfrom swt internal scaling factor = %f%n\tto swt internal scaling factor = %f%n",
+// swtZoom,
+// fromSwtInternalScalingFactorD,
+// toSwtInternalScalingFactorD,
+// );
+
+ initialized = true;
+ }
+
+ // Internals
+
+ private static Rectangle scale(float s, Rectangle r, Rectangle target) {
+ if (s == 1.0f) {
+ if (r == target)
+ return r;
+ if (target == null) {
+ return new Rectangle(r.x, r.y, r.width, r.height);
+ } else {
+ target.x = r.x;
+ target.y = r.y;
+ target.width = r.width;
+ target.height = r.height;
+ return target;
+ }
+ }
+ if (target == null) {
+ return new Rectangle(
+ Math.round(r.x*s),
+ Math.round(r.y*s),
+ Math.round(r.width*s),
+ Math.round(r.height*s));
+ } else {
+ target.x = Math.round(r.x*s);
+ target.y = Math.round(r.y*s);
+ target.width = Math.round(r.width*s);
+ target.height = Math.round(r.height*s);
+ return target;
+ }
+ }
+
+ private static Rectangle2D scale(double s, Rectangle2D r, Rectangle2D target) {
+ if (s == 1.0) {
+ if (r == target)
+ return r;
+ if (target == null)
+ return (Rectangle2D) r.clone();
+ target.setFrame(r);
+ return target;
+ }
+ if (target == null)
+ target = (Rectangle2D) r.clone();
+ target.setFrame(r.getX()*s, r.getY()*s, r.getWidth()*s, r.getHeight()*s);
+ return target;
+ }
+
+ private static double downscaleSwt0(double x) {
+ return hasSwtScale ? x * fromSwtInternalScalingFactorD : x;
+ }
+
+ private static int downscaleToIntegerSwt0(double x) {
+ return (int)(hasSwtScale ? Math.round((double) x * fromSwtInternalScalingFactorD) : x);
+ }
+
+ private static int downscaleSwt0(int x) {
+ return hasSwtScale ? (int) Math.round((double) x * fromSwtInternalScalingFactorD) : x;
+ }
+
+ private static double upscaleSwt0(double x) {
+ return hasSwtScale ? x * toSwtInternalScalingFactorD : x;
+ }
+
+ private static int upscaleToIntegerSwt0(double x) {
+ return (int)(hasSwtScale ? Math.round((double) x * toSwtInternalScalingFactorD) : x);
+ }
+
+ private static int upscaleSwt0(int x) {
+ return hasSwtScale ? (int) Math.round((double) x * toSwtInternalScalingFactorD) : x;
+ }
+
+ // SWT API Coordinates <-> pixels
+
+ // Downscaling
+
+ public static double downscaleSwt(double x) {
+ initialize();
+ return downscaleSwt0(x);
+ }
+
+ public static int downscaleSwt(int x) {
+ initialize();
+ return downscaleSwt0(x);
+ }
+
+ public static Point2D downscaleSwt(double x, double y) {
+ initialize();
+ if (!hasSwtScale)
+ return new Point2D.Double(x, y);
+ double s = fromSwtInternalScalingFactorD;
+ return new Point2D.Double(x * s, y * s);
+ }
+
+ public static Point downscaleSwt(int x, int y) {
+ initialize();
+ return new Point(downscaleSwt0(x), downscaleSwt0(y));
+ }
+
+ public static Point2D downscaleSwt(Point2D p) {
+ return downscaleSwt(p.getX(), p.getY());
+ }
+
+ public static Point downscaleSwtToInteger(Point2D p) {
+ initialize();
+ return new Point(downscaleToIntegerSwt0(p.getX()), downscaleToIntegerSwt0(p.getY()));
+ }
+
+ public static Rectangle2D downscaleSwt(Rectangle2D r, Rectangle2D target) {
+ initialize();
+ return scale(fromSwtInternalScalingFactorD, r, target);
+ }
+
+ public static Rectangle2D downscaleSwt(Rectangle2D r) {
+ return downscaleSwt(r, null);
+ }
+
+ public static Rectangle downscaleSwt(Rectangle r, Rectangle target) {
+ initialize();
+ return scale(fromSwtInternalScalingFactorF, r, target);
+ }
+
+ public static Rectangle downscaleSwt(Rectangle r) {
+ return downscaleSwt(r, null);
+ }
+
+ public static Rectangle downscaleSwtToInteger(Rectangle2D r) {
+ initialize();
+ return new Rectangle(
+ downscaleToIntegerSwt0(r.getMinX()),
+ downscaleToIntegerSwt0(r.getMinY()),
+ downscaleToIntegerSwt0(r.getWidth()),
+ downscaleToIntegerSwt0(r.getHeight()));
+ }
+
+ // Upscaling
+
+ public static double upscaleSwt(double x) {
+ initialize();
+ return upscaleSwt0(x);
+ }
+
+ public static int upscaleSwt(int x) {
+ initialize();
+ return upscaleSwt0(x);
+ }
+
+ public static Point2D upscaleSwt(double x, double y) {
+ initialize();
+ if (!hasSwtScale)
+ return new Point2D.Double(x, y);
+ double s = toSwtInternalScalingFactorD;
+ return new Point2D.Double(x * s, y * s);
+ }
+
+ public static Point upscaleSwt(int x, int y) {
+ initialize();
+ return new Point(upscaleSwt0(x), upscaleSwt0(y));
+ }
+
+ public static Point2D upscaleSwt(Point2D p) {
+ initialize();
+ return (hasSwtScale && p != null) ? upscaleSwt(p.getX(), p.getY()) : p;
+ }
+
+ public static Point upscaleSwtToInteger(Point2D p) {
+ initialize();
+ return new Point(upscaleToIntegerSwt0(p.getX()), upscaleToIntegerSwt0(p.getY()));
+ }
+
+ public static Point upscaleSwt(Point p) {
+ initialize();
+ return (hasSwtScale && p != null) ? upscaleSwt(p.x, p.y) : p;
+ }
+
+ public static Rectangle2D upscaleSwt(Rectangle2D r, Rectangle2D target) {
+ initialize();
+ return scale(toSwtInternalScalingFactorD, r, target);
+ }
+
+ public static Rectangle upscaleSwt(Rectangle r, Rectangle target) {
+ initialize();
+ return scale(toSwtInternalScalingFactorF, r, target);
+ }
+
+ public static Rectangle2D upscaleSwt(Rectangle2D r) {
+ return upscaleSwt(r, null);
+ }
+
+ public static Rectangle upscaleSwt(Rectangle r) {
+ return upscaleSwt(r, null);
+ }
+
+ public static Rectangle upscaleSwtToInteger(Rectangle2D r) {
+ return new Rectangle(
+ upscaleToIntegerSwt0(r.getMinX()),
+ upscaleToIntegerSwt0(r.getMinY()),
+ upscaleToIntegerSwt0(r.getWidth()),
+ upscaleToIntegerSwt0(r.getHeight()));
+ }
+
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.simantics.jdbc.feature</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.pde.FeatureBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.pde.FeatureNature</nature>
+ </natures>
+</projectDescription>
--- /dev/null
+bin.includes = feature.xml
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+ id="org.simantics.jdbc.feature"
+ label="Simantics JDBC Feature"
+ version="1.0.0.qualifier">
+
+ <description url="http://www.example.com/description">
+ [Enter Feature Description here.]
+ </description>
+
+ <copyright url="http://www.example.com/copyright">
+ [Enter Copyright Description here.]
+ </copyright>
+
+ <license url="http://www.example.com/license">
+ [Enter License Description here.]
+ </license>
+
+ <plugin
+ id="org.simantics.jdbc"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.simantics.simulator.toolkit"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.simantics.simulator.toolkit.db"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.simantics.simulator"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.simantics.jdbc.ontology"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+ <plugin
+ id="org.simantics.jdbc.simupedia.sharedlibrary"
+ download-size="0"
+ install-size="0"
+ version="0.0.0"
+ unpack="false"/>
+
+</feature>
<Import-Package>!sun.misc.*,*;resolution:=optional</Import-Package>
</instructions>
</artifact>
+ <artifact>
+ <id>com.impossibl.pgjdbc-ng:pgjdbc-ng:0.7.1</id>
+ <source>true</source>
+ <transitive>false</transitive>
+ </artifact>
</artifacts>
</configuration>
</execution>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
-<target name="Eclipse Oxygen" sequenceNumber="1536132639">
+<target name="Eclipse Oxygen" sequenceNumber="1536132640">
<locations>
<location includeMode="slicer" includeAllPlatforms="true" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
<unit id="com.google.guava" version="21.0.0.v20170206-1425"/>
<unit id="org.slf4j.api.source" version="1.7.25.b001"/>
<unit id="org.supercsv" version="2.4.0"/>
<unit id="org.supercsv.source" version="2.4.0"/>
+ <unit id="pgjdbc-ng" version="0.7.1"/>
+ <unit id="pgjdbc-ng.source" version="0.7.1"/>
<unit id="stax2-api" version="3.1.4"/>
<unit id="stax2-api.source" version="3.1.4"/>
<repository location="http://www.simantics.org/download/master/external-components/maven"/>
org.slf4j.api.source
org.supercsv
org.supercsv.source
+ pgjdbc-ng
+ pgjdbc-ng.source
stax2-api
stax2-api.source
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde?>
<!-- generated with https://github.com/mbarbero/fr.obeo.releng.targetplatform -->
-<target name="Simantics 1.36.0" sequenceNumber="1535957308">
+<target name="Simantics 1.36.0" sequenceNumber="1535957309">
<locations>
<location includeMode="slicer" includeAllPlatforms="true" includeSource="true" includeConfigurePhase="false" type="InstallableUnit">
<unit id="com.google.guava" version="21.0.0.v20170206-1425"/>
<unit id="org.slf4j.api.source" version="1.7.25.b001"/>
<unit id="org.supercsv" version="2.4.0"/>
<unit id="org.supercsv.source" version="2.4.0"/>
+ <unit id="pgjdbc-ng" version="0.7.1"/>
+ <unit id="pgjdbc-ng.source" version="0.7.1"/>
<unit id="stax2-api" version="3.1.4"/>
<unit id="stax2-api.source" version="3.1.4"/>
<repository location="http://www.simantics.org/download/master/external-components/maven"/>