From: Tuukka Lehtonen Date: Tue, 20 Oct 2020 21:41:34 +0000 (+0300) Subject: Merge branch 'bug-623' into release/1.43.0.1 X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=commitdiff_plain;h=0234cac5baaeb2f1a435b916c7497bb0c563b0aa;hp=3468c14426c76e98f5b4f7e99acfc2cee2f1707b;p=simantics%2Fplatform.git Merge branch 'bug-623' into release/1.43.0.1 Change-Id: Ib039644b70ecf8f9c4fc13178a06065d8ea38de9 --- diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java index 1e4b5cbac..52be328eb 100644 --- a/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java +++ b/bundles/org.simantics.acorn/src/org/simantics/acorn/MainProgram.java @@ -70,7 +70,7 @@ public class MainProgram implements Runnable, Closeable { this.updateSchedules = new ArrayList[CLUSTER_THREADS]; for(int i=0;i(); + updateSchedules[i] = new ArrayList<>(); } } @@ -93,11 +93,13 @@ public class MainProgram implements Runnable, Closeable { try { + TreeMap> updates = new TreeMap<>(clusterComparator); + main: while(alive) { - TreeMap> updates = new TreeMap>(clusterComparator); - + if (!updates.isEmpty()) + updates.clear(); operationQueue.pumpUpdates(updates); if(updates.isEmpty()) { @@ -165,6 +167,9 @@ public class MainProgram implements Runnable, Closeable { for(int i=0;i> entry : updates.entrySet()) { diff --git a/bundles/org.simantics.auditlogging/META-INF/MANIFEST.MF b/bundles/org.simantics.auditlogging/META-INF/MANIFEST.MF index 7c26acd26..0650cddab 100644 --- a/bundles/org.simantics.auditlogging/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.auditlogging/META-INF/MANIFEST.MF @@ -5,19 +5,19 @@ Bundle-SymbolicName: org.simantics.auditlogging Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.simantics.audit.Activator Require-Bundle: org.eclipse.core.runtime, - com.fasterxml.jackson.core.jackson-databind, - com.fasterxml.jackson.core.jackson-core, + com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.8.11,2.9.0)", + com.fasterxml.jackson.core.jackson-core;bundle-version="[2.8.11,2.9.0)", org.slf4j.api, javax.servlet-api, - jakarta.ws.rs-api, + javax.ws.rs-api, org.eclipse.jetty.server;bundle-version="9.4.24", org.eclipse.jetty.servlet;bundle-version="9.4.24", org.eclipse.jetty.util;bundle-version="9.4.24", - org.glassfish.jersey.core.jersey-server, - org.glassfish.jersey.media.jersey-media-json-jackson, - org.glassfish.jersey.containers.jersey-container-servlet-core, - org.glassfish.jersey.core.jersey-client, - org.glassfish.jersey.core.jersey-common + org.glassfish.jersey.core.jersey-server;bundle-version="[2.25.1,2.26.0)", + org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="[2.25.1,2.26.0)", + org.glassfish.jersey.containers.jersey-container-servlet-core;bundle-version="[2.25.1,2.26.0)", + org.glassfish.jersey.core.jersey-client;bundle-version="[2.25.1,2.26.0)", + org.glassfish.jersey.core.jersey-common;bundle-version="[2.25.1,2.26.0)" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Export-Package: org.simantics.audit.server diff --git a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GENatTableThemeConfiguration.java b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GENatTableThemeConfiguration.java index 80882b46c..c1551274e 100644 --- a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GENatTableThemeConfiguration.java +++ b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GENatTableThemeConfiguration.java @@ -15,12 +15,14 @@ public class GENatTableThemeConfiguration extends ModernNatTableThemeConfigurati public GENatTableThemeConfiguration(GETreeData treeData, int style) { super(); + TextPainter cellTextPainter = new TextPainter(); + cellTextPainter.setTrimText(false); this.oddRowBgColor = GUIHelper.getColor(250, 250, 250); this.defaultCellPainter = new GEStyler(treeData, new GEIconPainter( new PaddingDecorator( - new TextPainter(), + cellTextPainter, 0, 5, 0, diff --git a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GEStyler.java b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GEStyler.java index c9c37ab50..e773ebb00 100644 --- a/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GEStyler.java +++ b/bundles/org.simantics.browsing.ui.nattable/src/org/simantics/browsing/ui/nattable/GEStyler.java @@ -42,6 +42,8 @@ public class GEStyler extends CellPainterWrapper{ style.setAttributeValue(CellStyleAttributes.IMAGE, image); wrapper.setSpecificConfigAttribute(CellConfigAttributes.CELL_STYLE, DisplayMode.NORMAL, "BODY", style); + wrapper.setSpecificConfigAttribute(CellConfigAttributes.CELL_STYLE, DisplayMode.SELECT, "BODY", style); + wrapper.setSpecificConfigAttribute(CellConfigAttributes.CELL_STYLE, DisplayMode.SELECT_HOVER, "BODY", style); // wrapper.setSpecificConfigAttribute(CellStyleAttributes.FOREGROUND_COLOR, DisplayMode.NORMAL, "BODY", style.getAttributeValue(CellStyleAttributes.FOREGROUND_COLOR)); // wrapper.setSpecificConfigAttribute(CellStyleAttributes.BACKGROUND_COLOR, DisplayMode.NORMAL, "BODY", style.getAttributeValue(CellStyleAttributes.BACKGROUND_COLOR)); // wrapper.setSpecificConfigAttribute(CellStyleAttributes.FONT, DisplayMode.NORMAL, "BODY", style.getAttributeValue(CellStyleAttributes.FONT)); diff --git a/bundles/org.simantics.charts/META-INF/MANIFEST.MF b/bundles/org.simantics.charts/META-INF/MANIFEST.MF index b0c49505b..769222361 100644 --- a/bundles/org.simantics.charts/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.charts/META-INF/MANIFEST.MF @@ -47,7 +47,7 @@ Require-Bundle: org.eclipse.ui, org.eclipse.e4.ui.bindings;bundle-version="0.11.0", org.eclipse.e4.core.di.annotations, org.eclipse.e4.core.services, - com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2", + com.fasterxml.jackson.core.jackson-core;bundle-version="[2.8.11,2.9.0)", org.slf4j.api Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/editor/ChartCopyHandler.java b/bundles/org.simantics.charts/src/org/simantics/charts/editor/ChartCopyHandler.java index 65108d6f7..1e1c6e1b3 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/editor/ChartCopyHandler.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/editor/ChartCopyHandler.java @@ -1,6 +1,6 @@ /******************************************************************************* - * Copyright (c) 2011 Association for Decentralized Information Management in - * Industry THTH ry. + * Copyright (c) 2011,2020 Association for Decentralized Information Management + * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -8,6 +8,7 @@ * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation + * Semantum Oy - #501 *******************************************************************************/ package org.simantics.charts.editor; @@ -33,11 +34,14 @@ import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.jface.action.IStatusLineManager; import org.eclipse.jface.operation.IRunnableWithProgress; import org.eclipse.jface.preference.IPreferenceStore; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.window.Window; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.FileDialog; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.dialogs.PreferencesUtil; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.simantics.charts.ui.CSVProgressMonitor; @@ -74,8 +78,28 @@ public class ChartCopyHandler extends AbstractHandler { IStatusLineManager status = editor.getEditorSite().getActionBars().getStatusLineManager(); final Shell shell = HandlerUtil.getActiveShell(event); - final AtomicBoolean result = new AtomicBoolean(false); + // Find a good value to use for START_TIME based on the current horizontal ruler + // time range and the data start time. + IPreferenceStore csvnode = new ScopedPreferenceStore( InstanceScope.INSTANCE, CSVPreferences.P_NODE ); + double oldStartTime = csvnode.getDouble(CSVPreferences.P_CSV_START_TIME); + double timeStep = csvnode.getDouble(CSVPreferences.P_CSV_TIME_STEP); + double visibleChartMinTime = trendNode.horizRuler.from; + double dataStartTime = trendNode.horizRuler.getItemFromTime(); + // Find the first sample time that contains data if startTime < _from + double n = Math.max(0, Math.ceil((visibleChartMinTime-dataStartTime) / timeStep)); + double temporaryStartTime = dataStartTime + n*timeStep; + csvnode.setValue(CSVPreferences.P_CSV_START_TIME, temporaryStartTime); + try { + PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn( + shell, "org.simantics.modeling.csv.preferences", + new String[] { "org.simantics.modeling.csv.preferences" }, + null); + dialog.setMessage("Select Used CSV Export Settings"); + if (dialog.open() != Window.OK) + return null; + + AtomicBoolean result = new AtomicBoolean(false); PlatformUI.getWorkbench().getProgressService().busyCursorWhile(new IRunnableWithProgress() { @Override public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { @@ -92,6 +116,8 @@ public class ChartCopyHandler extends AbstractHandler { ErrorLogger.defaultLogError(e.getCause()); } catch (InterruptedException e) { ErrorLogger.defaultLogError(e); + } finally { + csvnode.setValue(CSVPreferences.P_CSV_START_TIME, oldStartTime); } return null; @@ -132,7 +158,7 @@ public class ChartCopyHandler extends AbstractHandler { for (TrendItem i : t.spec.items) { if (i.hidden) continue; - List items = im.search("variableId", i.variableId); + List items = im.search("groupItemId", i.groupItemId, "variableId", i.variableId); Collections.sort(items, SamplingFormat.INTERVAL_COMPARATOR); if (items.isEmpty()) continue; Bean config = items.get(0); diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/editor/ChartPreferencesAction.java b/bundles/org.simantics.charts/src/org/simantics/charts/editor/ChartPreferencesAction.java new file mode 100644 index 000000000..0cc582024 --- /dev/null +++ b/bundles/org.simantics.charts/src/org/simantics/charts/editor/ChartPreferencesAction.java @@ -0,0 +1,38 @@ +package org.simantics.charts.editor; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.preference.PreferenceDialog; +import org.eclipse.jface.window.IShellProvider; +import org.eclipse.ui.dialogs.PreferencesUtil; + +/** + * @author Tuukka Lehtonen + */ +public class ChartPreferencesAction extends Action { + + private static final String CHART_DEFAULTS_PREF_PAGE_ID = "org.simantics.charts.defaults"; //$NON-NLS-1$ + private static final String CHART_PREF_PAGE_ID = "org.simantics.charts.pref"; //$NON-NLS-1$ + private static final String CSV_PREF_PAGE_ID = "org.simantics.modeling.csv.preferences"; //$NON-NLS-1$ + + private IShellProvider shell; + + public ChartPreferencesAction(IShellProvider shell) { + super(Messages.ChartPreferencesAction_ChartPreferences); + this.shell = shell; + } + + @Override + public void run() { + PreferenceDialog dialog = PreferencesUtil.createPreferenceDialogOn( + shell.getShell(), + CHART_PREF_PAGE_ID, + new String[] { + CHART_PREF_PAGE_ID, + CHART_DEFAULTS_PREF_PAGE_ID, + CSV_PREF_PAGE_ID + }, + null); + dialog.open(); + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/editor/Messages.java b/bundles/org.simantics.charts/src/org/simantics/charts/editor/Messages.java new file mode 100644 index 000000000..5771b1421 --- /dev/null +++ b/bundles/org.simantics.charts/src/org/simantics/charts/editor/Messages.java @@ -0,0 +1,15 @@ +package org.simantics.charts.editor; + +import org.eclipse.osgi.util.NLS; + +public class Messages extends NLS { + private static final String BUNDLE_NAME = "org.simantics.charts.editor.messages"; //$NON-NLS-1$ + public static String ChartPreferencesAction_ChartPreferences; + static { + // initialize resource bundle + NLS.initializeMessages(BUNDLE_NAME, Messages.class); + } + + private Messages() { + } +} diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/editor/TimeSeriesEditor.java b/bundles/org.simantics.charts/src/org/simantics/charts/editor/TimeSeriesEditor.java index bffd4c8a2..ad718e49e 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/editor/TimeSeriesEditor.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/editor/TimeSeriesEditor.java @@ -635,6 +635,8 @@ public class TimeSeriesEditor extends ResourceEditorPart { if (chartItem != null) { manager.add(new HideItemsAction("Hide Item", true, Collections.singletonList(chartItem))); manager.add(new Separator()); + manager.add(new ChartPreferencesAction(getSite())); + manager.add(new Separator()); manager.add(new PropertiesAction("Item Properties", canvas, chartItem)); manager.add(new PropertiesAction("Chart Properties", canvas, chart)); } @@ -674,6 +676,8 @@ public class TimeSeriesEditor extends ResourceEditorPart { manager.add(new SendCommandAction("Zoom to Fit Vertically", IMG_ZOOM_TO_FIT_VERT, cvsCtx, Commands.ZOOM_TO_FIT_VERT)); manager.add(new SendCommandAction("Autoscale Chart", IMG_AUTOSCALE, cvsCtx, Commands.AUTOSCALE)); manager.add(new Separator()); + manager.add(new ChartPreferencesAction(getSite())); + manager.add(new Separator()); manager.add(new PropertiesAction("Chart Properties", canvas, chart)); } } diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/editor/messages.properties b/bundles/org.simantics.charts/src/org/simantics/charts/editor/messages.properties new file mode 100644 index 000000000..37bbe90f6 --- /dev/null +++ b/bundles/org.simantics.charts/src/org/simantics/charts/editor/messages.properties @@ -0,0 +1 @@ +ChartPreferencesAction_ChartPreferences=Chart Preferences diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartCSV.java b/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartCSV.java index 7e6bdc3b7..57f1ed33f 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartCSV.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/export/ExportChartCSV.java @@ -102,7 +102,7 @@ public class ExportChartCSV extends org.simantics.simulation.export.ExperimentEx labelBuilder.append(")"); } - List historyItems = im.search("variableId", item.variableReference); + List historyItems = im.search("groupItemId", item.groupItemId, "variableId", item.variableReference); Collections.sort(historyItems, SamplingFormat.INTERVAL_COMPARATOR); if (items.isEmpty()) continue; Bean config = historyItems.get(0); diff --git a/bundles/org.simantics.charts/src/org/simantics/charts/query/ChartAndSubscriptionItemData.java b/bundles/org.simantics.charts/src/org/simantics/charts/query/ChartAndSubscriptionItemData.java index 9438e404b..8f2bd26f8 100644 --- a/bundles/org.simantics.charts/src/org/simantics/charts/query/ChartAndSubscriptionItemData.java +++ b/bundles/org.simantics.charts/src/org/simantics/charts/query/ChartAndSubscriptionItemData.java @@ -48,7 +48,7 @@ public class ChartAndSubscriptionItemData extends Bean { // Output @Optional public String subscription = "Default"; - @Optional public String unit = ""; + @Optional public String unit; @Optional public Double min, max, deadband, interval, gain, bias; @Optional public DrawMode drawmode; @Optional public Scale scale; diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/UndoMetadata.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/UndoMetadata.java index f8026f594..0568b3103 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/UndoMetadata.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/UndoMetadata.java @@ -116,4 +116,11 @@ public class UndoMetadata extends ACommentMetadata { public String getHeader() { return getType() + getRange(); } + + /** + * Returns true when no change sets are included. + */ + public boolean isEmpty() { + return begin == 0 && end == 0; + } } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java index e9523c0c8..dfb5780f9 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/MergingGraphRequestProcessor.java @@ -33,7 +33,6 @@ import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter; import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.WriteRequest; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.CancelTransactionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.procedure.AsyncListener; @@ -63,9 +62,13 @@ import org.simantics.db.request.WriteOnlyResult; import org.simantics.db.request.WriteResult; import org.simantics.utils.DataContainer; import org.simantics.utils.datastructures.Pair; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class MergingGraphRequestProcessor implements AsyncRequestProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(MergingGraphRequestProcessor.class); + private static class SyncWriteRequestAdapter implements Write { private Semaphore semaphore = new Semaphore(0); @@ -128,7 +131,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { try { semaphore.acquire(); } catch (InterruptedException e) { - Logger.defaultLogError(e); + LOGGER.error("SyncWriteRequestAdapter interrupted", e); } } @@ -223,7 +226,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { try { MergingGraphRequestProcessor.this.wait(transactionKeepalivePeriod); } catch (InterruptedException e) { - Logger.defaultLogError(e); + LOGGER.error("MergedRead interrupted", e); } if (requestQueue.isEmpty()) break; @@ -262,7 +265,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("MergedRead failed", t); // if(currentRequest.second instanceof AsyncProcedure) { // ((AsyncProcedure)currentRequest.second).exception(graph, t); @@ -281,7 +284,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { } else { - try{ + try { if(currentRequest.second instanceof AsyncProcedure) { if(currentRequest.first instanceof AsyncRead) { @@ -298,7 +301,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("MergedRead failed", t); // if(currentRequest.second instanceof AsyncProcedure) { // ((AsyncProcedure)currentRequest.second).exception(graph, t); @@ -355,7 +358,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { try { MergingGraphRequestProcessor.this.wait(transactionKeepalivePeriod); } catch (InterruptedException e) { - Logger.defaultLogError(e); + LOGGER.error("RunnerWriteGraphRequest interrupted", e); } if (requestQueue.isEmpty()) break; @@ -385,7 +388,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { graph.syncRequest(adapter); if(callback != null) callback.accept(null); } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("RunnerWriteGraphRequest failed", t); if(callback != null) callback.accept(t); } @@ -399,7 +402,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { else if(currentRequest.first instanceof DelayedWrite) graph.syncRequest((DelayedWrite)currentRequest.first); if(callback != null) callback.accept(null); } catch(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("RunnerWriteGraphRequest failed", t); if(callback != null) callback.accept(t); } @@ -572,7 +575,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncMultiRead, AsyncMultiProcedure) failed", t); throw new RuntimeException(t.getMessage()); } @@ -625,7 +628,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncRead, AsyncProcedure) failed", t); throw new RuntimeException(t.getMessage()); } @@ -691,7 +694,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { @Override public void exception(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("asyncRequest(AsyncRead) failed", t); } }); @@ -736,7 +739,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncRead) failed", t); throw new RuntimeException(t.getMessage()); } @@ -775,7 +778,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { Throwable t = throwable.get(); if(t != null) { - Logger.defaultLogError(t); + LOGGER.error("syncRequest(AsyncMultiRead) failed", t); throw new RuntimeException(t.getMessage()); } @@ -878,7 +881,7 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { @Override public void exception(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("asyncRequest(Read) failed", t); } }); @@ -1305,4 +1308,9 @@ public class MergingGraphRequestProcessor implements AsyncRequestProcessor { throw new UnsupportedOperationException(); } + @Override + public T l0() { + return processor.l0(); + } + } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java index 1f00ff008..f47ebb3f3 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/processor/ProcessorBase.java @@ -46,6 +46,11 @@ import org.simantics.db.request.WriteResult; public class ProcessorBase implements AsyncRequestProcessor { + @Override + public T l0() { + throw new UnsupportedOperationException(); + } + @Override public void asyncRequest(AsyncMultiRead request, AsyncMultiProcedure procedure) { throw new UnsupportedOperationException(); diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java index b3eba37fb..aeea33f02 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/request/AdaptValue.java @@ -14,7 +14,7 @@ import org.simantics.scl.runtime.function.FunctionImpl3; * @author Hannu Niemistö */ public class AdaptValue extends ResourceRead { - + public AdaptValue(Resource resource) { super(resource); } @@ -31,14 +31,14 @@ public class AdaptValue extends ResourceRead { } }; - + @Override public Object perform(ReadGraph graph) throws DatabaseException { - String uri = graph.getURI(resource); - if(Layer0.URIs.Functions_functionApplication.equals(uri)) return functionApplication; + Layer0 L0 = graph.l0(); + if (L0.Functions_functionApplication.equalsResource(resource)) + return functionApplication; ComputationalValue ev = graph.adapt(resource, ComputationalValue.class); return ev.getValue(graph, resource); - } } diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java index 143d3e443..8e8171f85 100644 --- a/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java +++ b/bundles/org.simantics.db.common/src/org/simantics/db/common/utils/OrderedSetUtils.java @@ -220,6 +220,27 @@ public class OrderedSetUtils { } } + /** + * Reorders elements with a minimum number of writes. The set of elements must remain the same. + */ + public static void reorder(WriteGraph g, Resource l, Iterable order) throws DatabaseException { + Resource newPrev = l; + for (Resource r : order) { + Resource prev = OrderedSetUtils.prev(g, l, r); + if (!prev.equals(newPrev)) { + g.deny(prev, l, r); + g.claim(newPrev, l, r); + } + newPrev = r; + } + Resource newLast = newPrev; + Resource last = OrderedSetUtils.prev(g, l, l); + if (!last.equals(newLast)) { + g.deny(last, l, l); + g.claim(newLast, l, l); + } + } + /** * Converts ordered set into a list. */ diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java index 110e1d59b..cc15c1eac 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java @@ -1349,7 +1349,10 @@ public class ReadGraphImpl implements AsyncReadGraph { Statement stm = getSingleStatement(resource, relation); - return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz); + Object o = adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz); + if (clazz.isInstance(o)) + return (T)o; + throw new AdaptionException("Returned value is not expected class , got " + o.getClass().getName()+ " , expected " + clazz.getName()); } @@ -1511,15 +1514,15 @@ public class ReadGraphImpl implements AsyncReadGraph { try { - int result = processor.getSingleObject(this, subject, relation); - if(result == 0) return null; - - return processor.querySupport.getResource(result); + int result = processor.getSingleObject(this, subject, relation); + if(result == 0) return null; + + return processor.querySupport.getResource(result); - } catch (ManyObjectsForFunctionalRelationException e) { + } catch (ManyObjectsForFunctionalRelationException e) { + + throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation); - throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e); - } catch (DatabaseException e) { throw new ServiceException(e); @@ -6387,4 +6390,10 @@ public class ReadGraphImpl implements AsyncReadGraph { else return getTopLevelGraphStatic(impl.parentGraph); } + @SuppressWarnings("unchecked") + @Override + public T l0() { + return (T) processor.getL0(); + } + } diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java index 0c4e68138..8cb1688fb 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/WriteGraphImpl.java @@ -14,10 +14,13 @@ package org.simantics.db.impl.graph; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.IdentityHashMap; +import java.util.Map; import java.util.TreeMap; import java.util.function.Consumer; import org.simantics.databoard.Bindings; +import org.simantics.databoard.Datatypes; import org.simantics.databoard.accessor.Accessor; import org.simantics.databoard.binding.Binding; import org.simantics.databoard.binding.error.BindingConstructionException; @@ -31,7 +34,16 @@ import org.simantics.databoard.primitives.MutableLong; import org.simantics.databoard.primitives.MutableString; import org.simantics.databoard.serialization.SerializationException; import org.simantics.databoard.serialization.Serializer; +import org.simantics.databoard.type.ArrayType; +import org.simantics.databoard.type.BooleanType; +import org.simantics.databoard.type.ByteType; import org.simantics.databoard.type.Datatype; +import org.simantics.databoard.type.DoubleType; +import org.simantics.databoard.type.FloatType; +import org.simantics.databoard.type.IntegerType; +import org.simantics.databoard.type.LongType; +import org.simantics.databoard.type.StringType; +import org.simantics.databoard.type.VariantType; import org.simantics.databoard.util.binary.RandomAccessBinary; import org.simantics.db.DevelopmentKeys; import org.simantics.db.ExternalValueSupport; @@ -69,8 +81,6 @@ import org.simantics.layer0.Layer0; import org.simantics.utils.Development; import org.simantics.utils.datastructures.Pair; -import gnu.trove.map.hash.THashMap; - final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph { @@ -683,7 +693,7 @@ final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph { } - THashMap, Resource> builtinValues = new THashMap, Resource>(32); + Map builtinValues = new IdentityHashMap<>(40); private void initBuiltinValues(Layer0 b) { @@ -714,6 +724,76 @@ final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph { builtinValues.put(MutableByte.class, b.Byte); builtinValues.put(MutableBoolean.class, b.Boolean); + builtinValues.put(Datatypes.DOUBLE, b.Double); + builtinValues.put(Datatypes.STRING, b.String); + builtinValues.put(Datatypes.INTEGER, b.Integer); + builtinValues.put(Datatypes.LONG, b.Long); + builtinValues.put(Datatypes.FLOAT, b.Float); + builtinValues.put(Datatypes.BYTE, b.Byte); + builtinValues.put(Datatypes.BOOLEAN, b.Boolean); + builtinValues.put(Datatypes.VARIANT, b.Variant); + + builtinValues.put(Datatypes.DOUBLE_ARRAY, b.DoubleArray); + builtinValues.put(Datatypes.STRING_ARRAY, b.StringArray); + builtinValues.put(Datatypes.INTEGER_ARRAY, b.IntegerArray); + builtinValues.put(Datatypes.LONG_ARRAY, b.LongArray); + builtinValues.put(Datatypes.FLOAT_ARRAY, b.FloatArray); + builtinValues.put(Datatypes.BYTE_ARRAY, b.ByteArray); + builtinValues.put(Datatypes.BOOLEAN_ARRAY, b.BooleanArray); + builtinValues.put(Datatypes.VARIANT_ARRAY, b.VariantArray); + } + + private static Datatype canonicalizeToBuiltinDatatype(Datatype datatype) { + if (datatype instanceof ArrayType) { + ArrayType at = (ArrayType) datatype; + datatype = at.componentType(); + if (datatype instanceof ByteType) { + return Datatypes.BYTE_ARRAY; + } else if (datatype instanceof DoubleType) { + return Datatypes.DOUBLE_ARRAY; + } else if (datatype instanceof FloatType) { + return Datatypes.FLOAT_ARRAY; + } else if (datatype instanceof IntegerType) { + return Datatypes.INTEGER_ARRAY; + } else if (datatype instanceof LongType) { + return Datatypes.LONG_ARRAY; + } else if (datatype instanceof BooleanType) { + return Datatypes.BOOLEAN_ARRAY; + } else if (datatype instanceof StringType) { + return Datatypes.STRING_ARRAY; + } else if (datatype instanceof VariantType) { + return Datatypes.VARIANT_ARRAY; + } + return null; + } + if (datatype instanceof ByteType) { + return Datatypes.BYTE; + } else if (datatype instanceof DoubleType) { + return Datatypes.DOUBLE; + } else if (datatype instanceof FloatType) { + return Datatypes.FLOAT; + } else if (datatype instanceof IntegerType) { + return Datatypes.INTEGER; + } else if (datatype instanceof LongType) { + return Datatypes.LONG; + } else if (datatype instanceof BooleanType) { + return Datatypes.BOOLEAN; + } else if (datatype instanceof StringType) { + return Datatypes.STRING; + } else if (datatype instanceof VariantType) { + return Datatypes.VARIANT; + } + return null; + } + + private Resource resolveBuiltinResourceType(Class valueClass, Datatype datatype) { + Resource type = builtinValues.get(valueClass); + return type != null ? type : builtinValues.get(datatype); + } + + private Resource resolveBuiltinResourceTypeByCanonicalizedDatatype(Datatype datatype, Resource defaultResult) { + Datatype cdt = canonicalizeToBuiltinDatatype(datatype); + return cdt != null ? builtinValues.get(cdt) : defaultResult; } @Override @@ -734,13 +814,13 @@ final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph { initBuiltinValues(b); Resource literal = newResource(); - Class clazz = value.getClass(); - Resource type = builtinValues.get(clazz); + Datatype dt = binding.type(); + Resource type = resolveBuiltinResourceType(value.getClass(), dt); if (type == null) { - type = b.Literal; + type = resolveBuiltinResourceTypeByCanonicalizedDatatype(dt, b.Literal); Resource dataType = newResource(); claim(dataType, b.InstanceOf, null, b.DataType); - claimValue(dataType, binding.type(), DATA_TYPE_BINDING); + claimValue(dataType, dt, DATA_TYPE_BINDING); claim(literal, b.HasDataType, b.HasDataType_Inverse, dataType); } @@ -805,14 +885,14 @@ final public class WriteGraphImpl extends ReadGraphImpl implements WriteGraph { } else { - Class clazz = value.getClass(); - Resource type = builtinValues.get(clazz); Resource literal = newResource(); + Datatype dt = binding.type(); + Resource type = resolveBuiltinResourceType(value.getClass(), dt); if (type == null) { - type = b.Literal; + type = resolveBuiltinResourceTypeByCanonicalizedDatatype(dt, b.Literal); Resource dataType = newResource(); claim(dataType, b.InstanceOf, null, b.DataType); - claimValue(dataType, binding.type(), DATA_TYPE_BINDING); + claimValue(dataType, dt, DATA_TYPE_BINDING); claim(literal, b.HasDataType, null, dataType); } claim(literal, b.InstanceOf, null, type); diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java index f74344b2f..8bac42263 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Objects.java @@ -37,569 +37,566 @@ import org.simantics.db.request.RequestFlags; public final class Objects extends CollectionBinaryQuery implements IntProcedure { - public Objects(final int r1, final int r2) { - super(r1, r2); - } - - @Override - final public void removeEntry(QueryProcessor provider) { - provider.cache.remove(this); - } - - final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Objects entry) throws DatabaseException { - - class AssertionMapProc implements IntProcedure { - - boolean first = true; - - private IntArray result; - - public void addStatement(int s, int p, int o) { - - if(result.size() == 0) { - result.add(s); - result.add(p); - result.add(o); - } else { - for(int i = 0;i < result.sizeOrData ; i+=3) { - int existingP = result.data[i+1]; - if(p == existingP) { - int existingO = result.data[i+2]; - if(existingO == o) return; - } - } - result.add(s); - result.add(p); - result.add(o); - } - - } - - @Override - public void execute(ReadGraphImpl graph, int type) throws DatabaseException { - if(result == null) { - result = QueryCacheBase.resultAssertedStatements(graph, type, r2, entry, null); - } else { - if (first) { - IntArray ia = result; - result = new IntArray(); - if(ia.data != null) { - for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); - } - first = false; - } - IntArray ia = QueryCacheBase.resultAssertedStatements(graph, type, r2, entry, null); - if(ia.data != null) { - for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); - } - } - } + public Objects(final int r1, final int r2) { + super(r1, r2); + } - @Override - public void finished(ReadGraphImpl graph) { - } + @Override + final public void removeEntry(QueryProcessor provider) { + provider.cache.remove(this); + } - @Override - public void exception(ReadGraphImpl graph, Throwable throwable) { - } + final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Objects entry) throws DatabaseException { + + class AssertionMapProc implements IntProcedure { + + boolean first = true; + + private IntArray result; + + public void addStatement(int s, int p, int o) { + + if(result.size() == 0) { + result.add(s); + result.add(p); + result.add(o); + } else { + for(int i = 0;i < result.sizeOrData ; i+=3) { + int existingP = result.data[i+1]; + if(p == existingP) { + int existingO = result.data[i+2]; + if(existingO == o) return; + } + } + result.add(s); + result.add(p); + result.add(o); + } + + } + + @Override + public void execute(ReadGraphImpl graph, int type) throws DatabaseException { + if(result == null) { + result = QueryCacheBase.resultAssertedStatements(graph, type, r2, entry, null); + } else { + if (first) { + IntArray ia = result; + result = new IntArray(); + if(ia.data != null) { + for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); + } + first = false; + } + IntArray ia = QueryCacheBase.resultAssertedStatements(graph, type, r2, entry, null); + if(ia.data != null) { + for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); + } + } + } + + @Override + public void finished(ReadGraphImpl graph) { + } + + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } - } + } - AssertionMapProc amp = new AssertionMapProc(); + AssertionMapProc amp = new AssertionMapProc(); - // This dependency could be cut - QueryCache.runnerPrincipalTypes(graph, r1, entry, null, amp); + // This dependency could be cut + QueryCache.runnerPrincipalTypes(graph, r1, entry, null, amp); - return amp.result; + return amp.result; - } + } - final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final IntProcedure procedure) throws DatabaseException { + final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final IntProcedure procedure) throws DatabaseException { - IntArray map = getAssertionMap(graph, r1, r2, parent); - if(map == null) { - procedure.finished(graph); - return; - } + IntArray map = getAssertionMap(graph, r1, r2, parent); + if(map == null) { + procedure.finished(graph); + return; + } - int size = map.size(); - if(size == 3) { - int value = map.data[2]; - procedure.execute(graph, value); - procedure.finished(graph); - } else if(size == 0) { - procedure.finished(graph); - } else { + int size = map.size(); + if(size == 3) { + int value = map.data[2]; + procedure.execute(graph, value); + procedure.finished(graph); + } else if(size == 0) { + procedure.finished(graph); + } else { - int candidateS = map.data[0]; - int candidateO = map.data[2]; + int candidateS = map.data[0]; + int candidateO = map.data[2]; - IntSet candidateIs = null; - try { - candidateIs = QueryCache.resultSuperTypes(graph, candidateS, parent, null); - } catch (DatabaseException e) { - procedure.exception(graph, e); - return; - } + IntSet candidateIs = null; + try { + candidateIs = QueryCache.resultSuperTypes(graph, candidateS, parent, null); + } catch (DatabaseException e) { + procedure.exception(graph, e); + return; + } - for(int i=3;i ignore next + // Next is a super type of candidate => ignore next - } else { + } else { - IntSet nextIs = null; - try { - nextIs = QueryCache.resultSuperTypes(graph, nextS, parent, null); - } catch (DatabaseException e) { - procedure.exception(graph, e); - return; - } + IntSet nextIs = null; + try { + nextIs = QueryCache.resultSuperTypes(graph, nextS, parent, null); + } catch (DatabaseException e) { + procedure.exception(graph, e); + return; + } - if(nextIs.contains(candidateS)) { + if(nextIs.contains(candidateS)) { - // Candidate is a super type of next => next is the new candidate + // Candidate is a super type of next => next is the new candidate - candidateS = nextS; - candidateO = nextO; - candidateIs = nextIs; + candidateS = nextS; + candidateO = nextO; + candidateIs = nextIs; - } else { + } else { - // candidate and next are unrelated => error - ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has conflicting assertions " + r1 + ", " + r2 + " " + map , r1); - procedure.exception(graph, exception); - return; + // candidate and next are unrelated => error + ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has conflicting assertions " + r1 + ", " + r2 + " " + map , r1); + procedure.exception(graph, exception); + return; - } + } - } + } - } + } - } + } - procedure.execute(graph, candidateO); - procedure.finished(graph); + procedure.execute(graph, candidateO); + procedure.finished(graph); - } + } - } + } - final static InternalProcedure NOP = new InternalProcedure() { + final static InternalProcedure NOP = new InternalProcedure() { - @Override - public void execute(ReadGraphImpl graph, IntSet result) { - } + @Override + public void execute(ReadGraphImpl graph, IntSet result) { + } - @Override - public void exception(ReadGraphImpl graph, Throwable throwable) { - } + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } - }; + }; - final static TripleIntProcedure NOPT = new TripleIntProcedure() { + final static TripleIntProcedure NOPT = new TripleIntProcedure() { - @Override - public void exception(ReadGraphImpl graph, Throwable throwable) { - } + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } - @Override - public void execute(ReadGraphImpl graph, int s, int p, int o) { - } + @Override + public void execute(ReadGraphImpl graph, int s, int p, int o) { + } - @Override - public void finished(ReadGraphImpl graph) { - } + @Override + public void finished(ReadGraphImpl graph) { + } - }; + }; - // Search for one statement - final public void computeFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, final RelationInfo ri, final IntProcedure procedure) throws DatabaseException { - computeFunctionalIndex(graph, r1(), r2(), this, ri, procedure); - } + // Search for one statement + final public void computeFunctionalIndex(ReadGraphImpl graph, final QueryProcessor provider, final RelationInfo ri, final IntProcedure procedure) throws DatabaseException { + computeFunctionalIndex(graph, r1(), r2(), this, ri, procedure); + } - // Search for one statement - final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final RelationInfo ri, final IntProcedure procedure) throws DatabaseException { + // Search for one statement + final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final RelationInfo ri, final IntProcedure procedure) throws DatabaseException { - if(ri.isFinal) { + if(ri.isFinal) { - int result = graph.processor.querySupport.getFunctionalObject(r1, r2); + int result = graph.processor.querySupport.getFunctionalObject(r1, r2); - if(result == 0) { + if(result == 0) { - // Check for assertions - forSingleAssertion(graph, r1, r2, parent, procedure); + // Check for assertions + forSingleAssertion(graph, r1, r2, parent, procedure); - } else if (result == -1) { + } else if (result == -1) { - graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { + graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - procedure.execute(graph, i); - } + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + procedure.execute(graph, i); + } - @Override - public void exception(ReadGraphImpl graph, Throwable t) { - if(DebugException.DEBUG) new DebugException(t).printStackTrace(); - } + @Override + public void exception(ReadGraphImpl graph, Throwable t) { + if(DebugException.DEBUG) new DebugException(t).printStackTrace(); + } - @Override - public void finished(ReadGraphImpl graph) { - } + @Override + public void finished(ReadGraphImpl graph) { + } - }); + }); - // Check for assertions - forSingleAssertion(graph, r1, r2, parent, procedure); + // Check for assertions + forSingleAssertion(graph, r1, r2, parent, procedure); - } else { + } else { - // If functional relation was found there is no need to check assertions + // If functional relation was found there is no need to check assertions procedure.execute(graph, result); procedure.finished(graph); - - } + } - } else { + } else { - // Note! The dependency is intentionally cut! + // Note! The dependency is intentionally cut! IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null); direct.forEach(graph, new SyncIntProcedure() { - boolean found = false; - - @Override - public void run(ReadGraphImpl graph) throws DatabaseException { - - if(found) { - procedure.finished(graph); - } else { + /* + * 0 = not found + * 1 = found + * 2 = exception + */ + int found = 0; - // Check for assertions - forSingleAssertion(graph, r1, r2, parent, procedure); + @Override + public void run(ReadGraphImpl graph) throws DatabaseException { - } + if(found == 1) { - } + procedure.finished(graph); - @Override - public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException { + } else if(found == 0) { - if(found) return; + // Check for assertions + forSingleAssertion(graph, r1, r2, parent, procedure); - if(pred == r2) { + } - // Note! The dependency is intentionally cut! - QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { + } - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + @Override + public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException { - if(!found) { + if(found > 0) + return; - procedure.execute(graph, i); - found = true; + if(pred == r2) { - } else { + // Note! The dependency is intentionally cut! + QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { - ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement (r1=" + r1 + ", r2=" + r2 + ").", r1); - procedure.exception(graph, exception); + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - } + if(found == 0) { - } + procedure.execute(graph, i); + found = 1; - @Override - public void finished(ReadGraphImpl graph) { - } + } else { - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - } + ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement (r1=" + r1 + ", r2=" + r2 + ").", r1); + procedure.exception(graph, exception); + found = 2; - }); + } - } else { + } - QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure() { + @Override + public void finished(ReadGraphImpl graph) { + } - @Override - public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException { + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - if(found) return; + procedure.exception(graph, t); + found = 2; - if(result.contains(r2)) { + } - // Note! The dependency is intentionally cut! - QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { + }); - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + } else { - if(!found) { + QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure() { - procedure.execute(graph, i); - found = true; + @Override + public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException { - } else { + if(found > 0) + return; - ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement (r1=" + r1 + ", r2=" + r2 + ").", r1); - procedure.exception(graph, exception); + if(result.contains(r2)) { - } + // Note! The dependency is intentionally cut! + QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { - } + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - @Override - public void finished(ReadGraphImpl graph) { - } + if(found == 0) { - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - } + procedure.execute(graph, i); + found = 1; - }); + } else { - } + ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement (r1=" + r1 + ", r2=" + r2 + ").", r1); + procedure.exception(graph, exception); + found = 2; - } + } - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - } + } - }); + @Override + public void finished(ReadGraphImpl graph) { + } - } + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + procedure.exception(graph, t); + found = 2; + } - } + }); - @Override - public void finished(ReadGraphImpl graph) throws DatabaseException { + } - dec(graph); + } - } + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + procedure.exception(graph, t); + found = 2; + } - }); + }); + } - } + } - } + @Override + public void finished(ReadGraphImpl graph) throws DatabaseException { + dec(graph); + } - final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final IntProcedure procedure) throws DatabaseException { + }); - // Note! The dependency is intentionally cut! - QueryCache.runnerPrincipalTypes(graph, r1, null, null, new SyncIntProcedure() { - @Override - public void run(ReadGraphImpl graph) throws DatabaseException { - procedure.finished(graph); - } - - TripleIntProcedure proc = new TripleIntProcedure() { + } - @Override - public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException { - procedure.execute(graph, o); - } + } - @Override - public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); - } + final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, final IntProcedure procedure) throws DatabaseException { - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - if(DebugException.DEBUG) new DebugException(t).printStackTrace(); - procedure.exception(graph, t); - dec(graph); - } + // Note! The dependency is intentionally cut! + QueryCache.runnerPrincipalTypes(graph, r1, null, null, new SyncIntProcedure() { - }; + @Override + public void run(ReadGraphImpl graph) throws DatabaseException { + procedure.finished(graph); + } - @Override - public void execute(ReadGraphImpl graph, int type) throws DatabaseException { + TripleIntProcedure proc = new TripleIntProcedure() { - inc(); - QueryCache.runnerAssertedStatements(graph, type, r2, parent, null, proc); + @Override + public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException { + procedure.execute(graph, o); + } - } + @Override + public void finished(ReadGraphImpl graph) throws DatabaseException { + dec(graph); + } - @Override - public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); - } + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + if(DebugException.DEBUG) new DebugException(t).printStackTrace(); + procedure.exception(graph, t); + dec(graph); + } - }); + }; + @Override + public void execute(ReadGraphImpl graph, int type) throws DatabaseException { - } + inc(); + QueryCache.runnerAssertedStatements(graph, type, r2, parent, null, proc); - final public static void computeNotFunctionalFinalIndex(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, RelationInfo ri, AsyncMultiProcedure procedure) { - throw new Error(); - } + } - final public void computeNotFunctionalIndex(ReadGraphImpl graph, RelationInfo ri, final IntProcedure procedure) throws DatabaseException { - computeNotFunctionalIndex(graph, r1(), r2(), this, ri, procedure); - } + @Override + public void finished(ReadGraphImpl graph) throws DatabaseException { + dec(graph); + } - final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, RelationInfo ri, final IntProcedure procedure) throws DatabaseException { + }); - if(ri.isFinal) { - graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { + } - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - procedure.execute(graph, i); - } + final public static void computeNotFunctionalFinalIndex(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, RelationInfo ri, AsyncMultiProcedure procedure) { + throw new Error(); + } - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - if(DebugException.DEBUG) new DebugException(t).printStackTrace(); - procedure.exception(graph, t); - } + final public void computeNotFunctionalIndex(ReadGraphImpl graph, RelationInfo ri, final IntProcedure procedure) throws DatabaseException { + computeNotFunctionalIndex(graph, r1(), r2(), this, ri, procedure); + } - @Override - public void finished(ReadGraphImpl graph) { - } + final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Objects parent, RelationInfo ri, final IntProcedure procedure) throws DatabaseException { - }); + if(ri.isFinal) { - if(ri.isAsserted) { - forAssertions(graph, r1, r2, parent, procedure); - } else { - procedure.finished(graph); - } + graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { - } else { + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + procedure.execute(graph, i); + } - // Note! The dependency is intentionally cut! - IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null); - direct.forEach(graph, new SyncIntProcedure() { + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + if(DebugException.DEBUG) new DebugException(t).printStackTrace(); + procedure.exception(graph, t); + } - @Override - public void run(ReadGraphImpl graph) throws DatabaseException { - forAssertions(graph, r1, r2, parent, procedure); - } + @Override + public void finished(ReadGraphImpl graph) { + } - @Override - public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException { + }); - if(pred == r2) { + if(ri.isAsserted) { + forAssertions(graph, r1, r2, parent, procedure); + } else { + procedure.finished(graph); + } - inc(); + } else { - // Note! The dependency is intentionally cut! - QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { + // Note! The dependency is intentionally cut! + IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null); + direct.forEach(graph, new SyncIntProcedure() { - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - procedure.execute(graph, i); - } + @Override + public void run(ReadGraphImpl graph) throws DatabaseException { + forAssertions(graph, r1, r2, parent, procedure); + } - @Override - public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); - } + @Override + public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException { - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - dec(graph); - } + if(pred == r2) { - }); + // Note! The dependency is intentionally cut! + QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { - } else { + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + procedure.execute(graph, i); + } - inc(); + @Override + public void finished(ReadGraphImpl graph) throws DatabaseException { + } - QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure() { + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + procedure.exception(graph, t); + } - @Override - public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException { + }); - if(result.contains(r2)) { + } else { - inc(); + try { - // Note! The dependency is intentionally cut! - QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { + IntSet result = QueryCache.resultSuperRelations(graph, pred, parent, null); + if(result.contains(r2)) { - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - procedure.execute(graph, i); - } + inc(); - @Override - public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); - } + // Note! The dependency is intentionally cut! + QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - if(DebugException.DEBUG) new DebugException(t).printStackTrace(); - procedure.exception(graph, t); - dec(graph); - } + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + procedure.execute(graph, i); + } - }); + @Override + public void finished(ReadGraphImpl graph) throws DatabaseException { + dec(graph); + } - } + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + if(DebugException.DEBUG) new DebugException(t).printStackTrace(); + procedure.exception(graph, t); + dec(graph); + } - dec(graph); + }); - } + } - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - dec(graph); - } + } catch (Throwable e) { + procedure.exception(graph, e); + } - }); + } - } + } - } + @Override + public void finished(ReadGraphImpl graph) throws DatabaseException { + dec(graph); + } - @Override - public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); - } + }); - }); + } - } + } - } + public Object compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { + computeForEach(graph, r1(), r2(), this, procedure); + return getResult(); + } - public Object compute(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { - computeForEach(graph, r1(), r2(), this, procedure); - return getResult(); - } + public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, final IntProcedure procedure_) throws DatabaseException { - public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Objects entry, final IntProcedure procedure_) throws DatabaseException { + IntProcedure procedure = entry != null ? entry : procedure_; - IntProcedure procedure = entry != null ? entry : procedure_; - RelationInfo ri = QueryCache.resultRelationInfoQuery(graph, r2, entry, null); graph.ensureLoaded(r1, r2); if(ri.isFunctional) { @@ -607,63 +604,63 @@ public final class Objects extends CollectionBinaryQuery implement } else { computeNotFunctionalIndex(graph, r1, r2, entry, ri, procedure); } - - if(entry != null) entry.performFromCache(graph, procedure_); - } + if(entry != null) entry.performFromCache(graph, procedure_); - @Override - public String toString() { - return "Objects[" + r1() + " - " + r2() + "]"; - } + } - @Override - public Object performFromCache(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { + @Override + public String toString() { + return "Objects[" + r1() + " - " + r2() + "]"; + } - assert(isReady()); + @Override + public Object performFromCache(ReadGraphImpl graph, final IntProcedure procedure) throws DatabaseException { - if(handleException(graph, procedure)) return getResult(); + assert(isReady()); - final IntArray value = (IntArray)getResult(); - if(value.data == null) { - if(value.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, value.sizeOrData); - } else { - for(int i = 0;i < value.sizeOrData ; i++) procedure.execute(graph, value.data[i]); - } + if(handleException(graph, procedure)) return getResult(); - procedure.finished(graph); - - return value; + final IntArray value = (IntArray)getResult(); + if(value.data == null) { + if(value.sizeOrData != IntArray.NO_DATA) procedure.execute(graph, value.sizeOrData); + } else { + for(int i = 0;i < value.sizeOrData ; i++) procedure.execute(graph, value.data[i]); + } + + procedure.finished(graph); - } + return value; - @Override - public void recompute(ReadGraphImpl graph) throws DatabaseException { + } - compute(graph, new IntProcedureAdapter() { + @Override + public void recompute(ReadGraphImpl graph) throws DatabaseException { - @Override - public void finished(ReadGraphImpl graph) { - } + compute(graph, new IntProcedureAdapter() { - @Override - public void exception(ReadGraphImpl graph, Throwable t) { - new Error("Error in recompute.", t).printStackTrace(); - } + @Override + public void finished(ReadGraphImpl graph) { + } - }); + @Override + public void exception(ReadGraphImpl graph, Throwable t) { + new Error("Error in recompute.", t).printStackTrace(); + } - } + }); - @Override - public int type() { - return RequestFlags.IMMEDIATE_UPDATE; - } + } - @Override - boolean isImmutable(ReadGraphImpl graph) { - return graph.processor.isImmutable(r1()); - } + @Override + public int type() { + return RequestFlags.IMMEDIATE_UPDATE; + } + + @Override + boolean isImmutable(ReadGraphImpl graph) { + return graph.processor.isImmutable(r1()); + } @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java index 6345b7375..6d9560940 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/QueryProcessor.java @@ -4054,6 +4054,10 @@ final public class QueryProcessor extends AbstractDisposable implements ReadGrap return L0; } + public Layer0 getL0() { + return L0; + } + public static ThreadLocal thread = new ThreadLocal() { protected Integer initialValue() { return -1; diff --git a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java index 6652f1b6b..218777413 100644 --- a/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java +++ b/bundles/org.simantics.db.impl/src/org/simantics/db/impl/query/Statements.java @@ -11,8 +11,6 @@ *******************************************************************************/ package org.simantics.db.impl.query; -import java.util.concurrent.atomic.AtomicBoolean; - import org.simantics.db.RelationInfo; import org.simantics.db.common.exception.DebugException; import org.simantics.db.exception.DatabaseException; @@ -24,93 +22,93 @@ import org.simantics.db.procedure.ListenerBase; import org.simantics.db.request.RequestFlags; public final class Statements extends CollectionBinaryQuery implements TripleIntProcedure { - + public Statements(final int r1, final int r2) { super(r1, r2); } - + final public static void queryEach(ReadGraphImpl graph, final int r1, final int r2, final QueryProcessor provider, final CacheEntry parent, final ListenerBase listener, final TripleIntProcedure procedure) throws DatabaseException { - - assert(r1 != 0); - assert(r2 != 0); - + + assert(r1 != 0); + assert(r2 != 0); + if(parent == null && listener == null) { - Statements.computeForEach(graph, r1, r2, null, procedure); - return; + Statements.computeForEach(graph, r1, r2, null, procedure); + return; } - + QueryCache.runnerStatements(graph, r1, r2, parent, listener, procedure); - + } - @Override - final public void removeEntry(QueryProcessor provider) { + @Override + final public void removeEntry(QueryProcessor provider) { provider.cache.remove(this); - } - + } + final static TripleIntProcedure NOPT = new TripleIntProcedure() { - @Override - public void exception(ReadGraphImpl graph, Throwable throwable) { - } + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } - @Override - public void execute(ReadGraphImpl graph, int s, int p, int o) { - } + @Override + public void execute(ReadGraphImpl graph, int s, int p, int o) { + } + + @Override + public void finished(ReadGraphImpl graph) { + } - @Override - public void finished(ReadGraphImpl graph) { - } - }; - + final static private IntArray getAssertionMap(ReadGraphImpl graph, final int r1, final int r2, final Statements entry) throws DatabaseException { - + class AssertionMapProc implements IntProcedure { - - boolean first = true; - - private IntArray result; - - public void addStatement(int s, int p, int o) { - - if(result.size() == 0) { - result.add(s); - result.add(p); - result.add(o); - } else { - for(int i = 0;i < result.sizeOrData ; i+=3) { - int existingP = result.data[i+1]; - if(p == existingP) { - int existingO = result.data[i+2]; - if(existingO == o) return; - } - } - result.add(s); - result.add(p); - result.add(o); - } - - } - + + boolean first = true; + + private IntArray result; + + public void addStatement(int s, int p, int o) { + + if(result.size() == 0) { + result.add(s); + result.add(p); + result.add(o); + } else { + for(int i = 0;i < result.sizeOrData ; i+=3) { + int existingP = result.data[i+1]; + if(p == existingP) { + int existingO = result.data[i+2]; + if(existingO == o) return; + } + } + result.add(s); + result.add(p); + result.add(o); + } + + } + @Override public void execute(ReadGraphImpl graph, int type) throws DatabaseException { if(result == null) { - result = QueryCache.resultAssertedStatements(graph, type, r2, entry, null); + result = QueryCache.resultAssertedStatements(graph, type, r2, entry, null); } else { - if (first) { - IntArray ia = result; - result = new IntArray(); - if(ia.data != null) { - for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); - } - first = false; - } - IntArray ia = QueryCache.resultAssertedStatements(graph, type, r2, entry, null); - if(ia.data != null) { - for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); - } + if (first) { + IntArray ia = result; + result = new IntArray(); + if(ia.data != null) { + for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); + } + first = false; + } + IntArray ia = QueryCache.resultAssertedStatements(graph, type, r2, entry, null); + if(ia.data != null) { + for(int i = 0;i < ia.sizeOrData ; i+=3) addStatement(ia.data[i],ia.data[i+1],ia.data[i+2]); + } } } @@ -118,322 +116,336 @@ public final class Statements extends CollectionBinaryQuery public void finished(ReadGraphImpl graph) { } - @Override - public void exception(ReadGraphImpl graph, Throwable throwable) { - } + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } } - + AssertionMapProc amp = new AssertionMapProc(); // This dependency could be cut QueryCache.runnerPrincipalTypes(graph, r1, entry, null, amp); - + return amp.result; - + } - + final static private void forSingleAssertion(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final TripleIntProcedure procedure) throws DatabaseException { - - IntArray map = getAssertionMap(graph, r1, r2, parent); - if(map == null) { - procedure.finished(graph); + + IntArray map = getAssertionMap(graph, r1, r2, parent); + if(map == null) { + procedure.finished(graph); return; - } - + } + int size = map.size(); if(size == 3) { - int s = map.data[0]; - int p = map.data[1]; - int o = map.data[2]; - - procedure.execute(graph, s,p,o); - procedure.finished(graph); + int s = map.data[0]; + int p = map.data[1]; + int o = map.data[2]; + + procedure.execute(graph, s,p,o); + procedure.finished(graph); } else if(size == 0) { - procedure.finished(graph); - + procedure.finished(graph); + } else { - int candidateS = map.data[0]; - int candidateP = map.data[1]; - int candidateO = map.data[2]; - - IntSet candidateIs = null; - try { - candidateIs = QueryCache.resultSuperTypes(graph, candidateS, parent, null); - } catch (DatabaseException e) { - procedure.exception(graph, e); - return; - } - - for(int i=3;i ignore next - - } else { - - IntSet nextIs = null; - try { - nextIs = QueryCache.resultSuperTypes(graph, nextS, parent, null); - } catch (DatabaseException e) { - procedure.exception(graph, e); - return; - } - - if(nextIs.contains(candidateS)) { - - // Candidate is a super type of next => next is the new candidate - - candidateS = nextS; - candidateP = nextP; - candidateO = nextO; - candidateIs = nextIs; - - } else { - // candidate and next are unrelated => error - ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has conflicting assertions.", r1); - procedure.exception(graph, exception); - return; - } - - } - - } - - } - + int candidateS = map.data[0]; + int candidateP = map.data[1]; + int candidateO = map.data[2]; + + IntSet candidateIs = null; + try { + candidateIs = QueryCache.resultSuperTypes(graph, candidateS, parent, null); + } catch (DatabaseException e) { + procedure.exception(graph, e); + return; + } + + for(int i=3;i ignore next + + } else { + + IntSet nextIs = null; + try { + nextIs = QueryCache.resultSuperTypes(graph, nextS, parent, null); + } catch (DatabaseException e) { + procedure.exception(graph, e); + return; + } + + if(nextIs.contains(candidateS)) { + + // Candidate is a super type of next => next is the new candidate + + candidateS = nextS; + candidateP = nextP; + candidateO = nextO; + candidateIs = nextIs; + + } else { + // candidate and next are unrelated => error + ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has conflicting assertions.", r1); + procedure.exception(graph, exception); + return; + } + + } + + } + + } + procedure.execute(graph, candidateS, candidateP, candidateO); procedure.finished(graph); - + } - + } - + final static InternalProcedure NOP = new InternalProcedure() { - @Override - public void execute(ReadGraphImpl graph, IntSet result) { - } + @Override + public void execute(ReadGraphImpl graph, IntSet result) { + } + + @Override + public void exception(ReadGraphImpl graph, Throwable throwable) { + } - @Override - public void exception(ReadGraphImpl graph, Throwable throwable) { - } - }; - - // Search for one statement - final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final RelationInfo ri, final TripleIntProcedure procedure) throws DatabaseException { - + + // Search for one statement + final static public void computeFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final RelationInfo ri, final TripleIntProcedure procedure) throws DatabaseException { + if(ri.isFinal) { - - int result = graph.processor.querySupport.getFunctionalObject(r1, r2); - if(result == 0) { + int result = graph.processor.querySupport.getFunctionalObject(r1, r2); - // Check for assertions - forSingleAssertion(graph, r1, r2, parent, procedure); + if(result == 0) { - } else if(result == -1) { + // Check for assertions + forSingleAssertion(graph, r1, r2, parent, procedure); - graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { + } else if(result == -1) { + + graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { + + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + procedure.execute(graph, r1, r2, i); + } - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - procedure.execute(graph, r1, r2, i); - } + @Override + public void exception(ReadGraphImpl graph, Throwable t) { + if(DebugException.DEBUG) new DebugException(t).printStackTrace(); + } - @Override - public void exception(ReadGraphImpl graph, Throwable t) { - if(DebugException.DEBUG) new DebugException(t).printStackTrace(); - } + @Override + public void finished(ReadGraphImpl graph) { + } - @Override - public void finished(ReadGraphImpl graph) { - } + }); - }); + // Check for assertions + forSingleAssertion(graph, r1, r2, parent, procedure); - // Check for assertions - forSingleAssertion(graph, r1, r2, parent, procedure); - - } else { + } else { - // If functional relation was found there is no need to check assertions + // If functional relation was found there is no need to check assertions procedure.execute(graph, r1, r2, result); procedure.finished(graph); - - } - + } + + } else { - - final AtomicBoolean found = new AtomicBoolean(false); - + // Note! The dependency is intentionally cut! IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null); direct.forEach(graph, new SyncIntProcedure() { - + + /* + * 0 = not found + * 1 = found + * 2 = exception + */ + int found = 0; + @Override public void run(ReadGraphImpl graph) throws DatabaseException { - - if(found.get()) { - procedure.finished(graph); - } else { + + if(found == 1) { + + procedure.finished(graph); + + } else if(found == 0) { + // Check for assertions forSingleAssertion(graph, r1, r2, parent, procedure); + } - + } @Override public void execute(ReadGraphImpl graph, final int pred) throws DatabaseException { - - if(found.get()) return; + + if(found > 0) + return; if(pred == r2) { - - inc(); - + // Note! The dependency is intentionally cut! QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - - if(found.compareAndSet(false, true)) { + + if(found == 0) { + procedure.execute(graph, r1, pred, i); - } else { - ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1); - procedure.exception(graph, exception); - } + found = 1; + + } else { + + ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1); + procedure.exception(graph, exception); + found = 2; + + } } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); } - - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - dec(graph); - } + + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + + procedure.exception(graph, t); + found = 2; + + } }); } else { - - inc(); - + QueryCache.runnerSuperRelations(graph, pred, parent, null, new InternalProcedure() { - + @Override public void execute(ReadGraphImpl graph, IntSet result) throws DatabaseException { - - if(found.get()) { - dec(graph); + + if(found > 0) return; - } if(result.contains(r2)) { - + inc(); - + // Note! The dependency is intentionally cut! QueryCache.runnerDirectObjects(graph, r1, pred, null, null, new IntProcedure() { - + @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - - if(found.compareAndSet(false, true)) { - procedure.execute(graph, r1, pred, i); - } else { - ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement.", r1); - procedure.exception(graph, exception); - } - + + if(found == 0) { + + procedure.execute(graph, r1, pred, i); + found = 1; + + } else { + + ManyObjectsForFunctionalRelationException exception = new ManyObjectsForFunctionalRelationException("Functional relation has more than one statement (r1=" + r1 + ", r2=" + r2 + ").", r1); + procedure.exception(graph, exception); + found = 2; + + } + } - + @Override public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); } - - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - dec(graph); - } + + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + procedure.exception(graph, t); + found = 2; + } }); - + } - - dec(graph); - + + } + + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + procedure.exception(graph, t); + found = 2; } - - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - dec(graph); - } }); - + } - + } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { dec(graph); } - + }); - + } - } - + } + final static private void forAssertions(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final TripleIntProcedure procedure) throws DatabaseException { - QueryCache.runnerPrincipalTypes(graph, r1, parent, null, new SyncIntProcedure() { - + QueryCache.runnerPrincipalTypes(graph, r1, parent, null, new SyncIntProcedure() { + @Override public void run(ReadGraphImpl graph) throws DatabaseException { procedure.finished(graph); } - + TripleIntProcedure proc = new TripleIntProcedureAdapter() { @Override public void execute(ReadGraphImpl graph, int s, int p, int o) throws DatabaseException { - procedure.execute(graph, s, p, o); + procedure.execute(graph, s, p, o); } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { dec(graph); } - - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { dec(graph); - procedure.exception(graph, t); - } + procedure.exception(graph, t); + } }; @@ -442,57 +454,57 @@ public final class Statements extends CollectionBinaryQuery inc(); QueryCache.runnerAssertedStatements(graph, type, r2, parent, null, proc); } - + @Override public void finished(ReadGraphImpl graph) throws DatabaseException { dec(graph); } - + @Override public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { dec(graph); } - + }); - + } - final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final RelationInfo ri, final TripleIntProcedure procedure) throws DatabaseException { + final static public void computeNotFunctionalIndex(ReadGraphImpl graph, final int r1, final int r2, final Statements parent, final RelationInfo ri, final TripleIntProcedure procedure) throws DatabaseException { - if(ri.isFinal) { + if(ri.isFinal) { - graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { + graph.processor.querySupport.getObjects(graph, r1, r2, new IntProcedure() { - @Override - public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - procedure.execute(graph, r1, r2, i); - } + @Override + public void execute(ReadGraphImpl graph, int i) throws DatabaseException { + procedure.execute(graph, r1, r2, i); + } - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - if(DebugException.DEBUG) new DebugException(t).printStackTrace(); - procedure.exception(graph, t); - } + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + if(DebugException.DEBUG) new DebugException(t).printStackTrace(); + procedure.exception(graph, t); + } - @Override - public void finished(ReadGraphImpl graph) { - } + @Override + public void finished(ReadGraphImpl graph) { + } - }); + }); - if(ri.isAsserted) { - forAssertions(graph, r1, r2, parent, procedure); - } else { - procedure.finished(graph); - } + if(ri.isAsserted) { + forAssertions(graph, r1, r2, parent, procedure); + } else { + procedure.finished(graph); + } } else { // Note! The dependency is intentionally cut! IntSet direct = QueryCache.resultDirectPredicates(graph, r1, null, null); direct.forEach(graph, new SyncIntProcedure() { - + @Override public void run(ReadGraphImpl graph) throws DatabaseException { forAssertions(graph, r1, r2, parent, procedure); @@ -502,36 +514,30 @@ public final class Statements extends CollectionBinaryQuery public void execute(ReadGraphImpl graph, final int pred2) throws DatabaseException { if(pred2 == r2) { - - inc(); - + // Note! The dependency is intentionally cut! QueryCache.runnerDirectObjects(graph, r1, pred2, null, null, new IntProcedure() { @Override public void execute(ReadGraphImpl graph, int i) throws DatabaseException { - procedure.execute(graph, r1, pred2, i); + procedure.execute(graph, r1, pred2, i); } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { - dec(graph); } - - @Override - public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { - procedure.exception(graph, t); - dec(graph); - } + + @Override + public void exception(ReadGraphImpl graph, Throwable t) throws DatabaseException { + procedure.exception(graph, t); + } }); } else { - -// inc(); try { - + IntSet result = QueryCache.resultSuperRelations(graph, pred2, parent, null); if(result.contains(r2)) { @@ -560,30 +566,30 @@ public final class Statements extends CollectionBinaryQuery }); } - + } catch (Throwable e) { procedure.exception(graph, e); } } - + } @Override public void finished(ReadGraphImpl graph) throws DatabaseException { dec(graph); } - + }); - + } - + } - + public static void computeForEach(ReadGraphImpl graph, final int r1, final int r2, final Statements entry, final TripleIntProcedure procedure_) throws DatabaseException { - + TripleIntProcedure procedure = entry != null ? entry : procedure_; - + RelationInfo ri = QueryCache.resultRelationInfoQuery(graph, r2, entry, null); graph.ensureLoaded(r1, r2); if(ri.isFunctional) { @@ -593,16 +599,16 @@ public final class Statements extends CollectionBinaryQuery } if(entry != null) entry.performFromCache(graph, procedure_); - + } - + @Override public String toString() { - return "Statements[" + r1() + " - " + r2() + "]"; + return "Statements[" + r1() + " - " + r2() + "]"; } final private void finish(ReadGraphImpl graph, TripleIntProcedure procedure) throws DatabaseException { - + assert(assertPending()); synchronized(this) { @@ -614,95 +620,95 @@ public final class Statements extends CollectionBinaryQuery final IntArray value = (IntArray)getResult(); for(int i=0;i>>32); } - + final static public int r2(long id) { return (int)id; } - + final public void addOrSetFunctional(int s, long po) { - - addOrSetFunctional(s, r1(po), r2(po)); - + + addOrSetFunctional(s, r1(po), r2(po)); + } final public void addOrSetFunctional(int s, int p, int o) { - - assert(assertPending()); - - IntArray value = (IntArray)getResult(); + + assert(assertPending()); + + IntArray value = (IntArray)getResult(); value.add(s); value.add(p); value.add(o); - + } - + @Override public Object performFromCache(ReadGraphImpl graph, final TripleIntProcedure procedure) throws DatabaseException { - assert(isReady()); + assert(isReady()); final IntArray value = (IntArray)getResult(); - if(handleException(graph, procedure)) return value; - + if(handleException(graph, procedure)) return value; + for(int i=0;i public void exception(ReadGraphImpl graph, Throwable throwable) throws DatabaseException { except(throwable); } - + } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java index 517ce761e..6ad6315b9 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/adapter/ContextualRelatedValue.java @@ -27,41 +27,43 @@ import org.simantics.scl.runtime.function.FunctionImpl3; */ public abstract class ContextualRelatedValue implements ConverterComputationalValue { - @SuppressWarnings("unchecked") - @Override - public T getValue(ReadGraph graph, Resource resource) throws DatabaseException { - return (T) new FunctionImpl3() { - @Override - public Object apply(ReadGraph graph, Resource converter, Object context) { - SCLContext sclContext = SCLContext.getCurrent(); - Object oldGraph = sclContext.get("graph"); - try { - if (context instanceof Variable) { - Variable variable = (Variable)context; - try { - Function1 fn = getFunction(graph, variable.getParent(graph).getRepresents(graph), variable.getRepresents(graph), variable.getPredicateResource(graph)); - sclContext.put("graph", graph); - return fn.apply(variable); - } catch (DatabaseException e) { - throw new RuntimeDatabaseException(e); - } - } if (context instanceof Resource) { - Resource resource = (Resource)context; - try { - // Here converter is the object and context is the subject - Function1 fn = getFunction(graph, resource, converter, null); - return fn.apply(resource); - } catch (DatabaseException e) { - throw new RuntimeDatabaseException(e); - } - } else { - throw new IllegalStateException("Unknown context " + context); + private final FunctionImpl3 function = new FunctionImpl3() { + @Override + public Object apply(ReadGraph graph, Resource converter, Object context) { + SCLContext sclContext = SCLContext.getCurrent(); + Object oldGraph = sclContext.get("graph"); + try { + if (context instanceof Variable) { + Variable variable = (Variable)context; + try { + Function1 fn = getFunction(graph, variable.getParent(graph).getRepresents(graph), variable.getRepresents(graph), variable.getPredicateResource(graph)); + sclContext.put("graph", graph); + return fn.apply(variable); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); + } + } if (context instanceof Resource) { + Resource resource = (Resource)context; + try { + // Here converter is the object and context is the subject + Function1 fn = getFunction(graph, resource, converter, null); + return fn.apply(resource); + } catch (DatabaseException e) { + throw new RuntimeDatabaseException(e); } - } finally { - sclContext.put("graph", oldGraph); + } else { + throw new IllegalStateException("Unknown context " + context); } + } finally { + sclContext.put("graph", oldGraph); } - }; + } + }; + + @SuppressWarnings("unchecked") + @Override + public T getValue(ReadGraph graph, Resource resource) throws DatabaseException { + return (T) function; } } diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java index 4e775e08a..f52148c2a 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/function/All.java @@ -139,7 +139,7 @@ public class All { return graph.getValue2(object, variable); } else { for (Pair assertion : assertions.values()) { - if (assertion.first.predicate.equals(variable.property.predicate)) { + if (assertion.first.predicate.equals(variable.getPossiblePredicateResource(graph))) { return graph.getValue2(assertion.second, variable); } } @@ -201,7 +201,7 @@ public class All { return graph.getValue2(object, variable, binding); } else { for (Pair assertion : assertions.values()) { - if (assertion.first.predicate.equals(variable.property.predicate)) { + if (assertion.first.predicate.equals(variable.getPossiblePredicateResource(graph))) { return graph.getValue2(assertion.second, variable, binding); } } @@ -1164,8 +1164,11 @@ public class All { if(property instanceof StandardGraphPropertyVariable) { StandardGraphPropertyVariable variable = (StandardGraphPropertyVariable)property; if (variable.parentResource != null) { - Statement stm = graph.getPossibleStatement(variable.parentResource, variable.property.predicate); - return stm != null && stm.isAsserted(variable.parentResource); + Resource predicate = variable.getPossiblePredicateResource(graph); + if (predicate != null) { + Statement stm = graph.getPossibleStatement(variable.parentResource, predicate); + return stm != null && stm.isAsserted(variable.parentResource); + } } } return Boolean.FALSE; @@ -1313,7 +1316,7 @@ public class All { throw new InvalidVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ")."); try { - return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable); + return graph.getRelatedValue2(variable.parentResource, variable.getPredicateResource(graph), variable); } catch (NoSingleResultException e) { throw new MissingVariableValueException(variable.getPossibleURI(graph), e); } catch (DoesNotContainValueException e) { @@ -1334,9 +1337,10 @@ public class All { if (variable.parentResource == null) throw new MissingVariableException("Variable is not represented by any resource (URI=" + variable.getPossibleURI(graph) + ").", context.getPossibleRepresents(graph)); + try { - return graph.getRelatedValue2(variable.parentResource, variable.property.predicate, variable); + return graph.getRelatedValue2(variable.parentResource, variable.getPredicateResource(graph), variable); } catch (NoSingleResultException e) { throw new MissingVariableValueException(variable.getPossibleURI(graph), e); } catch (DoesNotContainValueException e) { diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java index 830f7a6bb..ad8676f81 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java @@ -1202,6 +1202,10 @@ public class Layer0Utils { } + public static boolean isMarkedReadOnly(ReadGraph graph, Resource r) throws DatabaseException { + return Boolean.TRUE.equals( graph.getPossibleRelatedValue(r, graph.l0().readOnly, Bindings.BOOLEAN) ); + } + private static TransferableGraph1 makeTG(ReadGraph graph, Resource r) throws DatabaseException { SimanticsClipboardImpl cp = new SimanticsClipboardImpl(); diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java new file mode 100644 index 000000000..a1b74638f --- /dev/null +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/NoPredicateResourceException.java @@ -0,0 +1,34 @@ +package org.simantics.db.layer0.variable; + +import org.simantics.db.Resource; +import org.simantics.db.exception.AssumptionException; + +public class NoPredicateResourceException extends AssumptionException { + + private static final long serialVersionUID = -374051341908276908L; + + public NoPredicateResourceException(Throwable cause) { + super(cause); + } + + public NoPredicateResourceException(String message, Throwable cause, Resource... rs) { + super(message, cause, rs); + } + + public NoPredicateResourceException(String message, Resource... resources) { + super(message, resources); + } + + public NoPredicateResourceException(String message, Throwable cause) { + super(message, cause); + } + + public NoPredicateResourceException(String message, int... args) { + super(message, args); + } + + public NoPredicateResourceException(String message) { + super(message); + } + +} diff --git a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java index b7eaf075e..c9214e398 100644 --- a/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java +++ b/bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/variable/StandardGraphPropertyVariable.java @@ -21,6 +21,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.DatatypeNotFoundException; import org.simantics.db.exception.ValidationException; import org.simantics.db.layer0.exception.InvalidVariableException; +import org.simantics.db.layer0.exception.MissingVariableException; import org.simantics.db.layer0.exception.MissingVariableValueException; import org.simantics.db.layer0.exception.PendingVariableException; import org.simantics.db.layer0.function.All; @@ -100,11 +101,15 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { @Override public String getPossibleLabel(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + return null; return graph.getPossibleRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING); } @Override public String getLabel(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + throw new NoPredicateResourceException("No predicate resource for property " + getName(graph)); return graph.getRelatedValue2(property.predicate, graph.getService(Layer0.class).HasLabel, parent, Bindings.STRING); } @@ -124,10 +129,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -145,10 +152,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -183,10 +192,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -200,10 +211,12 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { if(Development.DEVELOPMENT) { if(Development.getProperty(DevelopmentKeys.L0_VALIDATION, Bindings.BOOLEAN)) { - String error = L0Validations.checkValueType(graph, parentResource, property.predicate); - if(error != null) { - LOGGER.error(error); - throw new ValidationException(error); + if (property.predicate != null) { + String error = L0Validations.checkValueType(graph, parentResource, property.predicate); + if(error != null) { + LOGGER.error(error); + throw new ValidationException(error); + } } } } @@ -324,11 +337,15 @@ public class StandardGraphPropertyVariable extends AbstractPropertyVariable { @Override public Variable getPredicate(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + throw new MissingVariableException("No predicate for property " + getName(graph)); return Variables.getVariable(graph, graph.getURI(property.predicate)); } @Override public Resource getPredicateResource(ReadGraph graph) throws DatabaseException { + if (property.predicate == null) + throw new NoPredicateResourceException("No predicate for property " + getName(graph)); return property.predicate; } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java index 92c5e9dda..0178e805f 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplDb.java @@ -18,7 +18,6 @@ import org.simantics.db.SessionManager; import org.simantics.db.SessionReference; import org.simantics.db.VirtualGraph; import org.simantics.db.authentication.UserAuthenticationAgent; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InvalidAuthenticationException; import org.simantics.db.exception.InvalidUserException; @@ -30,9 +29,13 @@ import org.simantics.db.impl.graph.WriteSupport; import org.simantics.db.impl.query.QueryProcessor; import org.simantics.db.impl.query.QuerySupport; import org.simantics.db.service.ServerInformation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; final public class SessionImplDb extends SessionImplSocket { + private static final Logger LOGGER = LoggerFactory.getLogger(SessionImplDb.class); + /** * Cached ServerInformation structure fetched from the server at connection * time. It should never change during a single session and therefore it @@ -58,7 +61,7 @@ final public class SessionImplDb extends SessionImplSocket { try { newId = cluster.createResource(clusterTranslator); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("createResource failed", e); return null; } return new ResourceImpl(resourceSupport, newId); @@ -114,8 +117,7 @@ final public class SessionImplDb extends SessionImplSocket { // clusterTable.dispose(); clusterTable = null; // throw e; } catch (Throwable e) { - e.printStackTrace(); - Logger.defaultLogError("Unhandled error. See exception for details.", e); + LOGGER.error("Unhandled error. See exception for details.", e); graphSession = null; clusterTable.dispose(); clusterTable = null; throw new Exception(e); diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java index f8fd7d17d..29c70445b 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java @@ -328,7 +328,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule try { getClusterTable().refresh(csid, this, clusterUID); } catch (Throwable t) { - Logger.defaultLogError("Refesh failed.", t); + LOGGER.error("refresh({}, {}) failed", thread, csid, t); } } @@ -468,7 +468,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule assert (null != writer); } catch (Throwable t) { if (!(t instanceof CancelTransactionException)) - Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", t); + LOGGER.error("Write transaction caused an unexpected error, see exception.", t); writeState.except(t); } finally { writer.asyncBarrier.dec(); @@ -482,7 +482,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule // Log it first, just to be safe that the error is always logged. if (!(e instanceof CancelTransactionException)) - Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", e); + LOGGER.error("Write transaction caused an unexpected error, see exception.", e); // writeState.getGraph().state.barrier.dec(); // writeState.getGraph().waitAsync(request); @@ -626,7 +626,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if (t instanceof DatabaseException) callback.accept((DatabaseException) t); else callback.accept(new DatabaseException(t)); } else - Logger.defaultLogError("Unhandled exception", t); + LOGGER.error("Unhandled exception", t); } }; @@ -1324,7 +1324,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule callback.exception(new DatabaseException(e)); state.stopWriteTransaction(clusterStream); - Logger.defaultLogError("Write transaction caused an unexpected error, see exception.", e); + LOGGER.error("Write transaction caused an unexpected error, see exception.", e); } finally { @@ -1530,7 +1530,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if(throwable != null) { throwable.set(th); } else { - Logger.defaultLogError("Unhandled exception", th); + LOGGER.error("Unhandled exception", th); } } @@ -1543,7 +1543,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if(throwable != null) { throwable.set(t); } else { - Logger.defaultLogError("Unhandled exception", t); + LOGGER.error("Unhandled exception", t); } try { @@ -1555,7 +1555,7 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule if(throwable != null) { throwable.set(t2); } else { - Logger.defaultLogError("Unhandled exception", t2); + LOGGER.error("Unhandled exception", t2); } } @@ -2511,39 +2511,41 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule */ @SuppressWarnings("unchecked") @Override - public synchronized T peekService(Class api) { - - if(serviceKey1 == api) { - return (T)service1; - } else if (serviceKey2 == api) { - // Promote this key - Object result = service2; - service2 = service1; - serviceKey2 = serviceKey1; - service1 = result; - serviceKey1 = api; - return (T)result; - } + public T peekService(Class api) { + if (Layer0.class == api) + return (T) L0; - if (Layer0.class == api) - return (T) L0; - if (ServerInformation.class == api) - return (T) getCachedServerInformation(); - else if (WriteGraphImpl.class == api) - return (T) writeState.getGraph(); - else if (ClusterBuilder.class == api) - return (T)new ClusterBuilderImpl(this, (WriteOnlySupport)writeState.getGraph().writeSupport); - else if (ClusterBuilderFactory.class == api) - return (T)new ClusterBuilderFactoryImpl(this); + synchronized (this) { + if (serviceKey1 == api) { + return (T) service1; + } + if (serviceKey2 == api) { + // Promote this key + Object result = service2; + service2 = service1; + serviceKey2 = serviceKey1; + service1 = result; + serviceKey1 = api; + return (T)result; + } - service2 = service1; - serviceKey2 = serviceKey1; + if (ServerInformation.class == api) + return (T) getCachedServerInformation(); + else if (WriteGraphImpl.class == api) + return (T) writeState.getGraph(); + else if (ClusterBuilder.class == api) + return (T)new ClusterBuilderImpl(this, (WriteOnlySupport)writeState.getGraph().writeSupport); + else if (ClusterBuilderFactory.class == api) + return (T)new ClusterBuilderFactoryImpl(this); - service1 = serviceLocator.peekService(api); - serviceKey1 = api; + service2 = service1; + serviceKey2 = serviceKey1; - return (T)service1; + service1 = serviceLocator.peekService(api); + serviceKey1 = api; + return (T)service1; + } } /* @@ -2590,9 +2592,9 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule try { h.valuesChanged(ctx); } catch (Exception e) { - Logger.defaultLogError("monitor handler notification produced the following exception", e); + LOGGER.error("monitor handler notification produced the following exception", e); } catch (LinkageError e) { - Logger.defaultLogError("monitor handler notification produced a linkage error", e); + LOGGER.error("monitor handler notification produced a linkage error", e); } } } @@ -3579,4 +3581,10 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule state.setCombine(false); } + @SuppressWarnings("unchecked") + @Override + public T l0() { + return (T) L0; + } + } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java index 50184528e..d90f2c3a5 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplVirtual.java @@ -16,7 +16,6 @@ import java.io.IOException; import org.simantics.db.ServerI; import org.simantics.db.VirtualGraph; import org.simantics.db.authentication.UserAuthenticationAgent; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.InvalidAuthenticationException; import org.simantics.db.exception.InvalidUserException; @@ -24,6 +23,8 @@ import org.simantics.db.impl.ResourceImpl; import org.simantics.db.impl.VirtualGraphImpl; import org.simantics.db.impl.query.QueryProcessor; import org.simantics.db.service.ServerInformation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import fi.vtt.simantics.procore.BackdoorAuthenticator; import fi.vtt.simantics.procore.ProCoreServerReference; @@ -31,6 +32,9 @@ import fi.vtt.simantics.procore.ProCoreSessionReference; import fi.vtt.simantics.procore.SessionManagerSource; public class SessionImplVirtual extends SessionImplSocket { + + private static final Logger LOGGER = LoggerFactory.getLogger(SessionImplVirtual.class); + protected VirtualGraphImpl virtualGraphImpl; public SessionImplVirtual(UserAuthenticationAgent authAgent) throws DatabaseException { @@ -75,12 +79,11 @@ public class SessionImplVirtual extends SessionImplSocket { } catch (InvalidUserException e) { throw e; } catch (IOException e) { - Logger.defaultLogError("I/O error. See exception for details.", e); + LOGGER.error("I/O error. See exception for details.", e); graphSession = null; throw new DatabaseException(e); } catch (Throwable e) { - e.printStackTrace(); - Logger.defaultLogError("Unhandled error. See exception for details.", e); + LOGGER.error("Unhandled error. See exception for details.", e); graphSession = null; throw new DatabaseException(e); } @@ -108,7 +111,7 @@ public class SessionImplVirtual extends SessionImplSocket { try { return gs.getServerInformation(); } catch (DatabaseException e) { - Logger.defaultLogError("Failed to get server info.", e); + LOGGER.error("Failed to get server info.", e); return null; } } diff --git a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java index ea4319ace..247df4645 100644 --- a/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java +++ b/bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/WriteSupportImpl.java @@ -8,7 +8,6 @@ import org.simantics.db.VirtualGraph; import org.simantics.db.WriteGraph; import org.simantics.db.common.MetadataUtils; import org.simantics.db.common.exception.DebugException; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.exception.ImmutableException; import org.simantics.db.exception.ServiceException; @@ -28,9 +27,13 @@ import org.simantics.db.request.WriteOnly; import org.simantics.db.request.WriteResult; import org.simantics.db.request.WriteTraits; import org.simantics.db.service.ByteReader; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class WriteSupportImpl implements WriteSupport { + private static final Logger LOGGER = LoggerFactory.getLogger(WriteSupportImpl.class); + final private SessionImplSocket session; final private QueryProcessor queryProcessor; final private State state; @@ -122,7 +125,7 @@ public class WriteSupportImpl implements WriteSupport { try { addSetValue(((ResourceImpl) resource).id, value, value.length); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("writeOnly setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e); } } } else { @@ -134,7 +137,7 @@ public class WriteSupportImpl implements WriteSupport { try { addSetValue(((ResourceImpl) resource).id, value, value.length); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("setValue({}, {}, byte[{}]) failed", provider, resource, value.length, e); } } queryProcessor.releaseWrite(session.writeState.getGraph()); @@ -199,7 +202,7 @@ public class WriteSupportImpl implements WriteSupport { try { cluster.removeValue(key, session.clusterTranslator); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("denyValue({}, {}) failed", provider, resource, e); return; } queryProcessor.updateValue(key); @@ -460,7 +463,7 @@ public class WriteSupportImpl implements WriteSupport { if (null != c && c != cluster) session.clusterTable.replaceCluster(c); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("claimImpl({}, {}, {}) failed", subject, predicate, object, e); throw new RuntimeException(e); } queryProcessor.updateStatements(subject, predicate); @@ -480,7 +483,7 @@ public class WriteSupportImpl implements WriteSupport { if (null != c && c != cluster) session.clusterTable.replaceCluster(c); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("claimImpl2({}, {}, {}) failed", subject, predicate, object, e); } if (cluster.isWriteOnly()) return; @@ -504,7 +507,7 @@ public class WriteSupportImpl implements WriteSupport { try { cluster.denyRelation(subject, predicate, object, session.clusterTranslator); } catch (DatabaseException e) { - Logger.defaultLogError(e); + LOGGER.error("removeStatement({}, {}, {}) failed", subject, predicate, object, e); return false; } queryProcessor.updateStatements(subject, predicate); diff --git a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java index 5e818cb99..924ccffb0 100644 --- a/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java +++ b/bundles/org.simantics.db/src/org/simantics/db/RequestProcessor.java @@ -62,7 +62,7 @@ import org.simantics.db.request.WriteInterface; * @see MergingGraphRequestProcessor * @see AsyncRequestProcessor */ -public interface RequestProcessor extends RequestProcessorSpecific, ServiceLocator { +public interface RequestProcessor extends RequestProcessorSpecific, ServiceLocator, ResourceLocator { Resource getRootLibrary(); diff --git a/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java b/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java new file mode 100644 index 000000000..8a8b0fa48 --- /dev/null +++ b/bundles/org.simantics.db/src/org/simantics/db/ResourceLocator.java @@ -0,0 +1,29 @@ +/******************************************************************************* + * Copyright (c) 2020 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.db; + +/** + * @author Tuukka Lehtonen + * @since 1.43.0 + */ +public interface ResourceLocator { + + /** + * Layer0 is an integral part of Simantics database modelling and for performance + * reasons deserves simplest possible access to its resource class. + * + * @return returns the internally cached + * org.simantics.layer0.Layer0 instance + */ + public T l0(); + +} diff --git a/bundles/org.simantics.debug.graphical/META-INF/MANIFEST.MF b/bundles/org.simantics.debug.graphical/META-INF/MANIFEST.MF index 696289911..559b01350 100644 --- a/bundles/org.simantics.debug.graphical/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.debug.graphical/META-INF/MANIFEST.MF @@ -8,7 +8,7 @@ Require-Bundle: org.simantics.db;bundle-version="1.1.0", org.eclipse.core.runtime;bundle-version="3.6.0", org.eclipse.ui;bundle-version="3.6.0", org.simantics.ui;bundle-version="1.0.0", - com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.8", + com.fasterxml.jackson.core.jackson-core;bundle-version="[2.8.11,2.9.0)", org.slf4j.api, - com.fasterxml.jackson.core.jackson-databind;bundle-version="2.8.8" + com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.8.11,2.9.0)" Automatic-Module-Name: org.simantics.debug.graphical diff --git a/bundles/org.simantics.desktop.product/splash.bmp b/bundles/org.simantics.desktop.product/splash.bmp index b5138f1e9..cb00fe832 100644 Binary files a/bundles/org.simantics.desktop.product/splash.bmp and b/bundles/org.simantics.desktop.product/splash.bmp differ diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java index a6a4f22d2..50d6c85d4 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/RouteLine.java @@ -113,10 +113,17 @@ public class RouteLine implements RouteNode, Serializable { out.print(" HOR"); else out.print(" VER"); + if (hidden) + out.print(" HIDDEN"); + out.print(" @ " + position); for(RoutePoint point : points) { out.print(" ("+point.x+","+point.y+")"); } out.print(" (data=" + data + ")"); + if (nextTransient != null) + out.print(" (next transient line=" + nextTransient.getData() + ")"); + if (terminal != null) + out.print(" (terminal=" + terminal.getData() + ")"); out.println(); } diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java index b283cb4ed..4e4280c0a 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/segments/Segment.java @@ -28,4 +28,9 @@ public class Segment { public boolean isDegenerated() { return p1.getX() == p2.getX() && p1.getY() == p2.getY(); } + + @Override + public String toString() { + return String.format("(%f, %f) (%f, %f)", p1.getX(), p1.getY(), p2.getX(), p2.getY()); + } } diff --git a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java index ae79dc019..8f7f71a29 100644 --- a/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java +++ b/bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/splitting/SplittedRouteGraph.java @@ -1,13 +1,17 @@ package org.simantics.diagram.connection.splitting; -import gnu.trove.set.hash.THashSet; - +import java.awt.geom.Line2D; import java.awt.geom.Point2D; +import java.util.ArrayList; import org.simantics.diagram.connection.RouteGraph; import org.simantics.diagram.connection.RouteLine; import org.simantics.diagram.connection.RouteNode; +import org.simantics.diagram.connection.RoutePoint; import org.simantics.diagram.connection.RouteTerminal; +import org.simantics.diagram.connection.segments.Segment; + +import gnu.trove.set.hash.THashSet; public class SplittedRouteGraph { public final RouteLine splitLine; @@ -91,7 +95,75 @@ public class SplittedRouteGraph { } } - /** + public static final class PickResult { + /** + * The connection route line nearest to {@link #pickPoint}. + */ + public final RouteLine nearestLine; + /** + * Original pick point in canvas coordinates. + */ + public final Point2D pickPoint; + /** + * Intersection point in canvas coordinates of {@link #nearestLine} and + * perpendicular line from {@link #pickPoint} to {@link #nearestLine}. + */ + public final Point2D intersectionPoint; + + public PickResult(RouteLine nearestLine, Point2D pickPoint, Point2D intersectionPoint) { + this.nearestLine = nearestLine; + this.pickPoint = pickPoint; + this.intersectionPoint = intersectionPoint; + } + } + + public static PickResult pickNearestLine(RouteGraph rg, double x, double y) { + Segment nearestSegment = null; + RouteLine nearestLine = null; + + ArrayList segments = new ArrayList<>(); + double minDistanceSq = Double.MAX_VALUE; + for (RouteLine line : rg.getAllLines()) { + segments.clear(); + line.collectSegments(segments); + for (Segment segment : segments) { + RoutePoint p1 = segment.p1; + RoutePoint p2 = segment.p2; + double distanceSq = Line2D.ptSegDistSq(p1.getX(), p1.getY(), p2.getX(), p2.getY(), x, y); + if (distanceSq < minDistanceSq) { + minDistanceSq = distanceSq; + nearestSegment = segment; + nearestLine = line; + } + } + } + + if (nearestSegment == null) + return null; + + RoutePoint p1 = nearestSegment.p1; + RoutePoint p2 = nearestSegment.p2; + Point2D p = pointToLineIntersection(p1.getX(), p1.getY(), p2.getX(), p2.getY(), x, y); + return new PickResult(nearestLine, new Point2D.Double(x, y), p); + } + + private static Point2D pointToLineIntersection(double x1, double y1, double x2, double y2, double px, double py) { + double d = Math.pow(x2 - x1, 2.0) + Math.pow(y2 - y1, 2.0); + if (d == 0) { + return new Point2D.Double(x1, y1); + } else { + double u = ((px - x1) * (x2 - x1) + (py - y1) * (y2 - y1)) / d; + if (u > 1.0) { + return new Point2D.Double(x2, y2); + } else if (u <= 0.0) { + return new Point2D.Double(x1, y1); + } else { + return new Point2D.Double(x2 * u + x1 * (1.0-u), (y2 * u + y1 * (1.0- u))); + } + } + } + + /** * @param point * @param line * @return the specified point instance snapped to the specified line diff --git a/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/view/ActiveRuntimeDiagramInputSource.java b/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/view/ActiveRuntimeDiagramInputSource.java index fb07993ac..be0b062ad 100644 --- a/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/view/ActiveRuntimeDiagramInputSource.java +++ b/bundles/org.simantics.diagram.profile/src/org/simantics/diagram/profile/view/ActiveRuntimeDiagramInputSource.java @@ -37,6 +37,7 @@ import org.simantics.db.common.request.UniqueRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.management.ISessionContext; import org.simantics.db.procedure.Procedure; +import org.simantics.diagram.runtime.RuntimeDiagramManager; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.utils.ObjectUtils; import org.simantics.utils.ui.SWTUtils; @@ -170,7 +171,12 @@ public class ActiveRuntimeDiagramInputSource implements WorkbenchSessionContextI } protected void editorActivated(IEditorPart part) { - Resource resource = part.getAdapter(Resource.class); + RuntimeDiagramManager rdm = part.getAdapter(RuntimeDiagramManager.class); + Resource resource = null; + if (rdm != null) + resource = rdm.getRuntimeDiagram(); + if (resource == null) + resource = part.getAdapter(Resource.class); lastInputResource = resource; if (ownerIsVisible) { testAndChangeInput(resource); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GroupStyleProfileEntry.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GroupStyleProfileEntry.java index bdc3af02c..f38d1971b 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GroupStyleProfileEntry.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/GroupStyleProfileEntry.java @@ -44,6 +44,7 @@ public class GroupStyleProfileEntry implements ProfileEntry { else this.priority = 0; GroupStyleProfileEntry.this.style = graph.adapt(style, Style.class); + GroupStyleProfileEntry.this.style.setPriority(this.priority); GroupStyleProfileEntry.this.group = graph.adapt(group, Group.class); } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/export/ExportDiagramPdf.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/export/ExportDiagramPdf.java index 23cb9f970..25e72d984 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/export/ExportDiagramPdf.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/export/ExportDiagramPdf.java @@ -183,8 +183,14 @@ public class ExportDiagramPdf implements ExportClass { ThreadUtils.syncExec(workerThread, new Runnable() { @Override public void run() { - try { + try { cctx.getDefaultHintContext().setHint(Hints.KEY_PAGE_DESC, _marginaaliViiva); + if (!fitDiagramContentsToPageMargins) { + // Prevent PDF printing from drawing page borders if the + // print area is fitted directly to the page size. + // This avoids unwanted black half-visible edges. + cctx.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_PAGE, false); + } String bottomLabel = diagramName; if ( drawingTemplate != null && activeProfileEntries.contains(TMPL.DrawingTemplate) ) bottomLabel = null; diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java index d38a301da..e53f4b636 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/FlagUtil.java @@ -176,6 +176,17 @@ public final class FlagUtil { * @throws DatabaseException */ public static Resource join(WriteGraph g, Resource flag, Resource otherFlag) throws DatabaseException { + return join(g, flag, otherFlag, true); + } + + /** + * @param g + * @param flag + * @param otherFlag + * @return the created DIA.ConnectionJoin instance + * @throws DatabaseException + */ + public static Resource join(WriteGraph g, Resource flag, Resource otherFlag, boolean activateDiagramMapping) throws DatabaseException { DiagramResource DIA = DiagramResource.getInstance(g); StructuralResource2 STR = StructuralResource2.getInstance(g); Resource connectionJoin = g.newResource(); @@ -184,14 +195,24 @@ public final class FlagUtil { g.claim(connectionJoin, DIA.JoinsFlag, flag); g.claim(connectionJoin, DIA.JoinsFlag, otherFlag); - IActivationManager manager = g.getService(IActivationManager.class); - for(Resource diagram : OrderedSetUtils.getSubjects(g, flag)) - manager.activateOnce(g, diagram); - for(Resource diagram : OrderedSetUtils.getSubjects(g, otherFlag)) - manager.activateOnce(g, diagram); + if (activateDiagramMapping) { + activateMappingForParentDiagramsOf(g, flag, otherFlag); + } + return connectionJoin; } + public static void activateMappingForParentDiagramsOf(WriteGraph graph, Resource... elements) throws DatabaseException { + IActivationManager manager = graph.getService(IActivationManager.class); + Set diagrams = new HashSet<>(elements.length); + for (Resource e : elements) { + diagrams.addAll(OrderedSetUtils.getSubjects(graph, e)); + } + for (Resource diagram : diagrams) { + manager.activateOnce(graph, diagram); + } + } + public static void disconnectFlag(WriteGraph graph, Resource flag) throws DatabaseException { // Remove any :ConnectionJoin's this flag is joined by // if there's less than two flags joined by the join. @@ -531,5 +552,4 @@ public final class FlagUtil { return flags; } - -} +} \ No newline at end of file diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java index 3f1076b5d..5c85a9944 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/flag/RouteGraphConnectionSplitter.java @@ -1,11 +1,10 @@ package org.simantics.diagram.flag; -import gnu.trove.map.hash.TObjectIntHashMap; - import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; +import java.util.List; import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; @@ -24,9 +23,11 @@ import org.simantics.diagram.connection.RouteNode; import org.simantics.diagram.connection.RoutePoint; import org.simantics.diagram.connection.RouteTerminal; import org.simantics.diagram.connection.splitting.SplittedRouteGraph; +import org.simantics.diagram.connection.splitting.SplittedRouteGraph.PickResult; import org.simantics.diagram.content.ConnectionUtil; import org.simantics.diagram.stubs.DiagramResource; import org.simantics.diagram.synchronization.graph.AddElement; +import org.simantics.diagram.synchronization.graph.BasicResources; import org.simantics.diagram.synchronization.graph.DiagramGraphUtil; import org.simantics.diagram.synchronization.graph.RouteGraphModification; import org.simantics.g2d.elementclass.FlagClass; @@ -34,6 +35,8 @@ import org.simantics.layer0.Layer0; import org.simantics.modeling.ModelingResources; import org.simantics.structural.stubs.StructuralResource2; +import gnu.trove.map.hash.TObjectIntHashMap; + /** * A class that handles splitting a route graph connection in two with diagram * local flags. @@ -87,34 +90,33 @@ public class RouteGraphConnectionSplitter { RouteGraphModification modis = new RouteGraphModification(ss, rg); TObjectIntHashMap idMap = modis.getIdMap(); + if (DEBUG) { + System.out.println("Split canvas position: " + splitCanvasPos); + rg.print(); + } + // Find the edge to disconnect in the graph. // Bisect the nearest route line. - RouteLine line = SplittedRouteGraph.findNearestLine(rg, splitCanvasPos); - if (DEBUG) - rg.print(); - if (line == null) + PickResult picked = SplittedRouteGraph.pickNearestLine(rg, splitCanvasPos.getX(), splitCanvasPos.getY()); + if (picked == null) return; + + RouteLine line = picked.nearestLine; + if (DEBUG) { + System.out.println("picked nearest line:"); line.print(System.out); for (RoutePoint rp : line.getPoints()) System.out.println("RP: " + rp.getX() + ", " + rp.getY()); } // Get exact intersection point on the line - double isectX = splitCanvasPos.getX(); - double isectY = splitCanvasPos.getY(); - SplittedRouteGraph srg; - if (line.isHorizontal()) { - isectY = line.getPosition(); - srg = rg.splitGraph(line, isectX); - } - else { - isectX = line.getPosition(); - srg = rg.splitGraph(line, isectY); - } + double isectX = picked.intersectionPoint.getX(); + double isectY = picked.intersectionPoint.getY(); + SplittedRouteGraph srg = rg.splitGraph(line, line.isHorizontal() ? isectX : isectY); if (DEBUG) System.out.println(srg); - + // Disconnect if(rg.isSimpleConnection()) { RouteNode na = srg.terminals1.iterator().next(); @@ -141,44 +143,106 @@ public class RouteGraphConnectionSplitter { idMap.get(srg.splitLine) )); } - - ArrayList interfaceNodes1Resources = new ArrayList(srg.interfaceNodes1.size()); - for(RouteNode n : srg.interfaceNodes1) - interfaceNodes1Resources.add(ss.getResource((Long)n.getData())); - ArrayList interfaceNodes2Resources = new ArrayList(srg.interfaceNodes2.size()); - for(RouteNode n : srg.interfaceNodes2) - interfaceNodes2Resources.add(ss.getResource((Long)n.getData())); - - ArrayList lines2Resources = new ArrayList(srg.lines2.size()); - for(RouteLine n : srg.lines2) - lines2Resources.add(ss.getResource((Long)n.getData())); - - ArrayList terminals1Resources = new ArrayList(srg.terminals1.size()); - for(RouteTerminal n : srg.terminals1) - terminals1Resources.add(ss.getResource((Long)n.getData())); - ArrayList terminals2Resources = new ArrayList(srg.terminals2.size()); - for(RouteTerminal n : srg.terminals2) - terminals2Resources.add(ss.getResource((Long)n.getData())); + ArrayList terminals1Resources = toResources(srg.terminals1); + ArrayList terminals2Resources = toResources(srg.terminals2); + + boolean mustFlip = analyzePartInputs(graph, terminals1Resources, terminals2Resources); + + ArrayList interfaceNodes1 = toResources(mustFlip ? srg.interfaceNodes2 : srg.interfaceNodes1); + ArrayList interfaceNodes2 = toResources(mustFlip ? srg.interfaceNodes1 : srg.interfaceNodes2); + + ArrayList lines2 = toResources(mustFlip ? srg.lines1 : srg.lines2); + ArrayList terminals1 = mustFlip ? terminals2Resources : terminals1Resources; + ArrayList terminals2 = mustFlip ? terminals1Resources : terminals2Resources; + doSplit(graph, connection, - interfaceNodes1Resources, - interfaceNodes2Resources, - lines2Resources, - terminals1Resources, - terminals2Resources, + interfaceNodes1, + interfaceNodes2, + lines2, + terminals1, + terminals2, line.isHorizontal(), + mustFlip, isectX, isectY); modis.addModi(new RouteGraphModification.Split( - modis.toIds(interfaceNodes1Resources), - modis.toIds(interfaceNodes2Resources), - modis.toIds(lines2Resources), - modis.toIds(terminals1Resources), - modis.toIds(terminals2Resources), + modis.toIds(interfaceNodes1), + modis.toIds(interfaceNodes2), + modis.toIds(lines2), + modis.toIds(terminals1), + modis.toIds(terminals2), line.isHorizontal(), + mustFlip, isectX, isectY )); - } - + + private ArrayList toResources(Collection nodes) throws DatabaseException { + ArrayList result = new ArrayList<>(nodes.size()); + for (RouteNode n : nodes) + result.add(ss.getResource((Long)n.getData())); + return result; + } + + /** + * @param graph + * @param terminals1 + * @param terminals2 + * @return true if inputs need to be flipped, i.e. if terminals2 + * contains the output terminals and terminals1 doesn't. + * @throws DatabaseException + */ + private boolean analyzePartInputs(ReadGraph graph, List terminals1, List terminals2) throws DatabaseException { + @SuppressWarnings("unused") + int inputs1 = 0, outputs1 = 0; + for(Resource connector : terminals1) { + if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) + ++inputs1; + else + ++outputs1; + } + @SuppressWarnings("unused") + int inputs2 = 0, outputs2 = 0; + for(Resource connector : terminals2) { + if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) + ++inputs2; + else + ++outputs2; + } + + boolean mustFlip = outputs1 == 0; + + if (DEBUG) { + System.out.println("inputs1: " + inputs1); + System.out.println("outputs1: " + outputs1); + System.out.println("inputs2: " + inputs2); + System.out.println("outputs2: " + outputs2); + System.out.println("=> type1: " + (mustFlip ? FlagClass.Type.In : FlagClass.Type.Out)); + System.out.println("=> type2: " + (mustFlip ? FlagClass.Type.Out : FlagClass.Type.In)); + System.out.println("=> must flip route graph parts to split: " + mustFlip); + } + + return mustFlip; + } + + private static String routeNodeDebugInfo(ReadGraph graph, Resource c) throws DatabaseException { + BasicResources BR = BasicResources.getInstance(graph); + String ctr = NameUtils.getSafeName(graph, c, true); + for (Resource e : graph.getObjects(c, BR.STR.Connects)) { + ctr += " --> " + NameUtils.getSafeName(graph, e); + } + for (Resource e : graph.getObjects(c, BR.DIA.AreConnected)) { + ctr += " <-> " + NameUtils.getSafeName(graph, e); + } + return ctr; + } + + /** + * Internal routine that is only public because + * {@link RouteGraphModification#runUpdates(WriteGraph)} needs to invoke it. + * + * Assumes that #1 parameters will stay with the existing connection and #2 + * parameters will go to the newly created connection. + */ public void doSplit(WriteGraph graph, Resource connection, ArrayList interfaceNodes1Resources, @@ -186,22 +250,28 @@ public class RouteGraphConnectionSplitter { ArrayList lines2Resources, ArrayList terminals1Resources, ArrayList terminals2Resources, - boolean isHorizontal, + boolean isHorizontal, + boolean invertFlagRotation, double isectX, double isectY) throws DatabaseException { + // 1 = output, 2 = input + FlagClass.Type + type1 = FlagClass.Type.Out, + type2 = FlagClass.Type.In; + if (DEBUG) { System.out.println("doSplit:"); System.out.println(NameUtils.getSafeName(graph, connection, true)); for (Resource i : interfaceNodes1Resources) - System.out.println("i1: " + NameUtils.getSafeName(graph, i, true)); + System.out.println("i1: " + routeNodeDebugInfo(graph, i)); for (Resource i : interfaceNodes2Resources) - System.out.println("i2: " + NameUtils.getSafeName(graph, i, true)); + System.out.println("i2: " + routeNodeDebugInfo(graph, i)); for (Resource l : lines2Resources) - System.out.println("l2r: " + NameUtils.getSafeName(graph, l, true)); + System.out.println("l2r: " + routeNodeDebugInfo(graph, l)); for (Resource t : terminals1Resources) - System.out.println("t1: " + NameUtils.getSafeName(graph, t, true)); + System.out.println("t1: " + routeNodeDebugInfo(graph, t)); for (Resource t : terminals2Resources) - System.out.println("t2: " + NameUtils.getSafeName(graph, t, true)); + System.out.println("t2: " + routeNodeDebugInfo(graph, t)); System.out.println("is horizontal: " + isHorizontal); System.out.println("@(x,y): " + isectX + ", " + isectY); } @@ -209,15 +279,39 @@ public class RouteGraphConnectionSplitter { ConnectionUtil cu = new ConnectionUtil(graph); Resource diagram = OrderedSetUtils.getSingleOwnerList(graph, connection, DIA.Diagram); - Resource connectionType = graph.getSingleType(connection, DIA.Connection); + Resource diagramConnectionType = graph.getSingleType(connection, DIA.Connection); Resource hasConnectionType = graph.getPossibleObject(connection, STR.HasConnectionType); - Resource newConnection = cu.newConnection(diagram, connectionType); + Resource newConnection = cu.newConnection(diagram, diagramConnectionType); if (hasConnectionType != null) graph.claim(newConnection, STR.HasConnectionType, null, hasConnectionType); // Give running name to connection increment the counter attached to the diagram. AddElement.claimFreshElementName(graph, diagram, newConnection); + String commonLabel = DiagramFlagPreferences + .getActiveFlagLabelingScheme(graph) + .generateLabel(graph, diagram); + + Point2D pos1, pos2; + double theta; + double flagDist = 3.0; + if(isHorizontal) { + theta = 0.0; + pos1 = new Point2D.Double(isectX-flagDist, isectY); + pos2 = new Point2D.Double(isectX+flagDist, isectY); + } else { + theta = Math.PI*0.5; + pos1 = new Point2D.Double(isectX, isectY-flagDist); + pos2 = new Point2D.Double(isectX, isectY+flagDist); + } + + if (invertFlagRotation) { + theta += Math.PI; + Point2D p = pos1; + pos1 = pos2; + pos2 = p; + } + // WORKAROUND for mapping problems: // If any terminal of the split connection contains a flag, make sure their STR.Joins relations are all removed // to give mapping a chance to fix them properly. @@ -237,97 +331,31 @@ public class RouteGraphConnectionSplitter { graph.claim(rn, predicate, newConnection); } - // 1 = output, 2 = input - FlagClass.Type type1, type2; - - FlagLabelingScheme scheme = DiagramFlagPreferences.getActiveFlagLabelingScheme(graph); - String commonLabel = scheme.generateLabel(graph, diagram); - // Create flags and connect both disconnected ends to them. - Point2D pos1, pos2; - double theta; - double flagDist = 3.0; - if(isHorizontal) { - theta = 0.0; - pos1 = new Point2D.Double(isectX-flagDist, isectY); - pos2 = new Point2D.Double(isectX+flagDist, isectY); - } - else { - theta = Math.PI*0.5; - pos1 = new Point2D.Double(isectX, isectY-flagDist); - pos2 = new Point2D.Double(isectX, isectY+flagDist); - } - - // Chooses flag directions - { - @SuppressWarnings("unused") - int inputs1 = 0, outputs1 = 0; - for(Resource connector : terminals1Resources) { - if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) - ++inputs1; - else - ++outputs1; - } - @SuppressWarnings("unused") - int inputs2 = 0, outputs2 = 0; - for(Resource connector : terminals2Resources) { - if(graph.hasStatement(connector, DIA.IsHeadConnectorOf)) - ++inputs2; - else - ++outputs2; - } - - if(outputs1 == 0) { - type1 = FlagClass.Type.In; - type2 = FlagClass.Type.Out; - theta += Math.PI; - } - else { - type1 = FlagClass.Type.Out; - type2 = FlagClass.Type.In; - } - if (DEBUG) { - System.out.println("inputs1: " + inputs1); - System.out.println("outputs1: " + outputs1); - System.out.println("=> type1: " + type1); - System.out.println("inputs2: " + inputs2); - System.out.println("outputs2: " + outputs2); - System.out.println("=> type2: " + type2); - } - } Resource flag1 = createFlag(graph, diagram, getFlagTransform(pos1, theta), type1, commonLabel); Resource flag2 = createFlag(graph, diagram, getFlagTransform(pos2, theta), type2, commonLabel); + if (DEBUG) { + System.out.println("LABEL FOR NEW FLAGS: " + commonLabel); System.out.println("FLAG1: " + NameUtils.getSafeName(graph, flag1, true)); System.out.println("FLAG2: " + NameUtils.getSafeName(graph, flag2, true)); } -// System.out.println("conn1: " + NameUtils.getSafeLabel(graph, type1 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector)); -// System.out.println("conn2: " + NameUtils.getSafeLabel(graph, type2 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector)); - Resource flagConnector1 = cu.newConnector(connection, - type1 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector); - Resource flagConnector2 = cu.newConnector(newConnection, - type2 == FlagClass.Type.In ? DIA.HasPlainConnector : DIA.HasArrowConnector); + Resource flagConnector1 = cu.newConnector(connection, DIA.HasArrowConnector); + Resource flagConnector2 = cu.newConnector(newConnection, DIA.HasPlainConnector); graph.claim(flag1, DIA.Flag_ConnectionPoint, flagConnector1); graph.claim(flag2, DIA.Flag_ConnectionPoint, flagConnector2); double position = isHorizontal ? isectY : isectX; - connectFlag(graph, isHorizontal, position, connection, flagConnector1, - interfaceNodes1Resources); - connectFlag(graph, isHorizontal, position, newConnection, flagConnector2, - interfaceNodes2Resources); - - FlagUtil.join(graph, flag1, flag2); - - // Move mapping relations to new connection if necessary - if(type1 == FlagClass.Type.In) { - moveStatements(graph, connection, newConnection, MOD.ElementToComponent); - moveStatements(graph, connection, newConnection, MOD.DiagramConnectionToConnection); - moveStatements(graph, connection, newConnection, MOD.DiagramConnectionToConnectionSpecial); - FlagUtil.fixBindsStatements(graph, graph.getPossibleObject(newConnection, MOD.DiagramConnectionToConnection)); - } - else - FlagUtil.fixBindsStatements(graph, graph.getPossibleObject(connection, MOD.DiagramConnectionToConnection)); + connectFlag(graph, isHorizontal, position, connection, flagConnector1, interfaceNodes1Resources); + connectFlag(graph, isHorizontal, position, newConnection, flagConnector2, interfaceNodes2Resources); + + // Join the flags without activatingn diagram mapping at this point + FlagUtil.join(graph, flag1, flag2, false); + FlagUtil.fixBindsStatements(graph, graph.getPossibleObject(connection, MOD.DiagramConnectionToConnection)); + + // Finally ensure that all the diagrams related to the operation are mapped properly in one go + FlagUtil.activateMappingForParentDiagramsOf(graph, flag1, flag2); } /** @@ -370,15 +398,6 @@ public class RouteGraphConnectionSplitter { } } - private static void moveStatements(WriteGraph graph, Resource from, Resource to, Resource relation) throws DatabaseException { - if(from.equals(to)) - return; - for(Statement stat : graph.getStatements(from, relation)) - if(stat.getSubject().equals(from)) - graph.claim(to, stat.getPredicate(), stat.getObject()); - graph.deny(from, relation); - } - private void connectFlag(WriteGraph graph, boolean isHorizontal, double position, Resource connection, Resource flagConnector, Collection interfaceNodes) throws DatabaseException { if(interfaceNodes.size() > 1) { @@ -421,6 +440,7 @@ public class RouteGraphConnectionSplitter { } public static void splitConnection(WriteGraph graph, Resource connection, double x, double y) throws DatabaseException { + // TODO: provide a proper runtimeDiagram parameter to load to support also connections attached to flags attached to diagram template flag tables RouteGraph rg = RouteGraphUtils.load(graph, null, connection); new RouteGraphConnectionSplitter(graph).split(graph, connection, rg, new Point2D.Double(x, y)); } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java index 6cd4c542f..5bb793f7d 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/function/All.java @@ -95,6 +95,8 @@ public class All { Resource flag = context.element; Resource runtimeDiagram = context.runtime; + if (runtimeDiagram == null) + return flagTransformImpl(graph, converter, context); Resource diagram = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration); if (diagram == null) diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/IconButtonStyleBase.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/IconButtonStyleBase.java index f4c9470bd..4055e8d4a 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/IconButtonStyleBase.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/IconButtonStyleBase.java @@ -18,7 +18,15 @@ public abstract class IconButtonStyleBase extends St abstract protected String getNodePrefix(); abstract protected Class getNodeClass(); - + + public IconButtonStyleBase(Object identity) { + super(identity); + } + + public IconButtonStyleBase() { + super(); + } + private AffineTransform translateAndScaleIfNeeded(AffineTransform tr, Vec2d offset, boolean relativeTransform) { if(relativeTransform) { if(!offset.isZero()) { diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Updater.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Updater.java index 44ec7618e..2e79ef216 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Updater.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/Updater.java @@ -60,11 +60,11 @@ class Updater implements Runnable { } public void register(INode node) { - // We use ths size of this map to determine whether updates are needed, this is done in AWT thread + // We use the size of this map to determine whether updates are needed, this is done in AWT thread synchronized(requesters) { if(requesters.size() == 0) { if(state.compareAndSet(false, true)) { - ThreadUtils.getNonBlockingWorkExecutor().scheduleAtFixedRate(this, 0, 500, TimeUnit.MILLISECONDS); + ThreadUtils.getNonBlockingWorkExecutor().scheduleWithFixedDelay(this, 0, 500, TimeUnit.MILLISECONDS); } } ICanvasContext context = DiagramNodeUtil.getPossibleCanvasContext((G2DNode)node); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeVariable.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeVariable.java index 994370670..e7d411f85 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeVariable.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/runtime/RuntimeVariable.java @@ -65,6 +65,8 @@ class RuntimeVariable extends TernaryRead 0) json.append(","); - Object r = res[i]; - if(r instanceof IdentifiedObject) { - Object id = ((IdentifiedObject) r).getId(); - if(id instanceof IAdaptable) { - Object resource = ((IAdaptable) id).getAdapter(Resource.class); - if(resource != null) { - long rid = ((Resource)resource).getResourceId(); - json.append(Long.toString(rid)); - pos++; - } - } - } + if(pos > 0) json.append(","); + Object r = res[i]; + if(r instanceof IAdaptable) { + Resource resource = ((IAdaptable) r).getAdapter(Resource.class); + if(resource != null) { + long rid = resource.getResourceId(); + json.append(Long.toString(rid)); + pos++; + } + } } json.append("] }"); - StringSelection text = new StringSelection(json.toString()); - PlaintextTransfer plainText = new PlaintextTransfer(json.toString()); + String jsonText = json.toString(); + StringSelection text = new StringSelection(jsonText); + PlaintextTransfer plainText = new PlaintextTransfer(jsonText); return new MultiTransferable(local, text, plainText); diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java index ab28463e8..bbf9a8e5b 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/CopyAdvisorUtil.java @@ -11,8 +11,6 @@ *******************************************************************************/ package org.simantics.diagram.synchronization.graph; -import gnu.trove.map.hash.THashMap; - import java.util.Map; import java.util.Set; import java.util.function.BiFunction; @@ -46,6 +44,10 @@ import org.simantics.diagram.synchronization.SynchronizationHints; import org.simantics.graph.db.TransferableGraphs; import org.simantics.graph.representation.TransferableGraph1; import org.simantics.layer0.Layer0; +import org.simantics.utils.datastructures.BinaryFunction; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; /** * This class contains utility methods for the basic cut/copy operations @@ -82,6 +84,15 @@ public class CopyAdvisorUtil { public static final boolean DEBUG_COPY = DebugPolicy.DEBUG_COPY_PASTE; + private static class Statement4 { + public final Statement stm; + public final Resource inverse; + public Statement4(Statement stm, Resource inverse) { + this.stm = stm; + this.inverse = inverse; + } + } + /** * @param context a synchronization context instance, such as * {@link GraphToDiagramSynchronizer} @@ -364,8 +375,10 @@ public class CopyAdvisorUtil { * @throws DatabaseException */ public static Resource copy2(WriteGraph graph, Resource source, - BiFunction advisor) throws DatabaseException { - return copy2(graph, source, 0, advisor, new THashMap()); + BiFunction advisor) + throws DatabaseException + { + return copy2(graph, source, advisor, new THashMap<>()); } /** @@ -380,13 +393,52 @@ public class CopyAdvisorUtil { * @throws DatabaseException */ public static Resource copy2(WriteGraph graph, Resource source, - BiFunction advisor, Map copyMap) - throws DatabaseException { - return copy2(graph, source, 0, advisor, copyMap); + BiFunction advisor, + Map copyMap) + throws DatabaseException + { + Set pendingStatements = new THashSet<>(); + Resource result = copy2(graph, source, 0, advisor, copyMap, pendingStatements); + postProcessStatements(graph, copyMap, pendingStatements); + return result; + } + + /** + * Post-process pending statement + * + * Rule: If both the subject and object of a pending source statement have + * been copied, then the pending statement should also be copied. + */ + private static void postProcessStatements( + WriteGraph graph, + Map copyMap, + Set pendingStatements) + throws DatabaseException + { + if (pendingStatements.isEmpty()) + return; + + if (DEBUG_COPY) + System.out.println("post processing " + pendingStatements.size() + " pending statements"); + for (Statement4 srcStm : pendingStatements) { + // At this point, it is certain that srcStm subject has been copied + // but test it anyway. + Resource subjectCopy = (Resource) copyMap.get(srcStm.stm.getSubject()); + Resource objectCopy = (Resource) copyMap.get(srcStm.stm.getObject()); + if (subjectCopy == null || objectCopy == null) { + if (DEBUG_COPY) + System.out.println("skipping pending statement: " + NameUtils.toString(graph, srcStm.stm)); + continue; + } + if (DEBUG_COPY) + System.out.println("copying pending statement: " + NameUtils.toString(graph, srcStm.stm)); + graph.claim(subjectCopy, srcStm.stm.getPredicate(), srcStm.inverse, objectCopy); + } } private static Resource copy2(final WriteGraph graph, final Resource source, final int level, - BiFunction advisor, Map copyMap) + BiFunction advisor, Map copyMap, + Set pendingSourceStatements) throws DatabaseException { if (DEBUG_COPY) System.out.println("[" + level + "] CopyAdvisorUtil.copy(" + NameUtils.getSafeName(graph, source) + ", advisor=" + advisor + ")"); @@ -497,12 +549,18 @@ public class CopyAdvisorUtil { if (DEBUG_COPY) System.out.println("[" + level + "]\t\tcopy whole object"); - Resource clone = copy2(graph, obj, level + 1, advisor, copyMap); + Resource clone = copy2(graph, obj, level + 1, advisor, copyMap, pendingSourceStatements); graph.claim(copy, relation, inverse, clone); } } else { - if (DEBUG_COPY) - System.out.println("[" + level + "]\t\tskipping statement"); + if (graph.isSubrelationOf(relation, L0.IsRelatedTo)) { + if (DEBUG_COPY) + System.out.println("[" + level + "]\t\tmarking statement as pending for post-processing"); + pendingSourceStatements.add(new Statement4(stm, inverse)); + } else { + if (DEBUG_COPY) + System.out.println("[" + level + "]\t\tskipping weak statement"); + } } } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java index b0146cc21..e0d757417 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/ElementReorder.java @@ -55,9 +55,7 @@ public class ElementReorder extends ModificationAdapter { List graphOrder = OrderedSetUtils.toList(g, l); Set graphContents = new HashSet(graphOrder); - List diagramOrder = new ArrayList(order.size()); - Map diagramOrderIndex = new HashMap(order.size()); - int i = 0; + List newGraphOrder = new ArrayList<>(); for (IElement e : order) { Object obj = ElementUtils.getObject(e); if (obj instanceof Resource) { @@ -66,41 +64,22 @@ public class ElementReorder extends ModificationAdapter { // This prevents errors in situations where #order contains // elements that no longer exist in the diagram. if (graphContents.contains(r)) { - diagramOrder.add(r); - diagramOrderIndex.put(r, Integer.valueOf(i)); - ++i; + newGraphOrder.add(r); } } } - // Reorder the backend list according to diagramOrder - i = 0; - for (Resource r : graphOrder) { - Integer di = diagramOrderIndex.get(r); - if (di != null) { - int targetIndex = di; - int graphIndex = i++; - if (graphIndex != targetIndex) { - // Check if the predecessor of r is already correct. - // If it is, we don't have to do anything for r. - Resource graphPrev = OrderedSetUtils.prev(g, l, r); - Resource after = null; - if (targetIndex == 0) { - after = l; - if (l.equals(graphPrev)) - continue; - } else { - after = diagramOrder.get(targetIndex - 1); - if (after.equals(graphPrev)) - continue; - } - - // r needs to be repositioned. - OrderedSetUtils.remove(g, l, r); - OrderedSetUtils.addAfter(g, l, after, r); + // Safety measure for possible missing elements + if (graphOrder.size() != newGraphOrder.size()) { + Set added = new HashSet(newGraphOrder); + for (Resource r : graphOrder) { + if (!added.contains(r)) { + newGraphOrder.add(r); } } } + + OrderedSetUtils.reorder(g, l, newGraphOrder); } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java index a15b99bc4..41f4c00e6 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/synchronization/graph/RouteGraphModification.java @@ -162,12 +162,14 @@ public class RouteGraphModification { int[] lines2; int[] terminals1; int[] terminals2; - boolean isHorizontal; + boolean isHorizontal; + boolean invertFlagRotation; double isectX; double isectY; public Split(int[] interface1, int[] interface2, int[] lines2, int[] terminals1, int[] terminals2, boolean isHorizontal, + boolean invertFlagRotation, double isectX, double isectY) { this.interface1 = interface1; this.interface2 = interface2; @@ -175,6 +177,7 @@ public class RouteGraphModification { this.terminals1 = terminals1; this.terminals2 = terminals2; this.isHorizontal = isHorizontal; + this.invertFlagRotation = invertFlagRotation; this.isectX = isectX; this.isectY = isectY; } @@ -188,6 +191,7 @@ public class RouteGraphModification { this.terminals1 = readInts(it); this.terminals2 = readInts(it); this.isHorizontal = Boolean.parseBoolean(it.next()); + this.invertFlagRotation = Boolean.parseBoolean(it.next()); this.isectX = Double.parseDouble(it.next()); this.isectY = Double.parseDouble(it.next()); } @@ -208,6 +212,8 @@ public class RouteGraphModification { b.append("$"); b.append(isHorizontal); b.append("$"); + b.append(invertFlagRotation); + b.append("$"); b.append(isectX); b.append("$"); b.append(isectY); @@ -531,6 +537,7 @@ public class RouteGraphModification { toResources(modi.terminals1), toResources(modi.terminals2), modi.isHorizontal, + modi.invertFlagRotation, modi.isectX, modi.isectY ); diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java index d5a727ffa..8dea97ad1 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/Functions.java @@ -164,8 +164,8 @@ public class Functions { StandardAssertedGraphPropertyVariable ass = (StandardAssertedGraphPropertyVariable)property; if("dataDefinitions".equals(ass.property.name) || "commands".equals(ass.property.name) || "pollingFunction".equals(ass.property.name)) { storePropertyValueAndExceptions(graph, parent, ass.property.name, property, map); + continue; } - continue; } Resource predicate = property.getPossiblePredicateResource(graph); if(predicate != null) { @@ -297,8 +297,8 @@ public class Functions { StandardAssertedGraphPropertyVariable ass = (StandardAssertedGraphPropertyVariable)property; if("dataDefinitions".equals(ass.property.name) || "commands".equals(ass.property.name) || "pollingFunction".equals(ass.property.name)) { result.add(ass.property.name); + continue; } - continue; } Resource predicate = property.getPossiblePredicateResource(graph); if(predicate != null) { diff --git a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/HandleEventRequest.java b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/HandleEventRequest.java index 606b361b6..4c611a9aa 100644 --- a/bundles/org.simantics.document.server/src/org/simantics/document/server/request/HandleEventRequest.java +++ b/bundles/org.simantics.document.server/src/org/simantics/document/server/request/HandleEventRequest.java @@ -1,19 +1,17 @@ package org.simantics.document.server.request; import org.simantics.db.ReadGraph; +import org.simantics.db.common.request.UnaryRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; -import org.simantics.db.request.Read; import org.simantics.document.server.handler.AbstractEventHandler; import org.simantics.structural.stubs.StructuralResource2; -public class HandleEventRequest implements Read { - - final String id; +public class HandleEventRequest extends UnaryRead { public HandleEventRequest(String id) { - this.id = id; + super(id); } @Override @@ -21,7 +19,7 @@ public class HandleEventRequest implements Read { StructuralResource2.getInstance(graph); - Variable variable = Variables.getPossibleVariable(graph, id); + Variable variable = Variables.getPossibleVariable(graph, parameter); if(variable == null) return null; // System.err.println("EVENT " + variable.getURI(graph)); @@ -29,7 +27,7 @@ public class HandleEventRequest implements Read { if(handler instanceof AbstractEventHandler) return (AbstractEventHandler) handler; else - throw new DatabaseException("Handler for " + id + " is not instance of AbstractEventHandler (it is instance of " + (handler != null ? handler.getClass() : null) + ")"); + throw new DatabaseException("Handler for " + parameter + " is not instance of AbstractEventHandler (it is instance of " + (handler != null ? handler.getClass() : null) + ")"); } } \ No newline at end of file diff --git a/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph b/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph index ce06a4109..b08fbdaae 100644 --- a/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph +++ b/bundles/org.simantics.g2d.ontology/graph/G2D.pgraph @@ -210,7 +210,9 @@ G2D.HasVerticalAlignment G2D.Color diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java index 7896e52a7..9134c1729 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ElementPainter.java @@ -1033,6 +1033,17 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos return result; } + + /** + * We need to have separate class for SelectionNode, so that SCLSceneGraph can handle this properly. + * + */ + public static class SelectionShapeNode extends ShapeNode { + + private static final long serialVersionUID = -5393630944240940166L; + + } + public void paintSelectionFrame(int selectionId, G2DParentNode elementNode, G2DParentNode selectionNode, final IElement e, Color color) { // The element node already has the correct transform. AffineTransform selectionTransform = ElementUtils.getTransform(e);// no it doesnt ... new AffineTransform(); @@ -1054,7 +1065,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos Outline outline = (Outline) es.getAdapter(Outline.class); if (outline == null || outline.getElementShape(e) == null) continue; - ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), ShapeNode.class); + ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), SelectionShapeNode.class); // shapenode.setShape(es.getSelectionShape(e)); // shapenode.setStroke(SELECTION_STROKE); // shapenode.setScaleStroke(true); @@ -1090,7 +1101,7 @@ public class ElementPainter extends AbstractDiagramParticipant implements Compos G2DParentNode shapeholder = selectionNode.getOrCreateNode(getNodeId("outlines", e), G2DParentNode.class); for (SelectionOutline es : shapeHandlers) { - ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), ShapeNode.class); + ShapeNode shapenode = shapeholder.getOrCreateNode(getNodeId("outline", e, es), SelectionShapeNode.class); // shapenode.setShape(es.getSelectionShape(e)); // shapenode.setStroke(SELECTION_STROKE); // shapenode.setScaleStroke(true); diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ZOrderHandler.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ZOrderHandler.java index 007d039f2..8b893a2b1 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ZOrderHandler.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/participant/ZOrderHandler.java @@ -86,8 +86,8 @@ public class ZOrderHandler extends AbstractDiagramParticipant { int index = elements.indexOf(e); if (index != -1 && selectedElements.contains(e)) { changed |= diagram.moveTo(e, nextPos); - nextPos = index; } + nextPos = index; } if (changed) { notifyZOrderListeners(diagram); @@ -121,8 +121,8 @@ public class ZOrderHandler extends AbstractDiagramParticipant { int index = elements.indexOf(e); if (index != -1 && selectedElements.contains(e)) { changed |= diagram.moveTo(e, nextPos); - nextPos = index; } + nextPos = index; } if (changed) { notifyZOrderListeners(diagram); diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/ShapePick.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/ShapePick.java index a1d31acf0..3766a751b 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/ShapePick.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/element/handler/impl/ShapePick.java @@ -39,6 +39,8 @@ public class ShapePick implements Pick { pickRect = s.getBounds2D(); Shape es = ElementUtils.getElementShapeOrBounds(e); + // getElementShapeOrBounds returns shape or bounds in local coords! + es = ElementUtils.getTransform(e).createTransformedShape(es); PathIterator iter = es.getPathIterator(null); Collection segments = new ArrayList(); PathUtils.toLineSegments(iter, segments); @@ -55,7 +57,12 @@ public class ShapePick implements Pick { for (double[] seg : segments) { if (pickRect.intersectsLine(seg[0], seg[1], seg[2], seg[3])) return true; + if (pickRect.contains(seg[0], seg[1])) + return true; + if (pickRect.contains(seg[2], seg[3])) + return true; } + return false; } diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/gallery/GalleryViewer.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/gallery/GalleryViewer.java index 5bbe9f26e..d09ecf4a6 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/gallery/GalleryViewer.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/gallery/GalleryViewer.java @@ -631,8 +631,10 @@ public class GalleryViewer extends ContentViewer { 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(); + if (!ctx.isDisposed()) { + el.getElementClass().getSingleItem(GalleryItemSGNode.class).update(el); + ctx.getContentContext().setDirty(); + } }); break; } diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ShapeImage.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ShapeImage.java index 77c65cb6e..90ceaa12a 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ShapeImage.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/image/impl/ShapeImage.java @@ -21,7 +21,7 @@ import java.util.EnumSet; import org.simantics.g2d.image.Image; import org.simantics.scenegraph.Node; import org.simantics.scenegraph.g2d.G2DParentNode; -import org.simantics.scenegraph.g2d.nodes.ShapeNode; +import org.simantics.scenegraph.g2d.nodes.ShapeNode2; /** * @author Tuukka Lehtonen @@ -31,7 +31,8 @@ public class ShapeImage extends AbstractImage implements Image { private static final EnumSet defaultFeats = VECTOR; Shape shape; - Paint paint; + Paint fillPaint; + Paint strokePaint; Stroke stroke; EnumSet feats; boolean scaleStroke = false; @@ -41,16 +42,20 @@ public class ShapeImage extends AbstractImage implements Image { } public ShapeImage(Shape shape, Paint fill, Stroke stroke, boolean scaleStroke) { - this(shape, fill, stroke, scaleStroke, defaultFeats); + this(shape, fill, stroke, fill, scaleStroke, defaultFeats); } public ShapeImage(Shape shape, Paint fill, Stroke stroke, EnumSet features) { - this(shape, fill, stroke, false, features); + this(shape, fill, stroke, fill, false, features); + } + public ShapeImage(Shape shape, Paint fill, Stroke stroke, Paint strokeColor, boolean scaleStroke) { + this(shape, fill, stroke, strokeColor, scaleStroke, defaultFeats); } - public ShapeImage(Shape shape, Paint fill, Stroke stroke, boolean scaleStroke, EnumSet features) { + public ShapeImage(Shape shape, Paint fill, Stroke stroke, Paint strokeColor, boolean scaleStroke, EnumSet features) { this.shape = shape; - this.paint = fill; + this.fillPaint = fill; + this.strokePaint = strokeColor; this.stroke = stroke; this.scaleStroke = scaleStroke; this.feats = features; @@ -73,11 +78,11 @@ public class ShapeImage extends AbstractImage implements Image { @Override public Node init(G2DParentNode parent) { - ShapeNode shapeNode = parent.getOrCreateNode("ShapeImage", ShapeNode.class); + ShapeNode2 shapeNode = parent.getOrCreateNode("ShapeImage", ShapeNode2.class); shapeNode.setShape(shape); shapeNode.setStroke(stroke); - shapeNode.setFill(paint != null); - shapeNode.setColor(paint != null ? paint : Color.BLACK); + shapeNode.setFillColor(fillPaint); + shapeNode.setStrokeColor(strokePaint != null ? strokePaint : Color.BLACK); shapeNode.setScaleStroke(scaleStroke); return shapeNode; } diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java index f2a420b12..aafedcc09 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/OrientationRestorer.java @@ -88,7 +88,7 @@ public class OrientationRestorer extends AbstractCanvasParticipant { // long delay = 1000 / 25; this sounds quite frequent long delay = 1000 / 10; lastTrigger = System.currentTimeMillis(); - timer.scheduleAtFixedRate(task, delay, delay, TimeUnit.MILLISECONDS); + timer.scheduleWithFixedDelay(task, delay, delay, TimeUnit.MILLISECONDS); } @HintListener(Class = Hints.class, Field = "KEY_CANVAS_BOUNDS") diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/TimeParticipant.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/TimeParticipant.java index 9103dfd63..7eb4f4c37 100644 --- a/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/TimeParticipant.java +++ b/bundles/org.simantics.g2d/src/org/simantics/g2d/participant/TimeParticipant.java @@ -207,7 +207,7 @@ public class TimeParticipant extends AbstractCanvasParticipant { return; long interval = getInterval(); - future = ThreadUtils.getNonBlockingWorkExecutor().scheduleAtFixedRate(onTimer, DEFAULT_INTERVAL, interval, TimeUnit.MILLISECONDS); + future = ThreadUtils.getNonBlockingWorkExecutor().scheduleWithFixedDelay(onTimer, DEFAULT_INTERVAL, interval, TimeUnit.MILLISECONDS); } private void cancelTimer() { diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/refactoring/FixExportedOntology.java b/bundles/org.simantics.graph/src/org/simantics/graph/refactoring/FixExportedOntology.java index 17aa3ed26..33291cdf1 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/refactoring/FixExportedOntology.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/refactoring/FixExportedOntology.java @@ -41,8 +41,9 @@ public class FixExportedOntology { private static Path replaceExtension(Path p, String newExtension) { String newName = p.getFileName().toString(); - if (newName.contains(".")) - newName = newName.split("\\.")[0]; + int lastDot = newName.lastIndexOf('.'); + if (lastDot > -1) + newName = newName.substring(0, lastDot); return p.resolveSibling(newName + newExtension); } diff --git a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java index f2321dce9..9873f8f1e 100644 --- a/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java +++ b/bundles/org.simantics.graph/src/org/simantics/graph/representation/TransferableGraphUtils.java @@ -156,25 +156,27 @@ public class TransferableGraphUtils { } Identity consistsOf = findExternal(tg, "http://www.simantics.org/Layer0-1.1/ConsistsOf"); Identity hasName = findExternal(tg, "http://www.simantics.org/Layer0-1.1/HasName"); - for (int i = 0; i < tg.statements.length; i += 4) { - if (tg.statements[i] == parentResource) { - if (tg.statements[i + 1] == consistsOf.resource) { - Identity identity = getIdentity(tg, tg.statements[i + 3]); - if (identity != null) { - if (identity.definition instanceof Internal) { - Internal internal = (Internal) identity.definition; - result.put(internal.name, identity); - } - } else { - int possibleNameResource = getPossibleObject2(tg, tg.statements[i + 3], hasName); - if (possibleNameResource != NOT_FOUND) { - Value value = findValue(tg, possibleNameResource); - if (value != null) { - try { - String name = (String) value.value.getValue(Bindings.STRING); - result.put(name, new Identity(tg.statements[i + 3], new Internal(tg.statements[i], name))); - } catch (AdaptException e) { - e.printStackTrace(); + if(consistsOf != null && hasName != null) { + for (int i = 0; i < tg.statements.length; i += 4) { + if (tg.statements[i] == parentResource) { + if (tg.statements[i + 1] == consistsOf.resource) { + Identity identity = getIdentity(tg, tg.statements[i + 3]); + if (identity != null) { + if (identity.definition instanceof Internal) { + Internal internal = (Internal) identity.definition; + result.put(internal.name, identity); + } + } else { + int possibleNameResource = getPossibleObject2(tg, tg.statements[i + 3], hasName); + if (possibleNameResource != NOT_FOUND) { + Value value = findValue(tg, possibleNameResource); + if (value != null) { + try { + String name = (String) value.value.getValue(Bindings.STRING); + result.put(name, new Identity(tg.statements[i + 3], new Internal(tg.statements[i], name))); + } catch (AdaptException e) { + e.printStackTrace(); + } } } } diff --git a/bundles/org.simantics.history.rest/META-INF/MANIFEST.MF b/bundles/org.simantics.history.rest/META-INF/MANIFEST.MF index c9f04535f..a992c5e73 100644 --- a/bundles/org.simantics.history.rest/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.history.rest/META-INF/MANIFEST.MF @@ -8,24 +8,24 @@ Automatic-Module-Name: org.simantics.history.rest Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: org.simantics.history;bundle-version="1.0.0", org.eclipse.core.runtime;bundle-version="3.13.0", - org.glassfish.jersey.core.jersey-server, - jakarta.ws.rs-api, + org.glassfish.jersey.core.jersey-server;bundle-version="[2.25.1,2.26.0)", + javax.ws.rs-api, org.simantics.scl.compiler, org.simantics.scl.osgi, org.eclipse.jetty.servlet, - org.glassfish.jersey.containers.jersey-container-servlet-core, + org.glassfish.jersey.containers.jersey-container-servlet-core;bundle-version="[2.25.1,2.26.0)", javax.servlet-api, org.eclipse.jetty.server;bundle-version="9.4.24", org.eclipse.jetty.util;bundle-version="9.4.24", org.eclipse.jetty.io;bundle-version="9.4.24", org.eclipse.jetty.servlets;bundle-version="9.4.24", - com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.8", - com.fasterxml.jackson.core.jackson-annotations;bundle-version="2.8.0", - com.fasterxml.jackson.core.jackson-databind;bundle-version="2.8.8", - org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="2.25.1", + com.fasterxml.jackson.core.jackson-core;bundle-version="[2.8.11,2.9.0)", + com.fasterxml.jackson.core.jackson-annotations;bundle-version="[2.8.11,2.9.0)", + com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.8.11,2.9.0)", + org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="[2.25.1,2.26.0)", org.slf4j.api, - org.glassfish.jersey.core.jersey-client, - org.glassfish.jersey.core.jersey-common;bundle-version="2.25.1", + org.glassfish.jersey.core.jersey-client;bundle-version="[2.25.1,2.26.0)", + org.glassfish.jersey.core.jersey-common;bundle-version="[2.25.1,2.26.0)", org.simantics.scl.runtime, gnu.trove3;bundle-version="3.0.3", org.simantics.charts;bundle-version="0.0.1", diff --git a/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java b/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java index 4e405e2ac..b04e0dd37 100644 --- a/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java +++ b/bundles/org.simantics.history/src/org/simantics/history/csv/CSVFormatter.java @@ -38,6 +38,23 @@ import org.simantics.history.util.ValueBand; */ public class CSVFormatter { + /** + * This is the tolerance used to decide whether or not the last data point of + * the exported items is included in the exported material or not. If + * 0 <= (t - t(lastDataPoint) < {@value #RESAMPLING_END_TIMESTAMP_INCLUSION_TOLERANCE} + * is true, then the last exported data point will be + * lastDataPoint, with timestamp t(lastDataPoint) even + * if t > t(lastDataPoint). + * + *

+ * This works around problems where floating point inaccuracy causes a data + * point to be left out from the the export when it would be fair for the user + * to expect the data to be exported would contain a point with time stamp + * 9.999999999999996 when sampling with time-step 1.0 + * starting from time 0.0. + */ + private static final double RESAMPLING_END_TIMESTAMP_INCLUSION_TOLERANCE = 1e-13; + List items = new ArrayList(); double from = -Double.MAX_VALUE; double end = Double.MAX_VALUE; @@ -308,7 +325,7 @@ public class CSVFormatter { // Sampling based on given startTime and timeStep if(timeStep > 0) { - // Find the first sample time that contains data + // Find the first sample time that contains data if startTime < _from double n = Math.max(0, Math.ceil((_from-startTime) / timeStep)); time = startTime + n*timeStep; @@ -329,6 +346,13 @@ public class CSVFormatter { BigDecimal bigTime = new BigDecimal(String.valueOf(time)); BigDecimal bigTimeStep = new BigDecimal(String.valueOf(timeStep)); + // Loop kill-switch for the case where timeStep > 0 + boolean breakAfterNextWrite = false; + +// System.out.println("time: " + time); +// System.out.println("timeStep: " + timeStep); +// System.out.println("_end: " + Double.toString(_end)); + for (Item i : items) i.iter.gotoTime(time); do { if ( monitor!=null && monitor.isCanceled() ) return; @@ -394,10 +418,26 @@ public class CSVFormatter { sb.append( lineFeed ); - // Read next values, and the following times - if ( timeStep>0.0 ) { - bigTime = bigTime.add(bigTimeStep); - time = bigTime.doubleValue(); + if (breakAfterNextWrite) + break; + + // Read next values, and the following times + if ( timeStep>0.0 ) { + bigTime = bigTime.add(bigTimeStep); + time = bigTime.doubleValue(); + + // gitlab #529: prevent last data point from getting dropped + // due to small imprecisions in re-sampling mode. + double diff = time - _end; + if (diff > 0 && diff <= RESAMPLING_END_TIMESTAMP_INCLUSION_TOLERANCE) { + time = _end; + breakAfterNextWrite = true; + // Take floating point inaccuracy into account when re-sampling + // to prevent the last data point from being left out if there + // is small-enough imprecision in the last data point time stamp + // to be considered negligible compared to expected stepped time. + } + } else { // Get smallest end time that is larger than current time Double nextTime = null; @@ -420,6 +460,7 @@ public class CSVFormatter { if(contains(i, time)) hasMore = true; } + //System.out.println("hasMore @ " + time + " (" + bigTime + ") = " + hasMore); if(!hasMore) break; } while (time<=_end); @@ -587,7 +628,7 @@ public class CSVFormatter { private Formatter evaluateFormatter(Format format, DecimalSeparator target) { // Probe decimal separator String onePointTwo = format.format(1.2); - System.out.println("formatted zeroPointOne: " + onePointTwo); + //System.out.println("formatted zeroPointOne: " + onePointTwo); DecimalSeparator formatSeparator; if (onePointTwo.indexOf('.') != -1) { diff --git a/bundles/org.simantics.issues.ui/META-INF/MANIFEST.MF b/bundles/org.simantics.issues.ui/META-INF/MANIFEST.MF index da218152b..8d346bbb4 100644 --- a/bundles/org.simantics.issues.ui/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.issues.ui/META-INF/MANIFEST.MF @@ -24,6 +24,7 @@ Bundle-ActivationPolicy: lazy Bundle-Activator: org.simantics.issues.ui.internal.Activator Export-Package: org.simantics.issues.ui, org.simantics.issues.ui.contribution, - org.simantics.issues.ui.handler + org.simantics.issues.ui.handler, + org.simantics.issues.ui.property Bundle-Vendor: VTT Technical Research Centre of Finland Automatic-Module-Name: org.simantics.issues.ui diff --git a/bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/property/IssuesTab.java b/bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/property/IssuesTab.java new file mode 100644 index 000000000..fb1e0a977 --- /dev/null +++ b/bundles/org.simantics.issues.ui/src/org/simantics/issues/ui/property/IssuesTab.java @@ -0,0 +1,172 @@ +package org.simantics.issues.ui.property; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.eclipse.jface.layout.GridDataFactory; +import org.eclipse.jface.layout.GridLayoutFactory; +import org.eclipse.jface.viewers.CellLabelProvider; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredContentProvider; +import org.eclipse.jface.viewers.TableViewer; +import org.eclipse.jface.viewers.TableViewerColumn; +import org.eclipse.jface.viewers.ViewerCell; +import org.eclipse.swt.SWT; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.ui.IWorkbenchSite; +import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport; +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.common.procedure.adapter.TransientCacheListener; +import org.simantics.db.common.request.ResourceRead; +import org.simantics.db.common.utils.NameUtils; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.management.ISessionContext; +import org.simantics.db.request.Read; +import org.simantics.issues.Severity; +import org.simantics.issues.common.IssueResourceContexts; +import org.simantics.issues.common.ListModelIssuesBySeverity; +import org.simantics.issues.common.SimpleIssue; +import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; +import org.simantics.selectionview.PropertyTabContributorImpl; + +/** + * A very simple property tab for listing issues of a selected object. + * + * @author luukkainen + * + */ +public class IssuesTab extends PropertyTabContributorImpl{ + + + private TableViewer viewer; + private Resource model; + private Resource element; + + private List result; + + public IssuesTab(ReadGraph graph, Resource model, Resource element) throws DatabaseException { + this.model = model; + this.element = element; + + Layer0 L0 = Layer0.getInstance(graph); + List contexts = getContexts(graph, element); + Map> issuesBySeverity = graph.syncRequest( + new ListModelIssuesBySeverity(model, true, true, Severity.NOTE), + TransientCacheListener.>>instance()); + + result = new ArrayList<>(); + for (Severity severity : Severity.values()) { + List issues = issuesBySeverity.get(severity); + if (issues != null) { + for (Resource issue : issues) { + Set issueContexts = graph.syncRequest(new IssueResourceContexts(issue)); + if (!Collections.disjoint(issueContexts, contexts)) { + SimpleIssue si = new SimpleIssue((String) graph.getRelatedValue(issue, L0.HasLabel, Bindings.STRING), + severity, issue); + result.add(si); + System.out.println(si.label + " " + si.severity); + } + } + } + } + } + + + /** + * @see org.simantics.modeling.ui.diagram.style.IssueDecorationStyle + * + * @param graph + * @param element + * @return + * @throws DatabaseException + */ + protected List getContexts(ReadGraph graph, Resource element) throws DatabaseException { + + ModelingResources MOD = ModelingResources.getInstance(graph); + List result = new ArrayList(3); + result.add(element); + Resource config = graph.getPossibleObject(element, MOD.ElementToComponent); + if (config != null && result.indexOf(config) == -1) result.add(config); + config = graph.getPossibleObject(element, MOD.DiagramConnectionToConnection); + if (config != null && result.indexOf(config) == -1) result.add(config); + // For diagram reference element support + config = graph.getPossibleObject(element, MOD.HasParentComponent); + if (config != null && result.indexOf(config) == -1) result.add(config); + return result; + + } + + + @Override + public void createControls(Composite body, IWorkbenchSite site, ISessionContext context, WidgetSupport support) { + GridLayoutFactory.fillDefaults().numColumns(2).spacing(0, 0).applyTo(body); + + viewer = new TableViewer(body); + + TableViewerColumn issueColumn = new TableViewerColumn(viewer, SWT.LEFT); + TableViewerColumn severityColumn = new TableViewerColumn(viewer, SWT.LEFT); + + issueColumn.setLabelProvider(new CellLabelProvider() { + + @Override + public void update(ViewerCell cell) { + SimpleIssue issue = (SimpleIssue)cell.getElement(); + cell.setText(issue.label); + + } + }); + severityColumn.setLabelProvider(new CellLabelProvider() { + + @Override + public void update(ViewerCell cell) { + SimpleIssue issue = (SimpleIssue)cell.getElement(); + cell.setText(issue.severity.name()); + } + }); + + issueColumn.getColumn().setWidth(300); + issueColumn.getColumn().setText("Issue"); + + severityColumn.getColumn().setWidth(100); + severityColumn.getColumn().setText("Severity"); + + viewer.getTable().setHeaderVisible(true); + viewer.getTable().setLinesVisible(true); + + viewer.setContentProvider(new IStructuredContentProvider() { + + @Override + public Object[] getElements(Object inputElement) { + List list = (List)inputElement; + return list.toArray(); + } + }); + + viewer.setInput(result); + GridDataFactory.fillDefaults().grab(true, true).applyTo(viewer.getControl()); + + } + + @Override + public Read getPartNameReadRequest(ISelection forSelection) { + return new ObjectTitleRead(element); + } + + public static class ObjectTitleRead extends ResourceRead { + public ObjectTitleRead(Resource resource) { + super(resource); + } + + @Override + public String perform(ReadGraph graph) throws DatabaseException { + return NameUtils.getSafeName(graph, resource); + } + } + +} diff --git a/bundles/org.simantics.modeling.ontology/graph/Modeling.pgraph b/bundles/org.simantics.modeling.ontology/graph/Modeling.pgraph index 82808f837..b13462813 100644 --- a/bundles/org.simantics.modeling.ontology/graph/Modeling.pgraph +++ b/bundles/org.simantics.modeling.ontology/graph/Modeling.pgraph @@ -375,6 +375,7 @@ MOD.HasSourceInformation --> MOD.SourceInformation Vector Byte" +STR.ComponentType + MOD.contentDumpFunction + MOD.StructuralComponentTypeContentDumpFunction + @L0.sclValue "structuralComponentTypeContentDump" "Resource -> Vector Byte" + SEL.GenericParameterType MOD.contentDumpFunction MOD.GenericParameterTypeContentDumpFunction diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/chart/property/ObtainedDoubleAdapter.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/chart/property/ObtainedDoubleAdapter.java index 79f32fcd2..ff257169c 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/chart/property/ObtainedDoubleAdapter.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/chart/property/ObtainedDoubleAdapter.java @@ -20,6 +20,7 @@ import org.simantics.db.RelationContext; import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.common.adaption.SimpleContextualAdapter; +import org.simantics.db.exception.AdaptionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.property.OrderedResource; import org.simantics.operation.Layer0X; @@ -46,7 +47,7 @@ public class ObtainedDoubleAdapter extends SimpleContextualAdapter getInputValidator() { - return new ParametrizedRead() { - @Override - public Read get(IResourceEditorInput parameter) { - return Combinators.constant(Boolean.TRUE); - } - }; + // No-op validator that always returns true + return param -> Combinators.constant(Boolean.TRUE); } @Override @@ -131,12 +131,14 @@ public class ComponentTypeScriptEditor extends SCLModuleEditor { @Override public void run(ReadGraph graph) throws DatabaseException { StructuralResource2 STR = StructuralResource2.getInstance(graph); - final String type = graph.getPossibleRelatedValue(script, STR.ComponentTypeScript_type); + String type = graph.getPossibleRelatedValue(script, STR.ComponentTypeScript_type); if(type != null) + scriptType = type; combo.getDisplay().asyncExec(() -> { for(int i=0;i { int id = combo.getSelectionIndex(); + if (id == scriptTypeIndex) + return; + if (docProvider.isReadOnly(getEditorInput())) { + // Return configured selection + combo.select(scriptTypeIndex); + return; + } + String newType = EXECUTION_PHASES[id]; Simantics.getSession().asyncRequest((WriteGraph graph) -> { StructuralResource2 STR = StructuralResource2.getInstance(graph); String currentType = graph.getPossibleRelatedValue(script, STR.ComponentTypeScript_type); - String newType = EXECUTION_PHASES[id]; if(!newType.equals(currentType)) graph.claimLiteral(script, STR.ComponentTypeScript_type, newType, Bindings.STRING); + }, exc -> { + if (exc == null) { + scriptType = newType; + scriptTypeIndex = id; + } else { + ExceptionUtils.logError(exc); + } }); })); GridDataFactory.fillDefaults().grab(true, false).applyTo(combo); diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java index 73b09f7bf..4b9ffbe80 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ComponentTypeViewerData.java @@ -53,6 +53,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.function.DbConsumer; import org.simantics.db.layer0.QueryIndexUtils; import org.simantics.layer0.Layer0; +import org.simantics.modeling.ModelingResources; import org.simantics.modeling.userComponent.ComponentTypeCommands; import org.simantics.modeling.utils.ComponentTypeViewerPropertyInfo; import org.simantics.scl.runtime.function.Function2; @@ -265,34 +266,43 @@ public class ComponentTypeViewerData { String newValue2 = newValue; Resource possibleGraphType = null; - Resource root = graph.syncRequest(new IndexRoot(componentType)); - Resource L0Res = graph.getResource("http://www.simantics.org/Layer0-1.1"); Layer0 L0 = Layer0.getInstance(graph); - - Collection graphTypes1 = QueryIndexUtils.searchByTypeAndName(graph, L0Res, L0.ValueType, newValue); - Collection graphTypes2 = QueryIndexUtils.searchByTypeAndName(graph, root, L0.ValueType, newValue); - - Collection graphTypes = new HashSet<>(graphTypes1); - graphTypes.addAll(graphTypes2); - - Set> candidates = new HashSet<>(); - for (Resource graphType : graphTypes) { - Collection stms = graph.getAssertedStatements(graphType, L0.HasValueType); - if(stms.size() == 1) { - // Only accept valueType if it asserts HasValueType with the same name - String hasValueType = graph.getValue(stms.iterator().next().getObject(), Bindings.STRING); - if (hasValueType.equals(newValue)) { - candidates.add(new Pair<>(graphType, hasValueType)); + ModelingResources MOD = ModelingResources.getInstance(graph); + + Resource previousRange = graph.getPossibleObject(propertyInfo.resource, L0.HasRange); + if (previousRange != null && graph.isInheritedFrom(previousRange, MOD.MonitorValue)) { + // Do not override range of derived properties + possibleGraphType = previousRange; + } else { + Resource root = graph.syncRequest(new IndexRoot(componentType)); + + Resource L0Res = graph.getResource("http://www.simantics.org/Layer0-1.1"); + + Collection graphTypes1 = QueryIndexUtils.searchByTypeAndName(graph, L0Res, L0.ValueType, newValue); + Collection graphTypes2 = QueryIndexUtils.searchByTypeAndName(graph, root, L0.ValueType, newValue); + + Collection graphTypes = new HashSet<>(graphTypes1); + graphTypes.addAll(graphTypes2); + + Set> candidates = new HashSet<>(); + for (Resource graphType : graphTypes) { + Collection stms = graph.getAssertedStatements(graphType, L0.HasValueType); + if(stms.size() == 1) { + // Only accept valueType if it asserts HasValueType with the same name + String hasValueType = graph.getValue(stms.iterator().next().getObject(), Bindings.STRING); + if (hasValueType.equals(newValue)) { + candidates.add(new Pair<>(graphType, hasValueType)); + } } } - } - // We support only graph types with unique name at this point. Later we could implement UI to let the user to select from multiple graph types. - if (candidates.size() == 1) { - Pair result = candidates.iterator().next(); - possibleGraphType = result.first; - newValue2 = result.second; + // We support only graph types with unique name at this point. Later we could implement UI to let the user to select from multiple graph types. + if (candidates.size() == 1) { + Pair result = candidates.iterator().next(); + possibleGraphType = result.first; + newValue2 = result.second; + } } ComponentTypeCommands.editType(graph, componentType, propertyInfo.resource, convertDefaultValue, newValue2, possibleGraphType); diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ProceduralComponentTypeCodeDocumentProvider.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ProceduralComponentTypeCodeDocumentProvider.java index 1a1eb723f..5cc209943 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ProceduralComponentTypeCodeDocumentProvider.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/componentTypeEditor/ProceduralComponentTypeCodeDocumentProvider.java @@ -31,6 +31,7 @@ import org.simantics.scl.ui.editor.SCLSourceViewerConfigurationNew; import org.simantics.scl.ui.editor.TextAndErrors; import org.simantics.structural2.scl.procedural.CompileProceduralComponentTypeRequest; import org.simantics.structural2.scl.procedural.ProceduralComponentTypeCompilationException; +import org.simantics.structural2.utils.StructuralUtils; import org.simantics.ui.workbench.ResourceEditorInput; import org.simantics.utils.logging.TimeLogger; import org.simantics.utils.ui.SWTUtils; @@ -55,6 +56,7 @@ public class ProceduralComponentTypeCodeDocumentProvider extends SCLModuleEditor @Override public Document perform(ReadGraph graph) throws DatabaseException { currentText = graph.getValue(resource, Bindings.STRING); + immutable = StructuralUtils.isImmutable(graph, resource); errorHappened = false; return new Document(currentText != null ? currentText : ""); //$NON-NLS-1$ } diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/ObtainedColorAdapter.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/ObtainedColorAdapter.java index 21c820864..acb258110 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/ObtainedColorAdapter.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagram/monitor/ObtainedColorAdapter.java @@ -10,6 +10,7 @@ import org.simantics.db.RelationContext; import org.simantics.db.Resource; import org.simantics.db.Statement; import org.simantics.db.common.adaption.SimpleContextualAdapter; +import org.simantics.db.exception.AdaptionException; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.property.OrderedResource; import org.simantics.diagram.stubs.DiagramResource; @@ -34,7 +35,7 @@ public class ObtainedColorAdapter extends SimpleContextualAdapter { private static final String DECORATION_NODE_NAME = "issueDecorations"; //$NON-NLS-1$ - private List getContexts(ReadGraph graph, Resource element) throws DatabaseException { + protected List getContexts(ReadGraph graph, Resource element) throws DatabaseException { ModelingResources MOD = ModelingResources.getInstance(graph); List result = new ArrayList(3); diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java index decf3356c..dc9d9d1be 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/diagramEditor/DiagramViewerLoadJob.java @@ -111,8 +111,8 @@ public class DiagramViewerLoadJob extends DatabaseJob { }); END(task); } catch (Throwable t) { - viewer = null; LOGGER.error("Failed to complete loading of diagram {} in the canvas thread", viewer.diagramResource, t); + viewer = null; } } }); diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/expression/InvertBasicExpressionVisitor.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/expression/InvertBasicExpressionVisitor.java index 3f4ccc20b..9101700d0 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/expression/InvertBasicExpressionVisitor.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/expression/InvertBasicExpressionVisitor.java @@ -1,109 +1,15 @@ package org.simantics.modeling.ui.expression; -import java.util.Stack; - -import org.simantics.basicexpression.analysis.DepthFirstAdapter; -import org.simantics.basicexpression.node.AConstantValue; -import org.simantics.basicexpression.node.ADivMultiplicative; -import org.simantics.basicexpression.node.AMultMultiplicative; -import org.simantics.basicexpression.node.APlusExpression; import org.simantics.basicexpression.node.AStringValue; +import org.simantics.modeling.InvertBasicExpressionVisitorBase; import org.simantics.utils.datastructures.Triple; -public class InvertBasicExpressionVisitor extends DepthFirstAdapter { - - Stack stack = new Stack(); - - public Object getResult() { - return stack.pop(); - } - - public void outAConstantValue(AConstantValue node) { - stack.push(Double.valueOf(node.toString())); - } +public class InvertBasicExpressionVisitor extends InvertBasicExpressionVisitorBase { + @Override public void outAStringValue(AStringValue node) { String value = node.toString(); stack.push(Triple.make(1.0, 0.0, value.substring(1, value.length() - 2).trim())); } - @SuppressWarnings("unchecked") - public void outAPlusExpression(APlusExpression node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(p.first, p.second + (Double)o1, p.third)); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first, p.second + (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 + (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outAMinusExpression(APlusExpression node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(-p.first, (Double)o1 - p.second, p.third )); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first, p.second - (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 - (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outAMultMultiplicative(AMultMultiplicative node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(p.first * (Double)o1, p.second * (Double)o1, p.third)); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first * (Double)o2, p.second * (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 * (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outADivMultiplicative(ADivMultiplicative node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - stack.push(Double.NaN); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first / (Double)o2, p.second / (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 / (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - } diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/modelBrowser/handlers/ContextualHelp.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/modelBrowser/handlers/ContextualHelp.java index 0d0ec7ce6..e7bfd35fa 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/modelBrowser/handlers/ContextualHelp.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/modelBrowser/handlers/ContextualHelp.java @@ -20,16 +20,13 @@ import org.eclipse.jface.viewers.ISelection; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.handlers.HandlerUtil; import org.simantics.Simantics; -import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.request.UniqueRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; -import org.simantics.modeling.ModelingResources; -import org.simantics.modeling.PropertyVariables; +import org.simantics.modeling.help.HelpContexts; import org.simantics.ui.selection.WorkbenchSelectionUtils; -import org.simantics.utils.ui.AdaptionUtils; import org.slf4j.LoggerFactory; public class ContextualHelp extends AbstractHandler { @@ -47,7 +44,7 @@ public class ContextualHelp extends AbstractHandler { return Simantics.getSession().syncRequest(new UniqueRead() { @Override public String perform(ReadGraph graph) throws DatabaseException { - return getPossibleId(graph, resource, variable, sel); + return HelpContexts.getPossibleId(graph, resource, variable, sel); } }); } catch (DatabaseException e) { @@ -64,34 +61,12 @@ public class ContextualHelp extends AbstractHandler { return null; } + /** + * @deprecated use {@link HelpContexts#getPossibleId(ReadGraph, Resource, Variable, Object)} instead + */ + @Deprecated public static String getPossibleId(ReadGraph graph, Resource resource, Variable variable, ISelection sel) throws DatabaseException { - ModelingResources MOD = ModelingResources.getInstance(graph); - if (resource != null) { - Resource component = graph.getPossibleObject(resource, MOD.ElementToComponent); - String id = component != null ? graph.getPossibleRelatedValue2(component, MOD.contextualHelpId, Bindings.STRING) : null; - if (id != null) - return id; - id = graph.getPossibleRelatedValue2(resource, MOD.contextualHelpId, Bindings.STRING); - if (id != null) - return id; - } - - if (variable != null) { - String id = variable.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING); - if (id != null) - return id; - } - - // TODO: consider removing this block - if (sel != null) { - PropertyVariables vars = AdaptionUtils.adaptToSingle(sel, PropertyVariables.class); - Variable var = vars != null ? vars.getConfiguration() : null; - String id = var != null ? var.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING) : null; - if (id != null) - return id; - } - - return null; + return HelpContexts.getPossibleId(graph, resource, variable, sel); } } diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java index bec1e5408..0b7cd63e4 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/pdf/PDFPainter.java @@ -89,7 +89,15 @@ public class PDFPainter { ThreadUtils.asyncExec(thread, () -> { try { - PDFBuilder chassis = new PDFBuilder(writer, mapper, pageSize, pageDesc, fitDiagramContentsToPageMargins || isSymbol); + boolean fitToContent = fitDiagramContentsToPageMargins || isSymbol; + if (!fitToContent) { + // Prevent PDF printing from drawing page borders if the + // print area is fitted directly to the page size. + // This avoids unwanted black half-visible edges. + ctx.getDefaultHintContext().setHint(Hints.KEY_DISPLAY_PAGE, false); + } + + PDFBuilder chassis = new PDFBuilder(writer, mapper, pageSize, pageDesc, fitToContent); chassis.paint(ctx, true); } catch (Throwable e) { exception[0] = new DatabaseException(e); diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/preferences/CSVPreferencePage.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/preferences/CSVPreferencePage.java index aadd9395a..7a2e7a6eb 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/preferences/CSVPreferencePage.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/preferences/CSVPreferencePage.java @@ -23,8 +23,10 @@ import org.eclipse.jface.preference.IntegerFieldEditor; import org.eclipse.jface.preference.StringFieldEditor; import org.eclipse.jface.util.PropertyChangeEvent; import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Color; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Group; +import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; import org.eclipse.ui.preferences.ScopedPreferenceStore; @@ -110,7 +112,8 @@ public class CSVPreferencePage extends FieldEditorPreferencePage implements IWor fExtensionEditor = new StringFieldEditor(CSVPreferences.P_CSV_FILE_EXTENSION, "File extension", getFieldEditorParent()); addField(fExtensionEditor); - fResamplingEditor = new BooleanFieldEditor(CSVPreferences.P_CSV_RESAMPLE, "Resampling", getFieldEditorParent()); + fResamplingEditor = new BooleanFieldEditor(CSVPreferences.P_CSV_RESAMPLE, "&Resample", getFieldEditorParent()); + fResamplingEditor.getDescriptionControl(getFieldEditorParent()).setToolTipText("Resample exported data from raw data"); addField(fResamplingEditor); fSamplingModeEditor = new ComboFieldEditor(CSVPreferences.P_CSV_SAMPLING_MODE, "Sampling mode", @@ -127,8 +130,9 @@ public class CSVPreferencePage extends FieldEditorPreferencePage implements IWor return true; } try { + @SuppressWarnings("unused") double number = Double.parseDouble(text); - return number>0; + return true; } catch (NumberFormatException e1) { return false; } @@ -136,6 +140,8 @@ public class CSVPreferencePage extends FieldEditorPreferencePage implements IWor }; fStartEditor.setEmptyStringAllowed(true); fStartEditor.setErrorMessage("Enter valid start time value (s)"); + fStartEditor.getTextControl(getFieldEditorParent()).setToolTipText("Time to start resampling from"); + addField(fStartEditor); fStepEditor = new StringFieldEditor(CSVPreferences.P_CSV_TIME_STEP, "Step size (s)", getFieldEditorParent()) { protected boolean doCheckState() { @@ -153,6 +159,7 @@ public class CSVPreferencePage extends FieldEditorPreferencePage implements IWor }; fStepEditor.setEmptyStringAllowed(true); fStepEditor.setErrorMessage("Enter valid time step value (s)"); + fStepEditor.getTextControl(getFieldEditorParent()).setToolTipText("Time step to use when resampling"); addField(fStepEditor); Group significantDigitsGroup = new Group(getFieldEditorParent(), SWT.NONE); @@ -171,6 +178,8 @@ public class CSVPreferencePage extends FieldEditorPreferencePage implements IWor addField(fDoubleDigitsEditor); GridLayoutFactory.swtDefaults().numColumns(2).applyTo(significantDigitsGroup); + + updateSampling(getPreferenceStore().getBoolean(CSVPreferences.P_CSV_RESAMPLE)); } /** @@ -187,6 +196,8 @@ public class CSVPreferencePage extends FieldEditorPreferencePage implements IWor } else if (source == fColumnSeparatorEditor) { columnSeparatorValue = (String) event.getNewValue(); validate = true; + } else if (source == fResamplingEditor) { + updateSampling(); } if (validate) { if (decimalSeparatorValue.equals(columnSeparatorValue)) { @@ -201,4 +212,16 @@ public class CSVPreferencePage extends FieldEditorPreferencePage implements IWor super.propertyChange(event); } + private void updateSampling() { + updateSampling(fResamplingEditor.getBooleanValue()); + } + + private void updateSampling(boolean resample) { + Label fStartLabel = fStartEditor.getLabelControl(getFieldEditorParent()); + Label fStepLabel = fStepEditor.getLabelControl(getFieldEditorParent()); + Color gray = fStartLabel.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY); + fStartLabel.setForeground(resample ? null : gray); + fStepLabel.setForeground(resample ? null : gray); + } + } diff --git a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/sg/DiagramSceneGraphProvider.java b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/sg/DiagramSceneGraphProvider.java index d3170b950..3ca0cf698 100644 --- a/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/sg/DiagramSceneGraphProvider.java +++ b/bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/sg/DiagramSceneGraphProvider.java @@ -26,6 +26,7 @@ import org.simantics.db.exception.ManyObjectsForFunctionalRelationException; import org.simantics.db.exception.NoSingleResultException; import org.simantics.db.exception.ServiceException; import org.simantics.db.management.ISessionContext; +import org.simantics.db.procedure.Listener; import org.simantics.db.request.Read; import org.simantics.diagram.adapter.DefaultConnectionClassFactory; import org.simantics.diagram.adapter.FlagClassFactory; @@ -97,6 +98,7 @@ import org.simantics.utils.page.PageDesc; import org.simantics.utils.page.PageOrientation; import org.simantics.utils.threads.AWTThread; import org.simantics.utils.threads.IThreadWorkQueue; +import org.simantics.utils.threads.ThreadUtils; import org.simantics.utils.ui.ErrorLogger; @@ -288,6 +290,30 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi DiagramDesc diagramDesc = Simantics.getSession().syncRequest(DiagramRequests.getDiagramDesc(diagramResource)); if (diagramDesc != null) setDiagramDesc(ctx, diagramDesc); + + // Create a listener to react to page setting changes. + Simantics.getSession().asyncRequest(DiagramRequests.getDiagramDesc(diagramResource), new Listener() { + @Override + public void execute(DiagramDesc result) { + if (result != null && ctx != null) { + ThreadUtils.asyncExec(ctx.getThreadAccess(), () -> { + if (ctx != null) { + setDiagramDesc(ctx, result); + } + }); + } + } + + @Override + public void exception(Throwable t) { + ErrorLogger.defaultLogError(t); + } + + @Override + public boolean isDisposed() { + return DiagramSceneGraphProvider.this.ctx == null; + } + }); } catch (DatabaseException e) { ErrorLogger.defaultLogError(e); } @@ -296,7 +322,7 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi protected void setDiagramDesc(ICanvasContext ctx, DiagramDesc diagramDesc) { IHintContext hints = ctx.getDefaultHintContext(); hints.setHint(Hints.KEY_PAGE_DESC, diagramDesc.getPageDesc()); - //hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible()); + hints.setHint(Hints.KEY_DISPLAY_PAGE, diagramDesc.isPageBordersVisible()); hints.setHint(Hints.KEY_DISPLAY_MARGINS, diagramDesc.isMarginsVisible()); } @@ -348,13 +374,7 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi } try { - - IModelingRules modelingRules = Simantics.getSession().syncRequest(DiagramRequests.getModelingRules(resource, null)); - if (modelingRules != null) { - initialHints.setHint(DiagramModelHints.KEY_MODELING_RULES, modelingRules); - } - - initialHints.setHint(SynchronizationHints.COPY_ADVISOR, getCopyAdvisor()); + fillInitialDiagramHints(initialHints); final RuntimeDiagramManager runtimeDiagramManager = RuntimeDiagramManager.create(Simantics.getSession(), resource, modelURI, RVI); @@ -385,6 +405,15 @@ public class DiagramSceneGraphProvider implements ICanvasSceneGraphProvider, IDi return ctx.getSceneGraph(); } + protected void fillInitialDiagramHints(IHintContext initialHints) throws DatabaseException { + IModelingRules modelingRules = Simantics.getSession().syncRequest(DiagramRequests.getModelingRules(resource, null)); + if (modelingRules != null) { + initialHints.setHint(DiagramModelHints.KEY_MODELING_RULES, modelingRules); + } + + initialHints.setHint(SynchronizationHints.COPY_ADVISOR, getCopyAdvisor()); + } + protected IElementClassProvider createElementClassProvider(ReadGraph graph) throws DatabaseException { DiagramResource dr = DiagramResource.getInstance(graph); return ElementClassProviders.mappedProvider( diff --git a/bundles/org.simantics.modeling/META-INF/MANIFEST.MF b/bundles/org.simantics.modeling/META-INF/MANIFEST.MF index d23076695..e3aa4fd37 100644 --- a/bundles/org.simantics.modeling/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.modeling/META-INF/MANIFEST.MF @@ -47,6 +47,7 @@ Export-Package: org.simantics.modeling, org.simantics.modeling.adapters, org.simantics.modeling.export, org.simantics.modeling.flags, + org.simantics.modeling.help, org.simantics.modeling.mapping, org.simantics.modeling.migration, org.simantics.modeling.preferences, diff --git a/bundles/org.simantics.modeling/scl/Simantics/ChangeInformation.scl b/bundles/org.simantics.modeling/scl/Simantics/ChangeInformation.scl new file mode 100644 index 000000000..9d858d9d6 --- /dev/null +++ b/bundles/org.simantics.modeling/scl/Simantics/ChangeInformation.scl @@ -0,0 +1,2 @@ +importJava "org.simantics.modeling.adapters.ChangeInformation" where + data ChangeInformation diff --git a/bundles/org.simantics.modeling/scl/Simantics/Testing.scl b/bundles/org.simantics.modeling/scl/Simantics/Testing.scl index f1ebaf50c..08f9f2868 100644 --- a/bundles/org.simantics.modeling/scl/Simantics/Testing.scl +++ b/bundles/org.simantics.modeling/scl/Simantics/Testing.scl @@ -11,5 +11,6 @@ importJava "org.simantics.modeling.ContentDumps" where pgraphContentDump :: Resource -> Vector Byte graphFileContentDump :: Resource -> Vector Byte structuralComponentContentDump :: Resource -> Vector Byte + structuralComponentTypeContentDump :: Resource -> Vector Byte genericParameterTypeContentDump :: Resource -> Vector Byte diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ContentDumps.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ContentDumps.java index 687544e78..39ed968dd 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ContentDumps.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ContentDumps.java @@ -2,6 +2,8 @@ package org.simantics.modeling; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; +import java.util.Collection; +import java.util.Map; import java.util.TreeMap; import java.util.TreeSet; @@ -9,6 +11,7 @@ import org.simantics.databoard.Bindings; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.utils.CommonDBUtils; +import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; @@ -47,12 +50,10 @@ public class ContentDumps { return graph.getRelatedValue(resource, GF.HasFiledata, Bindings.BYTE_ARRAY); } - public static byte[] structuralComponentContentDump(ReadGraph graph, Resource resource) throws DatabaseException { - - StringBuilder dump = new StringBuilder(); + private static StringBuilder structuralComponentContentDump(ReadGraph graph, Resource resource, StringBuilder dump) throws DatabaseException { Variable v = Variables.getVariable(graph, resource); - + TreeSet types = new TreeSet<>(); for(Resource t : graph.getPrincipalTypes(resource)) { types.add(graph.getURI(t)); @@ -87,6 +88,47 @@ public class ContentDumps { dump.append("\n"); } } + + return dump; + } + + public static byte[] structuralComponentContentDump(ReadGraph graph, Resource resource) throws DatabaseException { + return structuralComponentContentDump(graph, resource, new StringBuilder()).toString().getBytes(UTF8); + } + + public static byte[] structuralComponentTypeContentDump(ReadGraph graph, Resource resource) throws DatabaseException { + StringBuilder dump = structuralComponentContentDump(graph, resource, new StringBuilder()); + + StructuralResource2 STR = StructuralResource2.getInstance(graph); + + // Dump procedural component type code if present + String proceduralCode = graph.getPossibleRelatedValue(resource, STR.ProceduralComponentType_code, Bindings.STRING); + if (proceduralCode != null) { + dump + .append("\n---- ProceduralComponentType.code begins ----\n") + .append(proceduralCode) + .append("---- ProceduralComponentType.code ends ----\n"); + } + + // Dump component type SCL scripts + Collection scripts = graph.getObjects(resource, STR.ComponentType_hasScript); + if (!scripts.isEmpty()) { + dump.append("\nComponentType.hasScript (").append(scripts.size()).append(")\n"); + TreeMap sortedScripts = new TreeMap<>(); + for (Resource script : scripts) + sortedScripts.put(NameUtils.getSafeName(graph, script), script); + for (Map.Entry entry : sortedScripts.entrySet()) { + String name = entry.getKey(); + Resource script = entry.getValue(); + String type = graph.getPossibleRelatedValue(script, STR.ComponentTypeScript_type, Bindings.STRING); + String code = graph.getPossibleRelatedValue(script, STR.ComponentTypeScript_code, Bindings.STRING); + dump + .append("---- script `").append(name).append("` of type `").append(type).append("` begins ----\n") + .append(code) + .append("\n---- script `").append(name).append("` of type `").append(type).append("` ends ----\n"); + } + } + return dump.toString().getBytes(UTF8); } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java index 5bcce3ee4..6293cbac9 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitor.java @@ -1,14 +1,6 @@ package org.simantics.modeling; -import java.util.Stack; - import org.simantics.basicexpression.Expressions; -import org.simantics.basicexpression.analysis.DepthFirstAdapter; -import org.simantics.basicexpression.node.AConstantValue; -import org.simantics.basicexpression.node.ADivMultiplicative; -import org.simantics.basicexpression.node.AMultMultiplicative; -import org.simantics.basicexpression.node.APlusExpression; -import org.simantics.basicexpression.node.AVariablePrimary; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.WriteGraph; @@ -19,110 +11,14 @@ import org.simantics.structural.stubs.StructuralResource2; import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.Triple; -public class InvertBasicExpressionVisitor extends DepthFirstAdapter { - - Stack stack = new Stack(); - - public Object getResult() { - if(stack.size() != 1) return null; - return stack.pop(); - } - - public void outAConstantValue(AConstantValue node) { - stack.push(Double.valueOf(node.toString())); - } - - @Override - public void outAVariablePrimary(AVariablePrimary node) { - String value = node.toString().trim(); - stack.push(Triple.make(1.0, 0.0, value)); - } - - @SuppressWarnings("unchecked") - public void outAPlusExpression(APlusExpression node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(p.first, p.second + (Double)o1, p.third)); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first, p.second + (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 + (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outAMinusExpression(APlusExpression node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(-p.first, (Double)o1 - p.second, p.third )); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first, p.second - (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 - (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outAMultMultiplicative(AMultMultiplicative node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - Triple p = (Triple)o2; - stack.push(Triple.make(p.first * (Double)o1, p.second * (Double)o1, p.third)); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first * (Double)o2, p.second * (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 * (Double)o2); - } else { - stack.push(Double.NaN); - } - - } - - @SuppressWarnings("unchecked") - public void outADivMultiplicative(ADivMultiplicative node) { - - final Object o1 = stack.pop(); - final Object o2 = stack.pop(); - - if(o1 instanceof Double && o2 instanceof Triple) { - stack.push(Double.NaN); - } else if (o2 instanceof Double && o1 instanceof Triple) { - Triple p = (Triple)o1; - stack.push(Triple.make(p.first / (Double)o2, p.second / (Double)o2, p.third)); - } else if (o2 instanceof Double && o1 instanceof Double) { - stack.push((Double)o1 / (Double)o2); - } else { - stack.push(Double.NaN); - } - - } +public class InvertBasicExpressionVisitor extends InvertBasicExpressionVisitorBase { private static final String MAGIC = "_111_"; - + private static String replaced(String expression) { return expression.replaceAll("\\.([A-Za-z])", MAGIC + "$1"); } - + public static void invert(WriteGraph graph, Variable base, String expression, Object value) throws DatabaseException { InvertBasicExpressionVisitor visitor = new InvertBasicExpressionVisitor(); Expressions.evaluate(replaced(expression), visitor); @@ -208,26 +104,36 @@ public class InvertBasicExpressionVisitor extends DepthFirstAdapter { } - public static Variable possibleInvertibleExpressionReferencedProperty(ReadGraph graph, Variable base, String expression) throws DatabaseException { + @SuppressWarnings("unchecked") + private static Triple possibleInvertibleExpression(ReadGraph graph, Variable base, String expression) throws DatabaseException { if (base == null || expression == null || expression.isEmpty()) return null; InvertBasicExpressionVisitor visitor = new InvertBasicExpressionVisitor(); //System.out.println("invert : " + expression + " -> " + replaced(expression) + " for " + base.getURI(graph)); Expressions.evaluate(replaced(expression), visitor); - Object pair = visitor.getResult(); - if(pair == null) - return null; - if(pair instanceof Triple) { - @SuppressWarnings("unchecked") - Triple data = (Triple)pair; - String key = data.third.replace(MAGIC,"."); - String path = getVariablePath(graph, base, key); - if (path == null) - return null; - Variable targetVariable = base.browsePossible(graph, path); - return targetVariable; - } + Object result = visitor.getResult(); + if (result instanceof Triple) + return (Triple) result; return null; } + public static Variable possibleInvertibleExpressionReferencedProperty(ReadGraph graph, Variable base, String expression) throws DatabaseException { + Triple data = possibleInvertibleExpression(graph, base, expression); + if (data == null) + return null; + String path = getVariablePath(graph, base, data.third.replace(MAGIC, ".")); + return path != null ? base.browsePossible(graph, path) : null; + } + + public static Triple possibleInvertibleExpressionReferencedTransformedProperty(ReadGraph graph, Variable base, String expression) throws DatabaseException { + Triple data = possibleInvertibleExpression(graph, base, expression); + if (data == null) + return null; + String path = getVariablePath(graph, base, data.third.replace(MAGIC, ".")); + if (path == null) + return null; + Variable targetVariable = base.browsePossible(graph, path); + return targetVariable != null ? Triple.make(data.first, data.second, targetVariable) : null; + } + } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitorBase.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitorBase.java new file mode 100644 index 000000000..8ccf5c28c --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/InvertBasicExpressionVisitorBase.java @@ -0,0 +1,141 @@ +/******************************************************************************* + * Copyright (c) 2020 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy - initial API and implementation + *******************************************************************************/ +package org.simantics.modeling; + +import java.util.Stack; + +import org.simantics.basicexpression.analysis.DepthFirstAdapter; +import org.simantics.basicexpression.node.AConstantValue; +import org.simantics.basicexpression.node.ADivMultiplicative; +import org.simantics.basicexpression.node.AMinusExpression; +import org.simantics.basicexpression.node.AMultMultiplicative; +import org.simantics.basicexpression.node.APlusExpression; +import org.simantics.basicexpression.node.AVariablePrimary; +import org.simantics.utils.datastructures.Triple; + +/** + * @author Tuukka Lehtonen + */ +public class InvertBasicExpressionVisitorBase extends DepthFirstAdapter { + + protected Stack stack = new Stack<>(); + + public InvertBasicExpressionVisitorBase() { + super(); + } + + public Object getResult() { + if(stack.size() != 1) return null; + return stack.pop(); + } + + @Override + public void outAConstantValue(AConstantValue node) { + stack.push(Double.valueOf(node.toString())); + } + + @Override + public void outAVariablePrimary(AVariablePrimary node) { + String value = node.toString().trim(); + stack.push(Triple.make(1.0, 0.0, value)); + } + + @SuppressWarnings("unchecked") + @Override + public void outAPlusExpression(APlusExpression node) { + + final Object o1 = stack.pop(); + final Object o2 = stack.pop(); + + if(o1 instanceof Double && o2 instanceof Triple) { + Triple p = (Triple)o2; + stack.push(Triple.make(p.first, p.second + (Double)o1, p.third)); + } else if (o2 instanceof Double && o1 instanceof Triple) { + Triple p = (Triple)o1; + stack.push(Triple.make(p.first, p.second + (Double)o2, p.third)); + } else if (o2 instanceof Double && o1 instanceof Double) { + stack.push((Double)o1 + (Double)o2); + } else { + stack.push(Double.NaN); + } + + } + + @SuppressWarnings("unchecked") + @Override + public void outAMinusExpression(AMinusExpression node) { + + final Object o1 = stack.pop(); + final Object o2 = stack.pop(); + + // o2 - o1 + if(o1 instanceof Double && o2 instanceof Triple) { + // o2 - double o1 + Triple p = (Triple)o2; + stack.push(Triple.make(p.first, p.second - (Double)o1, p.third)); + } else if (o2 instanceof Double && o1 instanceof Triple) { + // double o2 - o1 + Triple p = (Triple)o1; + stack.push(Triple.make(-p.first, (Double)o2 - p.second, p.third)); + } else if (o2 instanceof Double && o1 instanceof Double) { + stack.push((Double)o2 - (Double)o1); + } else { + stack.push(Double.NaN); + } + + } + + @SuppressWarnings("unchecked") + @Override + public void outAMultMultiplicative(AMultMultiplicative node) { + + final Object o1 = stack.pop(); + final Object o2 = stack.pop(); + + if(o1 instanceof Double && o2 instanceof Triple) { + Triple p = (Triple)o2; + stack.push(Triple.make(p.first * (Double)o1, p.second * (Double)o1, p.third)); + } else if (o2 instanceof Double && o1 instanceof Triple) { + Triple p = (Triple)o1; + stack.push(Triple.make(p.first * (Double)o2, p.second * (Double)o2, p.third)); + } else if (o2 instanceof Double && o1 instanceof Double) { + stack.push((Double)o1 * (Double)o2); + } else { + stack.push(Double.NaN); + } + + } + + @SuppressWarnings("unchecked") + @Override + public void outADivMultiplicative(ADivMultiplicative node) { + + final Object o1 = stack.pop(); + final Object o2 = stack.pop(); + + // o2 / o1 + if(o1 instanceof Double && o2 instanceof Triple) { + // o2 / double o1 + Triple p = (Triple)o2; + stack.push(Triple.make(p.first / (Double)o1, p.second / (Double)o1, p.third)); + } else if (o2 instanceof Double && o1 instanceof Triple) { + // double o2 / o1 + stack.push(Double.NaN); + } else if (o2 instanceof Double && o1 instanceof Double) { + stack.push((Double)o2 / (Double)o1); + } else { + stack.push(Double.NaN); + } + + } + +} \ No newline at end of file diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java index 1edf3cd31..516fe6231 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java @@ -70,6 +70,7 @@ import org.simantics.db.Session; import org.simantics.db.Statement; import org.simantics.db.VirtualGraph; import org.simantics.db.WriteGraph; +import org.simantics.db.WriteOnlyGraph; import org.simantics.db.common.Indexing; import org.simantics.db.common.NamedResource; import org.simantics.db.common.QueryMemoryWatcher; @@ -82,6 +83,7 @@ import org.simantics.db.common.request.ObjectsWithType; import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.request.ReadRequest; import org.simantics.db.common.request.ResourceRead2; +import org.simantics.db.common.request.WriteOnlyRequest; import org.simantics.db.common.request.WriteRequest; import org.simantics.db.common.request.WriteResultRequest; import org.simantics.db.common.utils.ListUtils; @@ -123,7 +125,6 @@ import org.simantics.db.layer0.util.SimanticsKeys; import org.simantics.db.layer0.util.TransferableGraphConfiguration2; import org.simantics.db.layer0.variable.Variable; import org.simantics.db.layer0.variable.Variables; -import org.simantics.db.request.Read; import org.simantics.db.service.ClusterControl; import org.simantics.db.service.CollectionSupport; import org.simantics.db.service.GraphChangeListenerSupport; @@ -2459,16 +2460,34 @@ public class ModelingUtils { return DiagramGraphUtil.getModelingRules(graph, diagramResource, null); } + //------------------------------------------------------------------------- + + private static final String VG_CHANGE_INFORMATION = "changeInformation"; //$NON-NLS-1$ + public static void markChanged(WriteGraph graph, Resource r) throws DatabaseException { - VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class); - VirtualGraph vg = support.getWorkspacePersistent("changeInformation"); - graph.syncRequest(new WriteRequest(vg) { + VirtualGraph vg = Simantics.getSession().getService(VirtualGraphSupport.class) + .getWorkspacePersistent(VG_CHANGE_INFORMATION); + ModelingResources MOD = ModelingResources.getInstance(graph); + graph.syncRequest(new WriteOnlyRequest(vg) { @Override - public void perform(WriteGraph graph) throws DatabaseException { - ModelingResources MOD = ModelingResources.getInstance(graph); + public void perform(WriteOnlyGraph graph) throws DatabaseException { graph.claim(r, MOD.changed, MOD.changed, r); } }); } - + + public static void markChanged(RequestProcessor processor, Iterable rs) throws DatabaseException { + VirtualGraph vg = Simantics.getSession().getService(VirtualGraphSupport.class) + .getWorkspacePersistent(VG_CHANGE_INFORMATION); + ModelingResources MOD = ModelingResources.getInstance(processor); + processor.syncRequest(new WriteOnlyRequest(vg) { + @Override + public void perform(WriteOnlyGraph graph) throws DatabaseException { + for (Resource r : rs) { + graph.claim(r, MOD.changed, MOD.changed, r); + } + } + }); + } + } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java index e8c54fa98..6256891b8 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/ProceduralSubstructureMapRequest.java @@ -3,6 +3,7 @@ package org.simantics.modeling; import gnu.trove.map.hash.THashMap; import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.db.layer0.request.PropertyInfoRequest; @@ -21,19 +22,28 @@ public class ProceduralSubstructureMapRequest extends VariableRead> perform(ReadGraph graph) throws DatabaseException { THashMap> propertyMap = new THashMap>(); for(Variable child : variable.getChildren(graph)) { - for(Variable property : child.getProperties(graph)) { - PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(property.getPredicateResource(graph))); + for(Variable property : child.getProperties(graph)) { + Resource predicate = property.getPossiblePredicateResource(graph); + if (predicate == null) + continue; + + PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(predicate)); propertyMap.put(child.getName(graph) + "." + propertyInfo.name, Pair.make("/" + child.getName(graph) + "#" + propertyInfo.name, SCLTypeUtils.getType(propertyInfo))); - } + } } - for(Variable property : variable.getProperties(graph)) { - PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(property.getPredicateResource(graph))); + for(Variable property : variable.getProperties(graph)) { + Resource predicate = property.getPossiblePredicateResource(graph); + if (predicate == null) + continue; + + PropertyInfo propertyInfo = graph.syncRequest(new PropertyInfoRequest(predicate)); propertyMap.put(propertyInfo.name, Pair.make("#" + propertyInfo.name, SCLTypeUtils.getType(propertyInfo))); - } + } + return propertyMap; } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java index db65b4de3..82115ef0e 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLScenegraph.java @@ -51,6 +51,7 @@ import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.DiagramHints; import org.simantics.g2d.diagram.IDiagram; import org.simantics.g2d.diagram.handler.DataElementMap; +import org.simantics.g2d.diagram.participant.ElementPainter.SelectionShapeNode; import org.simantics.g2d.diagram.participant.Selection; import org.simantics.g2d.element.IElement; import org.simantics.g2d.scenegraph.ICanvasSceneGraphProvider; @@ -964,9 +965,31 @@ public class SCLScenegraph { if (!hasContent) return; String svg = printSVGDocument(doc); - parentBuilder.append(MAIN_SECTION, ""); - parentBuilder.append(MAIN_SECTION, svg); - parentBuilder.append(MAIN_SECTION, "\n"); + if (node instanceof SelectionShapeNode) { + SingleElementNode parentSEN = (SingleElementNode)NodeUtil.getNearestParentOfType(node, SingleElementNode.class); + if(parentSEN != null) { + String key = getKey(parentSEN); + RenderSVGContext parentBuilder2 = getParentBuilder(parentSEN); + parentBuilder2.append(SELECTION_SECTION, "\n"); + parentBuilder2.append(SELECTION_SECTION, svg); + parentBuilder2.append(SELECTION_SECTION, "\n"); + + parentBuilder2.append(SELECTION_MASK_SECTION, "\n"); + Rectangle2D rect = node.getBounds(); + // NaN + if(rect.getHeight() == rect.getHeight() && rect.getWidth() == rect.getWidth()) { + parentBuilder2.append(SELECTION_MASK_SECTION,""); + } + parentBuilder2.append(SELECTION_MASK_SECTION,"\n"); + } + } else { + parentBuilder.append(MAIN_SECTION, ""); + parentBuilder.append(MAIN_SECTION, svg); + parentBuilder.append(MAIN_SECTION, "\n"); + } } catch (Exception e) { // TODO: There are nodes that do not behave well when rendered to SVG. For backwards compatibility, we don't handle the exceptions. } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLTypeUtils.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLTypeUtils.java index 27955fb7e..eeabbd960 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLTypeUtils.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/SCLTypeUtils.java @@ -13,6 +13,7 @@ import org.simantics.databoard.type.LongType; import org.simantics.databoard.type.StringType; import org.simantics.db.layer0.request.PropertyInfo; import org.simantics.scl.compiler.types.TCon; +import org.simantics.scl.compiler.types.TVar; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.kinds.Kinds; @@ -23,6 +24,8 @@ public class SCLTypeUtils { private static final Logger LOGGER = LoggerFactory.getLogger(SCLTypeUtils.class); private static final THashMap TYPE_MAP = new THashMap(); + private static final TVar STAR = Types.var(Kinds.STAR); + private static void add(TCon type) { TYPE_MAP.put(type.name, type); } @@ -66,6 +69,7 @@ public class SCLTypeUtils { Types.functionE(new Type[] {variable, Types.RESOURCE}, Types.READ_GRAPH, Types.RESOURCE)); add((TCon)Types.RESOURCE); + add(Types.con("Simantics/ChangeInformation", "ChangeInformation")); // MOD.ChangeInformation add(Types.con("Simantics/GUID", "GUID")); // L0.GUID add(Types.con("Simantics/Variables", "StructuredProperty")); // L0.methods add(Types.con("Simantics/Variables", "ValueAccessor")); // L0.ValueAccessor @@ -81,7 +85,7 @@ public class SCLTypeUtils { Type type = TYPE_MAP.get(typeText); if(type == null) { LOGGER.warn("SCLTypeUtils.getType cannot transform '" + typeText + "' to type. Returns a as default."); - return Types.var(Kinds.STAR); + return STAR; } return type; } @@ -105,18 +109,23 @@ public class SCLTypeUtils { return Types.list(getType(((ArrayType)dataType).componentType)); else { LOGGER.warn("SCLTypeUtils.getType cannot transform data type '" + dataType + "' to type. Returns a as default."); - return Types.var(Kinds.STAR); + return STAR; } } - public static Type getType(PropertyInfo propertyInfo) { + public static Type getType(PropertyInfo propertyInfo, boolean warnOfNoTypeInformation) { if(propertyInfo.requiredValueType != null) return getType(propertyInfo.requiredValueType); else if(propertyInfo.requiredDatatype != null) return getType(propertyInfo.requiredDatatype); else { - LOGGER.warn(propertyInfo.name + " doesn't have type information. Returns a as default."); - return Types.var(Kinds.STAR); + if (warnOfNoTypeInformation) + LOGGER.warn(propertyInfo.name + " doesn't have type information. Returns a as default."); + return STAR; } } + + public static Type getType(PropertyInfo propertyInfo) { + return getType(propertyInfo, propertyInfo.isHasProperty); + } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/Help.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/Help.java index ba1243108..22327aeb3 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/Help.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/actions/Help.java @@ -16,38 +16,36 @@ import org.simantics.Simantics; import org.simantics.databoard.Bindings; import org.simantics.db.Resource; import org.simantics.db.common.primitiverequest.PossibleRelatedValue2; -import org.simantics.db.common.utils.Logger; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.adapter.ActionFactory; import org.simantics.modeling.ModelingResources; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class Help implements ActionFactory { + private static final Logger LOGGER = LoggerFactory.getLogger(Help.class); + @Override public Runnable create(Object target) { - - if(!(target instanceof Resource)) + if (!(target instanceof Resource)) return null; - final Resource resource = (Resource)target; - - return new Runnable() { - @Override - public void run() { - - try { - ModelingResources MOD = ModelingResources.getInstance(Simantics.getSession()); - String id = Simantics.sync(new PossibleRelatedValue2(resource, MOD.contextualHelpId, Bindings.STRING)); - if(id == null) { - PlatformUI.getWorkbench().getHelpSystem().displayDynamicHelp(); - return; - } - PlatformUI.getWorkbench().getHelpSystem().displayHelp(id); - } catch (DatabaseException e) { - Logger.defaultLogError(e); + final Resource resource = (Resource) target; + + return () -> { + try { + ModelingResources MOD = ModelingResources.getInstance(Simantics.getSession()); + String id = Simantics.sync(new PossibleRelatedValue2(resource, MOD.contextualHelpId, Bindings.STRING)); + if (id == null) { + PlatformUI.getWorkbench().getHelpSystem().displayDynamicHelp(); + return; } - + PlatformUI.getWorkbench().getHelpSystem().displayHelp(id); + } catch (DatabaseException e) { + LOGGER.error("Failed to display help for resource {}", resource, e); } }; } + } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/help/HelpContexts.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/help/HelpContexts.java new file mode 100644 index 000000000..ca25cf417 --- /dev/null +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/help/HelpContexts.java @@ -0,0 +1,73 @@ +/******************************************************************************* + * Copyright (c) 2020 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Semantum Oy- initial API and implementation + *******************************************************************************/ +package org.simantics.modeling.help; + +import org.simantics.databoard.Bindings; +import org.simantics.db.ReadGraph; +import org.simantics.db.Resource; +import org.simantics.db.exception.DatabaseException; +import org.simantics.db.layer0.variable.Variable; +import org.simantics.modeling.ModelingResources; +import org.simantics.modeling.PropertyVariables; +import org.simantics.utils.ui.AdaptionUtils; + +/** + * @author Tuukka Lehtonen + * @since 1.46.0 + */ +public class HelpContexts { + + /** + * @param graph + * @param resource + * @param variable + * @param selection optional ISelection + * @return + * @throws DatabaseException + */ + public static String getPossibleId(ReadGraph graph, Resource resource, Variable variable, Object selection) throws DatabaseException { + ModelingResources MOD = ModelingResources.getInstance(graph); + if (resource != null) { + Resource component = graph.getPossibleObject(resource, MOD.ElementToComponent); + String id = component != null ? graph.getPossibleRelatedValue2(component, MOD.contextualHelpId, Bindings.STRING) : null; + if (id != null) + return id; + id = graph.getPossibleRelatedValue2(resource, MOD.contextualHelpId, Bindings.STRING); + if (id != null) + return id; + } + + if (variable != null) { + String id = variable.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING); + if (id != null) + return id; + } + + // TODO: consider removing this block + if (selection != null) { + PropertyVariables vars = AdaptionUtils.adaptToSingle(selection, PropertyVariables.class); + Variable var = vars != null ? vars.getConfiguration() : null; + String id = var != null ? var.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING) : null; + if (id != null) + return id; + } + + return null; + } + + public static String getPossibleId(ReadGraph graph, Variable variable, String property) throws DatabaseException { + ModelingResources MOD = ModelingResources.getInstance(graph); + Variable prop = variable != null ? variable.getPossibleProperty(graph, property) : null; + return prop != null ? prop.getPossiblePropertyValue(graph, MOD.contextualHelpId, Bindings.STRING) : null; + } + +} diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java index 3e6e9c1b9..021ecc436 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/mapping/ComponentCopyAdvisor.java @@ -32,7 +32,6 @@ import org.simantics.modeling.ModelingUtils; import org.simantics.modeling.services.ComponentNamingUtil; import org.simantics.modeling.services.NamingException; import org.simantics.project.IProject; -import org.simantics.structural.stubs.StructuralResource2; import gnu.trove.map.hash.THashMap; @@ -58,7 +57,6 @@ public class ComponentCopyAdvisor extends GraphCopyAdvisor { @Override public Object copy(ISynchronizationContext context, WriteGraph graph, Resource source, Resource sourceContainer, Resource targetContainer, Map map) throws DatabaseException { - StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource copy = CopyAdvisorUtil.copy2(graph, source, null, map); Layer0 L0 = Layer0.getInstance(graph); diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileProceduralSCLMonitorRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileProceduralSCLMonitorRequest.java index 4c7964513..79eb3d6ba 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileProceduralSCLMonitorRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileProceduralSCLMonitorRequest.java @@ -11,7 +11,7 @@ import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.request.VariableRead; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; -import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; +import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.modeling.ProceduralSubstructureMapRequest; @@ -88,7 +88,7 @@ public class CompileProceduralSCLMonitorRequest extends AbstractExpressionCompil public CompilationContext perform(ReadGraph graph) throws DatabaseException { Resource indexRoot = graph.syncRequest(new IndexRoot(componentType)); - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(indexRoot)); + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest2(componentType, indexRoot)); THashMap> propertyMap = graph.sync(new ProceduralSubstructureMapRequest(componentVariable)); return new CompilationContext(runtimeEnvironment, propertyMap); diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLMonitorRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLMonitorRequest.java index dfea83931..b9ec1affc 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLMonitorRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLMonitorRequest.java @@ -9,7 +9,7 @@ import org.simantics.db.common.request.ResourceRead; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; -import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; +import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.modeling.ComponentTypeSubstructure; @@ -114,7 +114,7 @@ public class CompileSCLMonitorRequest extends AbstractExpressionCompilationReque public CompilationContext perform(ReadGraph graph) throws DatabaseException { Resource indexRoot = graph.syncRequest(new IndexRoot(resource)); - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(indexRoot)); + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest2(resource, indexRoot)); return new CompilationContext(runtimeEnvironment, ComponentTypeSubstructure.forType(graph, resource)); } }); diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java index 1cef75ddf..dab7aa0e7 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/CompileSCLQueryRequest.java @@ -7,8 +7,8 @@ import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.IndexRoot; import org.simantics.db.common.request.ResourceRead2; +import org.simantics.db.common.request.RuntimeEnvironmentRequest; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; import org.simantics.db.layer0.variable.Variable; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.common.names.Name; diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/userComponent/ComponentTypeCommands.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/userComponent/ComponentTypeCommands.java index 9cf93fac5..de8591d5f 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/userComponent/ComponentTypeCommands.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/userComponent/ComponentTypeCommands.java @@ -209,6 +209,7 @@ public class ComponentTypeCommands { public static void setRequiredType(WriteGraph g, Resource componentType, Resource property, String requiredType, Resource possibleType) throws DatabaseException { Layer0 L0 = Layer0.getInstance(g); + ModelingResources MOD = ModelingResources.getInstance(g); g.claimLiteral(property, L0.RequiresValueType, requiredType); if (componentType != null) { @@ -229,6 +230,9 @@ public class ComponentTypeCommands { if(g.hasStatement(possibleType, L0.Enumeration)) { // This value type is an enumeration - let's constrain the range of this predicate to match the enumeration type only g.claim(property, L0.HasRange, possibleType); + } else if (g.isInheritedFrom(possibleType, MOD.MonitorValue)) { + // Support derived properties + g.claim(property, L0.HasRange, possibleType); } } diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/DumpOntologyStructure.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/DumpOntologyStructure.java index 5bb3d9ca2..e058f2c36 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/DumpOntologyStructure.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/DumpOntologyStructure.java @@ -5,7 +5,9 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; import java.util.TreeMap; import org.simantics.Simantics; @@ -32,17 +34,48 @@ public class DumpOntologyStructure { private Resource ontology; private Map names = new HashMap<>(); - private Map parents = new HashMap<>(); + private Map parents = new TreeMap<>(); private Map libraryFolders = new HashMap<>(); private Map contentDumps = new HashMap<>(); private void readNameAndParent(ReadGraph graph, Resource container, Resource r) throws DatabaseException { + String name = NameUtils.getSafeName(graph, r); parents.put(r, container); - names.put(r, NameUtils.getSafeName(graph, r)); + names.put(r, FileUtils.escapeFileName(name)); } - private Collection containers() { - return parents.values(); + /* + * This shall return containers sorted by full path. + * This makes processing order stable and ensures that + * directories are processed before their contents. + */ + private Collection sortedContainers(File rootFolder) { + Set parentSet = new HashSet(parents.values()); + TreeMap result = new TreeMap<>(); + for(Resource r : parentSet) { + File f = getFolder(rootFolder, r); + result.put(f.getAbsolutePath(), r); + } + return result.values(); + } + + private Collection sortedResources(File rootFolder) { + TreeMap result = new TreeMap<>(); + for(Resource r : parents.keySet()) { + byte[] dump = contentDumps.get(r); + if(dump == null) + dump = "".getBytes(StandardCharsets.UTF_8); + if(isParent(r)) { + if(dump.length > 0) { + File f = new File(getFolder(rootFolder, r), "__contents__"); + result.put(f.getAbsolutePath(), r); + } + } else { + File f = getFile(rootFolder, r); + result.put(f.getAbsolutePath(), r); + } + } + return result.values(); } private void readHierarchy(ReadGraph graph, Resource container) throws DatabaseException { @@ -110,37 +143,56 @@ public class DumpOntologyStructure { public void write(File unsafeFolder) throws IOException { File folder = escapeFile(unsafeFolder); FileUtils.delete(folder.toPath()); - folder.mkdirs(); + folder.getParentFile().mkdirs(); writeDirectories(folder); writeResources(folder); } + Resource getParent(Resource r) { + return parents.get(r); + } + private File getFolder(File root, Resource library) { if(ontology.equals(library)) return root; - Resource parent = parents.get(library); + Resource parent = getParent(library); if(parent == null) throw new IllegalStateException("null parent for " + library); File parentFolder = getFolder(root, parent); - return new File(parentFolder, FileUtils.escapeFileName(names.get(library))); + return new File(parentFolder, names.get(library)); } private File getFile(File rootFolder, Resource r) { - Resource parent = parents.get(r); + Resource parent = getParent(r); File folder = getFolder(rootFolder, parent); - return new File(folder, FileUtils.escapeFileName(names.get(r))); + return new File(folder, names.get(r)); } + private File makeUnique(File original, Resource r) { + int counter = 2; + File file = new File(original.getParent(), original.getName()); + File test = file; + while(test.exists()) { + // Here we have a name clash with small and big letters! (windows) + test = new File(file.getParent(), file.getName() + "____" + (counter++)); + } + // Enforce this renaming in future operations also + names.put(r, test.getName()); + return test; + } + private void writeDirectories(File rootFolder) { - for(Resource library : containers()) { - File folder = getFolder(rootFolder, library); + // Here stuff shall be returned in alphabetical order + for(Resource library : sortedContainers(rootFolder)) { + File folder = makeUnique(getFolder(rootFolder, library), library); folder.mkdirs(); libraryFolders.put(library, folder); } } private void writeResources(File rootFolder) throws IOException { - for(Resource r : parents.keySet()) { + // Here stuff shall be returned in alphabetical order + for(Resource r : sortedResources(rootFolder)) { writeResource(rootFolder, r); } } @@ -162,7 +214,7 @@ public class DumpOntologyStructure { } private void write(File rootFolder, Resource resource, byte[] bytes) throws IOException { - FileUtils.writeFile(getFile(rootFolder, resource), bytes); + FileUtils.writeFile(makeUnique(getFile(rootFolder, resource), resource), bytes); } } \ No newline at end of file diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/OntologicalRequirementEnforceRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/OntologicalRequirementEnforceRequest.java index 3f8ffb15b..d8eed0a66 100644 --- a/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/OntologicalRequirementEnforceRequest.java +++ b/bundles/org.simantics.modeling/src/org/simantics/modeling/utils/OntologicalRequirementEnforceRequest.java @@ -21,17 +21,28 @@ import org.simantics.modeling.adapters.ChangeInformation; */ public class OntologicalRequirementEnforceRequest extends WriteRequest { + private static final String PROP_WRITE_CHANGED_TAGS = "org.simantics.modeling.writeChangedTags"; //$NON-NLS-1$ + private Collection creates; private Collection modis; private Collection ids; private String author; private long time; + private static String getAuthor() { + return System.getProperty("user.name", ""); //$NON-NLS-1$ //$NON-NLS-2$ + } + + private static boolean writeChangedTags() { + return !System.getProperty(PROP_WRITE_CHANGED_TAGS, "") //$NON-NLS-1$ + .equalsIgnoreCase("false"); //$NON-NLS-1$ + } + public OntologicalRequirementEnforceRequest(Collection creates, Collection modis, Collection ids) { this(creates, modis, ids, - System.getProperty("user.name", ""), + getAuthor(), System.currentTimeMillis()); } @@ -45,7 +56,7 @@ public class OntologicalRequirementEnforceRequest extends WriteRequest { @Override public void perform(WriteGraph graph) throws DatabaseException { - update(graph, creates, modis, ids, true, author, time, true); + update(graph, creates, modis, ids, true, author, time, true, writeChangedTags()); } public static void update( @@ -61,7 +72,7 @@ public class OntologicalRequirementEnforceRequest extends WriteRequest { modis, ids, addComment, - System.getProperty("user.name", ""), + getAuthor(), System.currentTimeMillis(), disableDependencyIndexing); @@ -76,10 +87,24 @@ public class OntologicalRequirementEnforceRequest extends WriteRequest { String author, long time, boolean disableDependencyIndexing) throws DatabaseException + { + update(graph, creates, modis, ids, addComment, author, time, disableDependencyIndexing, writeChangedTags()); + } + + public static void update( + WriteGraph graph, + Collection creates, + Collection modis, + Collection ids, + boolean addComment, + String author, + long time, + boolean disableDependencyIndexing, + boolean writeChangedTags) throws DatabaseException { if (disableDependencyIndexing) Layer0Utils.setDependenciesIndexingDisabled(graph, true); - + ModelingResources MOD = ModelingResources.getInstance(graph); Layer0 L0 = Layer0.getInstance(graph); @@ -93,8 +118,9 @@ public class OntologicalRequirementEnforceRequest extends WriteRequest { for (Resource c : creates) { CommonDBUtils.selectClusterSet(graph, c); graph.claimLiteral(c, MOD.changeInformation, MOD.changeInformation_Inverse, MOD.ChangeInformation, info, ChangeInformation.BINDING); - ModelingUtils.markChanged(graph, c); } + if (writeChangedTags) + ModelingUtils.markChanged(graph, creates); } for (Resource m : modis) { @@ -109,9 +135,10 @@ public class OntologicalRequirementEnforceRequest extends WriteRequest { info.modifiedBy = author; CommonDBUtils.selectClusterSet(graph, m); graph.claimLiteral(m, MOD.changeInformation, MOD.changeInformation_Inverse, MOD.ChangeInformation, info, ChangeInformation.BINDING); - ModelingUtils.markChanged(graph, m); } - + if (writeChangedTags) + ModelingUtils.markChanged(graph, modis); + for (Resource r : ids) { if (!graph.hasStatement(r, L0.identifier)) { CommonDBUtils.selectClusterSet(graph, r); @@ -119,10 +146,8 @@ public class OntologicalRequirementEnforceRequest extends WriteRequest { } } - graph.addMetadata( graph.getMetadata(CommentMetadata.class).add("Updated change information") ); - + graph.addMetadata( graph.getMetadata(CommentMetadata.class).add("Updated change information") ); //$NON-NLS-1$ graph.addMetadata( graph.getMetadata(ChangeHistoryUpdated.class) ); - } } \ No newline at end of file diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementRule.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementRule.java index a0b7befed..251895ad7 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementRule.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementRule.java @@ -67,7 +67,7 @@ public class MappedElementRule implements IBidirectionalMappingRu public boolean checkChanges(ReadGraph g, IForwardMapping map, Domain domainElement, Range rangeElement) throws MappingException { Domain value = domainAccessor.get(g, domainElement); Range mappedValue = value == null ? null : map.map(g, value); - return mappedValue == rangeAccessor.get(rangeElement); + return mappedValue != rangeAccessor.get(rangeElement); } @Override diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementsRule.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementsRule.java index 45fe70641..fcc62d7b5 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementsRule.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/MappedElementsRule.java @@ -75,7 +75,7 @@ public class MappedElementsRule implements IBidirectionalMappingR public boolean checkChanges(ReadGraph g, IForwardMapping map, Domain domainElement, Range rangeElement) throws MappingException { LOGGER.trace(" MappedElementsRule.updateRange"); ArrayList mappedValue = getMappedValue(g, map, domainElement); - return Objects.equals(mappedValue, rangeAccessor.get(rangeElement)); + return !Objects.equals(mappedValue, rangeAccessor.get(rangeElement)); } private ArrayList getMappedValue(ReadGraph g, IForwardMapping map, Domain domainElement) diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/ValueRule.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/ValueRule.java index cbea3253a..2e2b81b19 100644 --- a/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/ValueRule.java +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/graph/rules/ValueRule.java @@ -66,7 +66,7 @@ public class ValueRule implements IBidirectionalMappingRule map, Domain domainElement, Range rangeElement) throws MappingException { Object value = rangeAccessor.get(rangeElement); - return Objects.equals(value, domainAccessor.get(g, domainElement)); + return !Objects.equals(value, domainAccessor.get(g, domainElement)); } public void createDomain(WriteGraph g, IBackwardMapping map, Domain domainElement, Range rangeElement) throws MappingException { diff --git a/bundles/org.simantics.scenegraph.profile/META-INF/MANIFEST.MF b/bundles/org.simantics.scenegraph.profile/META-INF/MANIFEST.MF index e032ff417..6d8c271b0 100644 --- a/bundles/org.simantics.scenegraph.profile/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scenegraph.profile/META-INF/MANIFEST.MF @@ -14,7 +14,7 @@ Require-Bundle: org.simantics.db.layer0;bundle-version="1.1.0", org.simantics.scenegraph;bundle-version="1.1.1", org.eclipse.core.runtime;bundle-version="3.6.0", org.simantics.diagram.ontology;bundle-version="1.1.1", - org.simantics.db.common + org.slf4j.api Bundle-ActivationPolicy: lazy Bundle-Activator: org.simantics.scenegraph.profile.impl.Activator Import-Package: org.simantics diff --git a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/common/ProfileObserver.java b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/common/ProfileObserver.java index 9d379c890..440ee2714 100644 --- a/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/common/ProfileObserver.java +++ b/bundles/org.simantics.scenegraph.profile/src/org/simantics/scenegraph/profile/common/ProfileObserver.java @@ -23,8 +23,8 @@ import org.simantics.db.AsyncRequestProcessor; import org.simantics.db.Resource; import org.simantics.db.Session; import org.simantics.db.common.session.SessionEventListenerAdapter; -import org.simantics.db.common.utils.Logger; import org.simantics.db.procedure.Procedure; +import org.simantics.db.service.QueryControl; import org.simantics.db.service.SessionEventSupport; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.g2d.G2DSceneGraph; @@ -38,9 +38,13 @@ import org.simantics.utils.datastructures.Pair; import org.simantics.utils.datastructures.disposable.IDisposable; import org.simantics.utils.threads.IThreadWorkQueue; import org.simantics.utils.threads.ThreadUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class ProfileObserver implements EvaluationContext { + private static final Logger LOGGER = LoggerFactory.getLogger(ProfileObserver.class); + private final Session session; /** @@ -58,6 +62,7 @@ public class ProfileObserver implements EvaluationContext { private volatile boolean dirty = true; private volatile boolean disposed = false; + private boolean needSynchronizedUpdates = false; private List> updates = new ArrayList<>(); private boolean updateAll; @@ -95,6 +100,7 @@ public class ProfileObserver implements EvaluationContext { this.sceneGraph = sceneGraph; this.constants.putAll(constants); this.notification = notification; + this.needSynchronizedUpdates = session.getService(QueryControl.class).getAmountOfQueryThreads() > 1; attachSessionListener(); @@ -139,8 +145,14 @@ public class ProfileObserver implements EvaluationContext { public void update(Style style, Object item) { if (DebugPolicy.DEBUG_PROFILE_OBSERVER_UPDATE) System.out.println("Profile observer marked dirty."); - - updates.add(Pair.make(style, item)); + + if (needSynchronizedUpdates) { + synchronized (updates) { + updates.add(Pair.make(style, item)); + } + } else { + updates.add(Pair.make(style, item)); + } //updateAll = true; dirty = true; } @@ -179,10 +191,25 @@ public class ProfileObserver implements EvaluationContext { e.apply(ProfileObserver.this); } updateAll = false; - updates.clear(); + if (needSynchronizedUpdates) { + synchronized (updates) { + updates.clear(); + } + } else { + updates.clear(); + } } else { - List> updatesCopy = new ArrayList<>(updates); - updates.clear(); + List> updatesCopy; + if (needSynchronizedUpdates) { + synchronized (updates) { + updatesCopy = new ArrayList<>(updates); + updates.clear(); + } + } else { + updatesCopy = new ArrayList<>(updates); + updates.clear(); + } + for (Pair update : updatesCopy) { Style style = update.first; Object item = update.second; @@ -221,7 +248,7 @@ public class ProfileObserver implements EvaluationContext { @Override public void exception(Throwable t) { - Logger.defaultLogError(t); + LOGGER.error("RuntimeProfileActiveEntries request failed", t); } }); } @@ -233,7 +260,7 @@ public class ProfileObserver implements EvaluationContext { @Override public void exception(Throwable throwable) { - Logger.defaultLogError(throwable); + LOGGER.error("Exception occurred during diagram profile observation", throwable); } @SuppressWarnings("unchecked") diff --git a/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ShapeNode2.java b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ShapeNode2.java new file mode 100644 index 000000000..2a8b9599a --- /dev/null +++ b/bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ShapeNode2.java @@ -0,0 +1,191 @@ +/******************************************************************************* + * Copyright (c) 2007, 2010 Association for Decentralized Information Management + * in Industry THTH ry. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * VTT Technical Research Centre of Finland - initial API and implementation + *******************************************************************************/ +package org.simantics.scenegraph.g2d.nodes; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Paint; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; + +import org.simantics.scenegraph.g2d.G2DNode; +import org.simantics.scenegraph.utils.GeometryUtils; +import org.simantics.scenegraph.utils.InitValueSupport; + +/** + * A scene graph node that renders a specified AWT {@link Shape} by optionally + * filling or drawing it. + * + * This is similar to ShapeNode, but allows separate stroke and fill colors. + * Due to API changes, I've done separate implementation. -MLuu + * + * + * @author luukkainen + * @author J-P Laine + * @author Tuukka Lehtonen + * + */ +public class ShapeNode2 extends G2DNode implements InitValueSupport { + + private static final long serialVersionUID = -5700299566608619380L; + + protected static final Stroke DEFAULT_STROKE = new BasicStroke(2); + + protected Shape shape = null; + protected Stroke stroke = DEFAULT_STROKE; + protected Paint strokeColor = Color.BLACK; + protected Paint fillColor = null; + protected boolean scaleStroke = false; + protected boolean scaleShape = false; + + protected transient Shape dynamicShape = null; + protected transient Stroke dynamicStroke = null; + protected transient Paint dynamicStrokeColor = null; + protected transient Paint dynamicFillColor = null; + protected transient Boolean dynamicScaleStroke = null; + protected transient Boolean dynamicScaleShape = null; + + @PropertySetter("shape") + @SyncField("shape") + public void setShape(Shape shape) { + this.shape = shape; + repaint(); + } + + @PropertySetter("stroke") + @SyncField("stroke") + public void setStroke(Stroke stroke) { + this.stroke = stroke; + } + + @PropertySetter("strokeColor") + @SyncField("strokeColor") + public void setStrokeColor(Paint color) { + this.strokeColor = color; + } + + @PropertySetter("fillColor") + @SyncField("fillColor") + public void setFillColor(Paint color) { + this.fillColor = color; + } + + + @SyncField("scaleStroke") + public void setScaleStroke(boolean scaleStroke) { + this.scaleStroke = scaleStroke; + } + + @SyncField("scaleShape") + public void setScaleShape(boolean scaleShape) { + this.scaleShape = scaleShape; + } + + @Override + public void render(Graphics2D g2d) { + Shape shape = dynamicShape != null ? dynamicShape : this.shape; + if (shape == null) + return; + + AffineTransform ot = setupRender(g2d); + renderShape(g2d, shape); + if (ot != null) + g2d.setTransform(ot); + } + + /** + * @param g2d + * @return current transform + */ + protected AffineTransform setupRender(Graphics2D g2d) { + AffineTransform old = null; + if (!transform.isIdentity()) { + old = g2d.getTransform(); + g2d.transform(transform); + } + + + boolean scaleShape = Boolean.TRUE.equals(dynamicScaleShape) ? true : this.scaleShape; + if (scaleShape) { + double xs = g2d.getTransform().getScaleX(); + double ys = g2d.getTransform().getScaleY(); + g2d.scale(1/xs, 1/ys); + } + + return old; + } + + protected void renderShape(Graphics2D g2d, Shape s) { + Paint color = dynamicFillColor != null ? dynamicFillColor : this.fillColor; + if (color != null) { + g2d.setPaint(color); + g2d.fill(s); + } + + Stroke stroke = dynamicStroke != null ? dynamicStroke : this.stroke; + if (stroke != null) { + color = dynamicStrokeColor != null ? dynamicStrokeColor : this.strokeColor; + if (color != null) g2d.setPaint(color); + + boolean scaleStroke = Boolean.TRUE.equals(dynamicScaleStroke) ? true : this.scaleStroke; + if (scaleStroke && stroke instanceof BasicStroke) { + BasicStroke bs = GeometryUtils.scaleStroke(stroke, (float) (1.0 / GeometryUtils.getScale(g2d.getTransform()))); + g2d.setStroke(bs); + } else { + g2d.setStroke(stroke); + } + + g2d.draw(s); + } + } + + @Override + public Rectangle2D getBoundsInLocal() { + if(shape == null) return null; + return shape.getBounds2D(); + } + + public void setValue(String key, Object value) { + if ("shape".equals(key)) + dynamicShape = (Shape) value; + else if ("stroke".equals(key)) + dynamicStroke = (Stroke) value; + else if ("strokeColor".equals(key)) + dynamicStrokeColor = (Paint) value; + else if ("fillColor".equals(key)) + dynamicFillColor = (Paint) value; + else if ("scaleStroke".equals(key)) + dynamicScaleStroke = (Boolean) value; + else if ("scaleShape".equals(key)) + dynamicScaleShape = (Boolean) value; +// else super.setValue(key, value); + } + + @Override + public void initValues() { + dynamicShape = null; + dynamicStroke = null; + dynamicStrokeColor = null; + dynamicFillColor = null; + dynamicScaleStroke = null; + dynamicScaleShape = null; + } + + @Override + public String toString() { + return super.toString() + " [shape=" + shape + ",color=" + strokeColor + ",fill=" + fillColor +"]"; + } + +} diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java index 79b596908..23491235c 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/module/repository/ModuleRepository.java @@ -240,6 +240,10 @@ public class ModuleRepository { return getModule(moduleName, null); } + public void update(String moduleName) { + getModuleEntry(moduleName, null).notifyAboutUpdate(); + } + public Failable getRuntimeModule(String moduleName, UpdateListener listener) { return getModuleEntry(moduleName, listener).getRuntimeModule(); } diff --git a/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF index eb6ba41c5..ea90658a3 100644 --- a/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scl.data/META-INF/MANIFEST.MF @@ -8,7 +8,7 @@ Require-Bundle: org.simantics.scl.runtime;bundle-version="0.4.0", org.simantics.scl.osgi;bundle-version="1.0.4", org.jdom2;bundle-version="2.0.6", org.junit;bundle-version="4.12.0";resolution:=optional, - com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.2", - com.fasterxml.jackson.core.jackson-databind + com.fasterxml.jackson.core.jackson-core;bundle-version="[2.8.11,2.9.0)", + com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.8.11,2.9.0)" Bundle-ClassPath: . Automatic-Module-Name: org.simantics.scl.data diff --git a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/Activator.java b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/Activator.java index a14be4896..4e1d01816 100644 --- a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/Activator.java +++ b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/Activator.java @@ -1,14 +1,11 @@ package org.simantics.scl.reflection.internal; -import java.util.concurrent.ForkJoinPool; - import org.eclipse.core.runtime.ILog; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Status; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; -import org.simantics.scl.reflection.internal.registry.BindingRegistry; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,21 +20,6 @@ public class Activator implements BundleActivator { public void start(BundleContext context) throws Exception { this.context = context; instance = this; - - primeBindingRegistry(); - } - - private static void primeBindingRegistry() { - LOGGER.info("Priming BindingRegistry"); - ForkJoinPool.commonPool().submit(() -> { - try { - // this forces static initialzation of the registry in advance - BindingRegistry.primeBindingRegistry(); - } catch (Exception e) { - LOGGER.error("Could not prime binding registry", e); - } - LOGGER.info("Priming done"); - }); } @Override diff --git a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/BindingRegistry.java b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/BindingRegistry.java index 648e314d9..f9bf3fadc 100644 --- a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/BindingRegistry.java +++ b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/BindingRegistry.java @@ -49,12 +49,6 @@ public class BindingRegistry { } } - public static void primeBindingRegistry() { - for (Namespace ns : namespaces.values()) { - ns.initializeValues(); - } - } - static { initialize(); if (DEBUG_INIT) { diff --git a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java index 5234d3bfc..daaa204db 100644 --- a/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java +++ b/bundles/org.simantics.scl.reflection/src/org/simantics/scl/reflection/internal/registry/Namespace.java @@ -275,7 +275,7 @@ public class Namespace { } } - synchronized void initializeValues() { + private synchronized void initializeValues() { if(values == null) { initializeTypes(); TypeBindingScheme scheme = MinimalTypeBindingScheme.INSTANCE; diff --git a/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF b/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF index 2c2f670f8..c816d74a6 100644 --- a/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF +++ b/bundles/org.simantics.scl.rest/META-INF/MANIFEST.MF @@ -4,27 +4,34 @@ Bundle-Name: Simantics SCL REST-Server Bundle-SymbolicName: org.simantics.scl.rest Bundle-Version: 1.0.0.qualifier Bundle-Activator: org.simantics.scl.rest.Activator -Require-Bundle: org.glassfish.jersey.core.jersey-server, +Require-Bundle: org.glassfish.jersey.core.jersey-server;bundle-version="[2.25.1,2.26.0)", org.simantics.scl.compiler, org.simantics.scl.osgi, - org.glassfish.jersey.containers.jersey-container-servlet-core, + org.glassfish.jersey.containers.jersey-container-servlet-core;bundle-version="[2.25.1,2.26.0)", javax.servlet-api, org.eclipse.jetty.servlet;bundle-version="9.4.24", org.eclipse.jetty.server;bundle-version="9.4.24", org.eclipse.jetty.util;bundle-version="9.4.24", org.eclipse.jetty.io;bundle-version="9.4.24", - com.fasterxml.jackson.core.jackson-core;bundle-version="2.8.8", - com.fasterxml.jackson.core.jackson-annotations;bundle-version="2.8.0", - com.fasterxml.jackson.core.jackson-databind;bundle-version="2.8.8", - org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="2.25.1", - org.glassfish.jersey.media.jersey-media-multipart;bundle-version="2.25.1", + com.fasterxml.jackson.core.jackson-core;bundle-version="[2.8.11,2.9.0)", + com.fasterxml.jackson.core.jackson-annotations;bundle-version="[2.8.11,2.9.0)", + com.fasterxml.jackson.core.jackson-databind;bundle-version="[2.8.11,2.9.0)", + org.glassfish.jersey.media.jersey-media-json-jackson;bundle-version="[2.25.1,2.26.0)", + org.glassfish.jersey.media.jersey-media-multipart;bundle-version="[2.25.1,2.26.0)", org.slf4j.api, org.jvnet.mimepull;bundle-version="1.9.6", - org.glassfish.jersey.core.jersey-client, - org.glassfish.jersey.core.jersey-common;bundle-version="2.25.1", + org.glassfish.jersey.core.jersey-client;bundle-version="[2.25.1,2.26.0)", + org.glassfish.jersey.core.jersey-common;bundle-version="[2.25.1,2.26.0)", org.simantics.scl.runtime, org.eclipse.osgi;bundle-version="3.15.100", - jakarta.ws.rs-api;bundle-version="2.1.6" + javax.ws.rs-api, + org.glassfish.hk2.external.aopalliance-repackaged;bundle-version="2.5.0", + org.glassfish.jersey.bundles.repackaged.jersey-guava;bundle-version="[2.25.1,2.26.0)", + org.glassfish.hk2.api;bundle-version="2.5.0", + org.glassfish.hk2.locator;bundle-version="2.5.0", + org.glassfish.hk2.osgi-resource-locator;bundle-version="1.0.1", + org.glassfish.hk2.utils;bundle-version="2.5.0", + javassist;bundle-version="3.20.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy Automatic-Module-Name: org.simantics.scl.rest diff --git a/bundles/org.simantics.scl.ui/plugin.xml b/bundles/org.simantics.scl.ui/plugin.xml index b7d5c9fb2..ac4489d2e 100644 --- a/bundles/org.simantics.scl.ui/plugin.xml +++ b/bundles/org.simantics.scl.ui/plugin.xml @@ -142,30 +142,6 @@ - - - - - - - - - - = 0 && (Character.isJavaIdentifierPart(currentText.charAt(offset)) && !Character.isWhitespace(currentText.charAt(offset)))) - length--; - - int nameSpaceBeginRange = currentText.lastIndexOf(".", caretEndRange - 1); //$NON-NLS-1$ - if (nameSpaceBeginRange > length) - length = nameSpaceBeginRange; - int endRange = currentText.length(); - if (caretEndRange < endRange) - endRange = caretEndRange; - text.setSelection(length, endRange); + int replacementOffset = findPrefixMatchOffset(currentText, caretOffset, contents); + +// System.out.println("text: " + currentText); +// System.out.println("proposal to fill: " + contents); +// System.out.format("longest match of proposed contents found from text @ offset %d: \"%s[%s]%s\"%n", +// replacementOffset, +// currentText.substring(0, replacementOffset), +// currentText.substring(replacementOffset, caretOffset), +// currentText.substring(caretOffset)); + + // The text between [replaceOffset, caretOffset) will be replaced with `contents` + text.setSelection(replacementOffset, caretOffset); text.insert(contents); - // calculate the initial count of letters that was typed when the proposal was accepted to insert the caret - // at the right position - int proposalFirstLettersCount = endRange - (length); - text.setCaretOffset(caretEndRange + cursorPosition - proposalFirstLettersCount); + text.setSelection(replacementOffset + contents.length()); + } + + /** + * Find offset of longest prefix match of match in + * text ending at offset endOffset. + * + * Example: + *
+	 * ...  res (=text)
+	 * resource (=match)
+	 *  resourc
+	 *   resour
+	 *    resou
+	 *     reso
+	 *      res match! return endOffset - 3
+	 * 
+ * + * @param text the text from which to find the match + * @param endOffset endOffset until which to search for the longest match + * @param match the text to prefix-match + * @return + */ + private static int findPrefixMatchOffset(String text, int endOffset, String match) { + for (int i = match.length(); i >= 0; --i) { + if (text.regionMatches(true, endOffset - i, match, 0, i)) + return endOffset - i; + } + return 0; } /* diff --git a/bundles/org.simantics.simulation/src/org/simantics/simulation/data/DatasourceAdapter.java b/bundles/org.simantics.simulation/src/org/simantics/simulation/data/DatasourceAdapter.java index 1ee543f4c..34fbb587d 100644 --- a/bundles/org.simantics.simulation/src/org/simantics/simulation/data/DatasourceAdapter.java +++ b/bundles/org.simantics.simulation/src/org/simantics/simulation/data/DatasourceAdapter.java @@ -19,8 +19,6 @@ import java.util.Set; import java.util.concurrent.Executor; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; -import java.util.logging.Level; -import java.util.logging.Logger; import org.simantics.databoard.Bindings; import org.simantics.databoard.accessor.error.AccessorException; @@ -32,6 +30,8 @@ import org.simantics.history.HistoryException; import org.simantics.history.util.subscription.SubscriptionItem; import org.simantics.simulation.data.Datasource.DatasourceListener; import org.simantics.utils.datastructures.Triple; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * This adapter reads data from Datasource and writes to an open Subscription. @@ -41,7 +41,7 @@ import org.simantics.utils.datastructures.Triple; */ public class DatasourceAdapter implements DatasourceListener { - protected Logger logger = Logger.getLogger( DatasourceAdapter.class.toString() ); + protected Logger logger = LoggerFactory.getLogger( DatasourceAdapter.class ); protected Collector session; protected boolean loaded = false; protected List handles = new ArrayList(); @@ -139,7 +139,7 @@ public class DatasourceAdapter implements DatasourceListener { result.add(Triple.make(key, binding, value)); } catch (AccessorException e) { if (failedIds.add(key)) - logger.log(Level.SEVERE, e.toString(), e); + logger.error(e.toString(), e); continue; } } @@ -172,20 +172,20 @@ public class DatasourceAdapter implements DatasourceListener { value = handle.getValue(source); } catch (AccessorException e) { if (failedIds.add(key)) - logger.log(Level.SEVERE, e.toString(), e); + logger.error(e.toString(), e); continue; } Binding binding = handle.binding(); try { session.setValue( key, binding, value ); } catch (HistoryException e) { - logger.log(Level.SEVERE, e.toString(), e); + logger.error(e.toString(), e); } } else { Binding binding = bindings.get(i); if (binding != null) { session.setValue( key, binding, value ); - } + } } } @@ -193,11 +193,11 @@ public class DatasourceAdapter implements DatasourceListener { try { session.endStep(); } catch (HistoryException e) { - logger.log(Level.SEVERE, e.toString(), e); + logger.error(e.toString(), e); } } } catch (HistoryException e) { - logger.log(Level.SEVERE, e.toString(), e); + logger.error(e.toString(), e); } finally { stepLock.unlock(); } @@ -207,6 +207,5 @@ public class DatasourceAdapter implements DatasourceListener { public Executor getExecutor() { return null; } - } diff --git a/bundles/org.simantics.simulation/src/org/simantics/simulation/export/CSVItemsQuery.java b/bundles/org.simantics.simulation/src/org/simantics/simulation/export/CSVItemsQuery.java index a39f2e736..6ce6a50cf 100644 --- a/bundles/org.simantics.simulation/src/org/simantics/simulation/export/CSVItemsQuery.java +++ b/bundles/org.simantics.simulation/src/org/simantics/simulation/export/CSVItemsQuery.java @@ -77,7 +77,10 @@ public class CSVItemsQuery implements Read> { // Resource experiment = graph.syncRequest(new PossibleExperiment(subscriptionItem)); // String runIdentifier = ""; // experiment.getIdentifier(); - + + item.groupItemId = graph.getPossibleRelatedValue(subscriptionItem, L0.HasName, Bindings.STRING); + if (item.groupItemId == null) continue; + item.variableReference = rvi.toPossibleString(graph, configuration); if (item.variableReference == null) continue; @@ -118,6 +121,7 @@ public class CSVItemsQuery implements Read> { public static class CSVItem { public String modelUri; public String label; + public String groupItemId; public String variableReference; public String unit; } diff --git a/bundles/org.simantics.simulation/src/org/simantics/simulation/export/ExportSubscriptionCSV.java b/bundles/org.simantics.simulation/src/org/simantics/simulation/export/ExportSubscriptionCSV.java index 07954660e..9abae29d2 100644 --- a/bundles/org.simantics.simulation/src/org/simantics/simulation/export/ExportSubscriptionCSV.java +++ b/bundles/org.simantics.simulation/src/org/simantics/simulation/export/ExportSubscriptionCSV.java @@ -97,7 +97,7 @@ public class ExportSubscriptionCSV extends ExperimentExportClass implements Expo labelBuilder.append(")"); } - List historyItems = im.search("variableId", item.variableReference); + List historyItems = im.search("groupItemId", item.groupItemId, "variableId", item.variableReference); Collections.sort(historyItems, SamplingFormat.INTERVAL_COMPARATOR); if (items.isEmpty()) continue; Bean config = historyItems.get(0); diff --git a/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java b/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java index 343adefc8..6719cf63b 100644 --- a/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java +++ b/bundles/org.simantics.simulation/src/org/simantics/simulation/history/HistoryUtil.java @@ -664,7 +664,7 @@ public class HistoryUtil { */ public static HistoryImportResult importHistoryArchive(HistoryManager history, Path path) throws IOException, HistoryException { HistoryImportResult result = new HistoryImportResult(); - try (RandomAccessBinary rab = new BinaryFile(path.toFile())) { + try (RandomAccessBinary rab = new BinaryFile(path.toFile(), "r")) { importHistoryArchive(history, rab, result); return result; } catch (IOException e) { diff --git a/bundles/org.simantics.structural.synchronization/src/org/simantics/structural/synchronization/base/SynchronizationEventHandlerBase.java b/bundles/org.simantics.structural.synchronization/src/org/simantics/structural/synchronization/base/SynchronizationEventHandlerBase.java index 095640c4a..5f8334398 100644 --- a/bundles/org.simantics.structural.synchronization/src/org/simantics/structural/synchronization/base/SynchronizationEventHandlerBase.java +++ b/bundles/org.simantics.structural.synchronization/src/org/simantics/structural/synchronization/base/SynchronizationEventHandlerBase.java @@ -56,6 +56,13 @@ public abstract class SynchronizationEventHandlerBase */ THashSet potentiallyUpdatedComponents = new THashSet<>(); + /** + * Is this potentially an undo/redo-related synchronization? + * + * Default is true for backwards compatibility. + */ + protected boolean isUndo = true; + public SynchronizationEventHandlerBase(Solver solver, ReferenceResolverBase resolver, SolverNameUtil nameUtil, ComponentFactory componentFactory, ModuleUpdaterFactoryBase moduleUpdaterFactory, MappingBase mapping) { this.solver = solver; @@ -66,6 +73,19 @@ public abstract class SynchronizationEventHandlerBase this.resolver = resolver; } + /** + * Mark the undo/redo status of this handler. + * + * Set 'isUndo' to false when processing a normal synchronization and true when + * processing an undo/redo. + * + * When 'isUndo' is false, loading of component solver state from the state undo context + * is skipped for added components. + */ + public void setAsUndo(boolean isUndo) { + this.isUndo = isUndo; + } + @Override public void beginSynchronization() { if(TRACE_EVENTS) { @@ -311,14 +331,16 @@ public abstract class SynchronizationEventHandlerBase else { component.attached = false; context.setModuleName(nameUtil.getFreshName(parentSolverComponentName, name)); - context.addPostUpdateAction(new Runnable() { - @Override - public void run() { - context.stateLoadedFromUndo = mapping.undoContext.loadState(solver, - context.component.componentId, - context.component.uid); - } - }); + if (isUndo) { + context.addPostUpdateAction(new Runnable() { + @Override + public void run() { + context.stateLoadedFromUndo = mapping.undoContext.loadState(solver, + context.component.componentId, + context.component.uid); + } + }); + } updater.create(context, properties, connections); solverComponentNameToComponent.put(context.getModuleName(), component); } diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java index e43007637..e9bb272d3 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/Functions.java @@ -635,8 +635,8 @@ public class Functions { @Override public Map getVariables(ReadGraph graph, Variable context, Map map) throws DatabaseException { - - Resource type = context.getPossibleType(graph); + StructuralResource2 STR = StructuralResource2.getInstance(graph); + Resource type = context.getPossibleType(graph, STR.Component); if(type == null) return null; StructuralComponentClass clazz = StructuralComponentClass.get(graph, type); @@ -653,7 +653,6 @@ public class Functions { } return map; } else if (StructuralComponentClass.DEFINED.equals(clazz)) { - StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource def = graph.getSingleObject(type, STR.IsDefinedBy); Map children = graph.syncRequest(new UnescapedChildMapOfResource(def), TransientCacheListener.instance()); return StandardChildDomainChildren.getStandardChildDomainChildVariables(graph, context, children, map); diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/GetComponentLocation.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/GetComponentLocation.java index df6e1598c..e109f59e8 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/GetComponentLocation.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/queries/GetComponentLocation.java @@ -66,10 +66,16 @@ public class GetComponentLocation extends UnaryRead Variable firstRepresentedParent = findFirstParentWithRepresentation(graph, parameter, STR); if (firstRepresentedParent == null) return null; - Resource realParentComposite = graph.getPossibleObject(firstRepresentedParent.getRepresents(graph), L0.PartOf); - if (realParentComposite == null) - return null; - isInsideStructure = graph.hasStatement(realParentComposite, STR.Defines); + Resource representedParent = firstRepresentedParent.getRepresents(graph); + Resource representedParentType = graph.getPossibleType(representedParent, STR.Component); + if (representedParentType != null && graph.isInstanceOf(representedParentType, STR.ProceduralComponentType)) { + isInsideStructure = !parameter.equals(firstRepresentedParent); + } else { + Resource realParentComposite = graph.getPossibleObject(representedParent, L0.PartOf); + if (realParentComposite == null) + return null; + isInsideStructure = graph.hasStatement(realParentComposite, STR.Defines); + } Variable firstParentComposite = findFirstParentComposite(graph, firstRepresentedParent, STR); if (firstParentComposite != null) { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java index fce1abaa2..5e8538a69 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/AbstractCompileStructuralValueRequest.java @@ -9,10 +9,10 @@ import org.simantics.db.Resource; import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.PossibleIndexRoot; import org.simantics.db.common.request.ResourceRead2; +import org.simantics.db.common.request.RuntimeEnvironmentRequest; import org.simantics.db.exception.DatabaseException; import org.simantics.db.layer0.scl.AbstractExpressionCompilationContext; import org.simantics.db.layer0.scl.AbstractExpressionCompilationRequest; -import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.layer0.Layer0; import org.simantics.scl.compiler.elaboration.expressions.EApply; diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/procedural/ProceduralComponentTypeCompilationContextRequest.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/procedural/ProceduralComponentTypeCompilationContextRequest.java index 50a905e82..1e3647905 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/procedural/ProceduralComponentTypeCompilationContextRequest.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/scl/procedural/ProceduralComponentTypeCompilationContextRequest.java @@ -8,7 +8,7 @@ import org.simantics.db.common.procedure.adapter.TransientCacheListener; import org.simantics.db.common.request.IndexRoot; import org.simantics.db.common.request.UnaryRead; import org.simantics.db.exception.DatabaseException; -import org.simantics.db.layer0.util.RuntimeEnvironmentRequest; +import org.simantics.db.layer0.util.RuntimeEnvironmentRequest2; import org.simantics.scl.compiler.environment.specification.EnvironmentSpecification; import org.simantics.scl.compiler.runtime.RuntimeEnvironment; import org.simantics.structural2.scl.ComponentTypeProperty; @@ -25,7 +25,7 @@ public class ProceduralComponentTypeCompilationContextRequest extends UnaryRead< public ProceduralComponentTypeCompilationContext perform(ReadGraph graph) throws DatabaseException { Resource indexRoot = graph.syncRequest(new IndexRoot(parameter)); - RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(indexRoot) { + RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest2(parameter, indexRoot) { @Override protected void fillEnvironmentSpecification( EnvironmentSpecification environmentSpecification) { diff --git a/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java b/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java index e27d92f29..aac19a7f1 100644 --- a/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java +++ b/bundles/org.simantics.structural2/src/org/simantics/structural2/utils/StructuralUtils.java @@ -308,11 +308,13 @@ public class StructuralUtils { } public static boolean isImmutable(ReadGraph graph, Resource r) throws DatabaseException { + // Marking a resource L0.readOnly also makes it immutable + if (graph.isImmutable(r) || Layer0Utils.isMarkedReadOnly(graph, r)) + return true; StructuralResource2 STR = StructuralResource2.getInstance(graph); Resource uc = graph.syncRequest(new PossibleTypedParent(r, STR.ComponentType)); - return graph.isImmutable(r) - // Anything under a published or locked user component is published as well - || (uc != null && (Layer0Utils.isPublished(graph, uc) + return // Anything under a published or locked user component is published as well + (uc != null && (Layer0Utils.isPublished(graph, uc) || graph.hasStatement(uc, STR.ComponentType_Locked))) // Anything under a published container (shared library) is published as well || Layer0Utils.isContainerPublished(graph, r) diff --git a/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java b/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java index a70949d5e..708a32efc 100644 --- a/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java +++ b/bundles/org.simantics.trend/src/org/simantics/trend/impl/HorizRuler.java @@ -284,6 +284,14 @@ public class HorizRuler extends TrendGraphicalNode { return (end-from) / getWidth(); } + /** + * @return the current starting sample time calculated from all visible chart + * items. + */ + public double getItemFromTime() { + return iFrom; + } + /** * @return the current ending sample time calculated from all visible chart * items. diff --git a/features/org.simantics.history.rest.feature/feature.xml b/features/org.simantics.history.rest.feature/feature.xml index b5cd3f73d..598157c6e 100644 --- a/features/org.simantics.history.rest.feature/feature.xml +++ b/features/org.simantics.history.rest.feature/feature.xml @@ -40,7 +40,7 @@ unpack="false"/> + + + + + + + + + + 1.2.0 2.0.6 2.0.6.b0001 - 2.10.2 - 2.10.2.b0001 + 2.8.11 + 2.8.11 3.1.0 - 2.1.6 - - 2.1.6.b0005 - 2.30.1 - - 2.30.1.b0005 + 2.25.1 1.5.0 1.7.30 1.7.30 @@ -40,6 +35,7 @@ 0.5.4 4.4 1.20 + 1.6 2.6 1.2 1.4 @@ -85,12 +81,12 @@ org.eclipse.tycho.extras tycho-p2-extras-plugin - 1.0.0 + 1.7.0 org.reficio p2-maven-plugin - 1.2.0 + 1.3.0 default-cli @@ -268,6 +264,10 @@ org.apache.commons.compress + + org.apache.commons:commons-csv:${commons-csv.version} + true + commons-lang:commons-lang:${commons-lang.version} true @@ -449,138 +449,28 @@ org.apache.aries.spifly:org.apache.aries.spifly.dynamic.bundle:${org.apache.aries.spifly.dynamic.bundle.version} true - - jakarta.ws.rs:jakarta.ws.rs-api:${jakarta.version} - true - true - - ${jakarta.version.actual} - - jakarta.xml.bind-api - - !javax.*,*;resolution:=optional - - javax.ws.rs;version="${jakarta.version}", - javax.ws.rs.core;version="${jakarta.version}", - javax.ws.rs.ext;version="${jakarta.version}", - javax.ws.rs.client;version="${jakarta.version}", - javax.ws.rs.container;version="${jakarta.version}", - javax.ws.rs.sse;version="${jakarta.version}" - - - - - org.glassfish.jersey.core:jersey-common:${jersey.version} - true - true - - ${jersey.version.actual} - - javax.annotation, - javax.inject, - jakarta.validation.jakarta.validation-api, - jakarta.ws.rs-api, - jakarta.xml.bind-api - - !javax.*,*;resolution:=optional - - org.glassfish.jersey.*;version="${jersey.version}" - - - org.glassfish.jersey.core:jersey-server:${jersey.version} true - true - - ${jersey.version.actual} - - javax.annotation, - javax.inject, - jakarta.validation.jakarta.validation-api, - jakarta.ws.rs-api, - jakarta.xml.bind-api - - !javax.*,*;resolution:=optional - org.glassfish.jersey.core:jersey-client:${jersey.version} true - true - - ${jersey.version.actual} - - javax.annotation, - javax.inject, - jakarta.validation.jakarta.validation-api, - jakarta.ws.rs-api, - jakarta.xml.bind-api - - !javax.*,*;resolution:=optional - - org.glassfish.jersey.media:jersey-media-multipart:${jersey.version} true - - - - - org.glassfish.jersey.ext:jersey-entity-filtering:${jersey.version} - true - true - - ${jersey.version.actual} - - jakarta.ws.rs-api, - org.glassfish.jersey.core.jersey-server - - !javax.*,*;resolution:=optional - org.glassfish.jersey.media:jersey-media-json-jackson:${jersey.version} true - true com.fasterxml.jackson.* - - ${jersey.version.actual} - - javax.annotation, - javax.inject, - jakarta.validation.jakarta.validation-api, - jakarta.ws.rs-api, - jakarta.xml.bind-api - - !javax.*,*;resolution:=optional - org.glassfish.jersey.containers:jersey-container-servlet-core:${jersey.version} true - true - - ${jersey.version.actual} - - javax.annotation, - javax.inject, - jakarta.validation.jakarta.validation-api, - jakarta.ws.rs-api, - jakarta.xml.bind-api - - !javax.*,*;resolution:=optional - org.jboss.windup.decompiler:decompiler-procyon:${decompiler-procyon.version} diff --git a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target index 2386f897f..052490947 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target +++ b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.target @@ -1,7 +1,7 @@ - + @@ -195,28 +195,30 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -258,14 +260,16 @@ + + - - - - - - + + + + + + @@ -279,6 +283,8 @@ + + @@ -315,24 +321,32 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -355,8 +369,8 @@ - - + + @@ -371,15 +385,15 @@ - - - + + + - + diff --git a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd index 8f52a3571..c15e0308a 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd +++ b/releng/org.simantics.sdk.build.targetdefinition/org.simantics.sdk.build.targetdefinition.tpd @@ -173,7 +173,7 @@ location "http://www.simantics.org/update/collections/10.2.0/repository/" { org.eclipse.collections.feature.source.feature.group } -location "http://www.simantics.org/download/master/external-components/maven/" { +location "http://www.simantics.org/download/release/1.43.0.1/external-components/maven/" { bouncycastle.bcmail-jdk14 bouncycastle.bcprov-jdk14 ch.qos.logback.classic @@ -218,6 +218,8 @@ location "http://www.simantics.org/download/master/external-components/maven/" { com.fasterxml.woodstox.woodstox-core.source com.healthmarketscience.jackcess com.healthmarketscience.jackcess.source + com.influxdb.client-core + com.influxdb.client-core.source com.influxdb.client-java com.influxdb.client-java.source com.koloboke.api-jdk8 @@ -259,14 +261,16 @@ location "http://www.simantics.org/download/master/external-components/maven/" { it.unimi.dsi.fastutil it.unimi.dsi.fastutil.source jakarta-regexp + javassist + javassist.source javax.servlet-api javax.servlet-api.source - jakarta.xml.bind-api - jakarta.xml.bind-api.source - jakarta.validation.jakarta.validation-api - jakarta.validation.jakarta.validation-api.source - jakarta.ws.rs-api - jakarta.ws.rs-api.source + javax.ws.rs-api + javax.ws.rs-api.source + javax.validation.api + javax.validation.api.source + javax.annotation-api + javax.annotation-api.source net.jcip.annotations net.jcip.annotations.source net.ucanaccess @@ -280,6 +284,8 @@ location "http://www.simantics.org/download/master/external-components/maven/" { org.apache.commons.collections4.source org.apache.commons.compress org.apache.commons.compress.source + org.apache.commons.csv + org.apache.commons.csv.source org.apache.commons.io org.apache.commons.io.source org.apache.commons.lang @@ -316,20 +322,18 @@ location "http://www.simantics.org/download/master/external-components/maven/" { org.eclipse.jetty.servlets.source com.github.benmanes.caffeine com.github.benmanes.caffeine.source - //org.glassfish.hk2.api - //org.glassfish.hk2.api.source - //org.glassfish.hk2.locator - //org.glassfish.hk2.locator.source + org.glassfish.hk2.api + org.glassfish.hk2.api.source + org.glassfish.hk2.locator + org.glassfish.hk2.locator.source org.glassfish.hk2.osgi-resource-locator org.glassfish.hk2.osgi-resource-locator.source - //org.glassfish.hk2.utils - //org.glassfish.hk2.utils.source - //org.glassfish.jersey.bundles.repackaged.jersey-guava - //org.glassfish.jersey.bundles.repackaged.jersey-guava.source - //org.glassfish.hk2.external.aopalliance-repackaged - //org.glassfish.hk2.external.aopalliance-repackaged.source - org.glassfish.hk2.external.jakarta.inject - org.glassfish.hk2.external.jakarta.inject.source + org.glassfish.hk2.utils + org.glassfish.hk2.utils.source + org.glassfish.jersey.bundles.repackaged.jersey-guava + org.glassfish.jersey.bundles.repackaged.jersey-guava.source + org.glassfish.hk2.external.aopalliance-repackaged + org.glassfish.hk2.external.aopalliance-repackaged.source org.glassfish.jersey.core.jersey-client org.glassfish.jersey.core.jersey-client.source org.glassfish.jersey.core.jersey-common @@ -386,7 +390,7 @@ location "http://www.simantics.org/download/master/external-components/maven/" { stax2-api.source } -location "http://www.simantics.org/download/master/external-components/manual" { +location "http://www.simantics.org/download/release/1.43.0.1/external-components/manual" { org.apache.batik.feature.feature.group lazy org.apache.poi.feature.feature.group lazy io.grpc.feature.feature.group lazy diff --git a/releng/org.simantics.sdk.build.targetdefinition/simantics.target b/releng/org.simantics.sdk.build.targetdefinition/simantics.target index f06dc5e47..87618645f 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/simantics.target +++ b/releng/org.simantics.sdk.build.targetdefinition/simantics.target @@ -1,7 +1,7 @@ - + @@ -195,28 +195,30 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + @@ -258,14 +260,16 @@ + + - - - - - - + + + + + + @@ -279,6 +283,8 @@ + + @@ -315,24 +321,32 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -355,8 +369,8 @@ - - + + @@ -371,20 +385,20 @@ - - - + + + - + - + diff --git a/releng/org.simantics.sdk.build.targetdefinition/simantics.tpd b/releng/org.simantics.sdk.build.targetdefinition/simantics.tpd index 1d7588e26..76d990bda 100644 --- a/releng/org.simantics.sdk.build.targetdefinition/simantics.tpd +++ b/releng/org.simantics.sdk.build.targetdefinition/simantics.tpd @@ -2,9 +2,9 @@ target "Simantics 1.43.0" with source allEnvironments -include "http://www.simantics.org/download/master/org.simantics.sdk.build.targetdefinition.tpd" +include "./org.simantics.sdk.build.targetdefinition.tpd" -location "http://www.simantics.org/download/master/sdk" { +location "http://www.simantics.org/download/release/1.43.0.1/sdk" { org.simantics.sdk.feature.group lazy org.simantics.sdk.source.feature.group lazy }