]> gerrit.simantics Code Review - simantics/platform.git/commitdiff
Merge branch 'change/2080/9' into private/balas private/balas
authorAntti Villberg <antti.villberg@semantum.fi>
Wed, 26 Sep 2018 10:10:27 +0000 (13:10 +0300)
committerAntti Villberg <antti.villberg@semantum.fi>
Wed, 26 Sep 2018 10:10:27 +0000 (13:10 +0300)
29 files changed:
bundles/org.simantics.diagram.connection/src/org/simantics/diagram/connection/rendering/StyledRouteGraphRenderer.java
bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java [new file with mode: 0644]
bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java
bundles/org.simantics.g2d/src/org/simantics/g2d/diagram/handler/impl/PickContextImpl.java
bundles/org.simantics.modeling/src/org/simantics/modeling/internal/Activator.java
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphModuleSourceRepository.java
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java [moved from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java with 98% similarity]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphPropertyRelation.java [moved from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphPropertyRelation.java with 99% similarity]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java [moved from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java with 99% similarity]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java [new file with mode: 0644]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModule.java [moved from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java with 58% similarity]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModuleSourceRepository.java [moved from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModuleSourceRepository.java with 97% similarity]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java [new file with mode: 0644]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java [new file with mode: 0644]
bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java [new file with mode: 0644]
bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/g2d/nodes/ConnectionNode.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EConstant.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/macros/MacroRule.java
bundles/org.simantics.scl.db/scl/Simantics/DB.scl
bundles/org.simantics.scl.db/scl/Simantics/Variables.scl
bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java [new file with mode: 0644]
bundles/pom.xml
features/org.simantics.jdbc.feature/feature.xml
features/org.simantics.sdk.feature/feature.xml
features/pom.xml

index b084e5875714938026400e5a8b6c938659e3ca71..dd9473042152d0c3af43244d9549d63e4c649e4b 100644 (file)
@@ -36,9 +36,13 @@ public class StyledRouteGraphRenderer implements IRouteGraphRenderer, Serializab
 
        protected final ConnectionStyle style;
 
+       private static class Cache {
+               Path2D path = new Path2D.Double();
+               THashSet<RoutePoint> branchPoints = new THashSet<>();
+       }
+
        // Caches to avoid creating new objects all the time during rendering
-       protected transient Path2D path;
-       protected transient THashSet<RoutePoint> branchPoints;
+       protected static ThreadLocal<Cache> caches = ThreadLocal.withInitial(() -> new Cache());
 
        public StyledRouteGraphRenderer(ConnectionStyle style) {
                if (style == null)
@@ -52,14 +56,14 @@ public class StyledRouteGraphRenderer implements IRouteGraphRenderer, Serializab
 
        @Override
        public void render(Graphics2D g, RouteGraph rg) {
-               if (path == null)
-                       path = new Path2D.Double();
+               Cache cache = caches.get();
+               Path2D path = cache.path;
+               THashSet<RoutePoint> branchPoints = cache.branchPoints;
+
                path.reset();
                rg.getPath2D(path);
                style.drawPath(g, path, false);
 
-               if (branchPoints == null)
-                       branchPoints = new THashSet<RoutePoint>();
                branchPoints.clear();
                for(RouteLine line : rg.getLines()) {
                    renderLine(g, line, false);
index e025fb2ddf16927783a2fc353817b87c9c068155..522c0b9d5b73661051370fa6cecdb446ffe656a5 100644 (file)
@@ -47,6 +47,31 @@ public class TypeGroup implements Group {
         this.name = name;
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((types == null) ? 0 : types.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        TypeGroup other = (TypeGroup) obj;
+        if (types == null) {
+            if (other.types != null)
+                return false;
+        } else if (!types.equals(other.types))
+            return false;
+        return true;
+    }
+
     /**
      * Initialize TypeGroup from a DIAGRAM.Group instance.
      * 
index 3bbbf8081dea77cfbb7792d0c1ecbd97d3e2a1ed..224e767c2792956f83cb52399a54a2b8e16fce6c 100644 (file)
@@ -23,11 +23,10 @@ import org.simantics.utils.datastructures.Pair;
  */
 public class ResourceSCLTextGridStyle extends TextGridStyle {
 
-       final Resource style;
        final Font font;
 
        public ResourceSCLTextGridStyle(ReadGraph graph, Resource style) throws DatabaseException {
-               this.style = style;
+           super(style);
                G2DResource G2D = G2DResource.getInstance(graph);
         Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
                if(fontR != null) {
@@ -51,7 +50,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle {
 
        @Override
        protected Object getIdentity(Resource entry) {
-               return new Pair<Resource, Resource>(style, entry);
+               return new Pair<Resource, Resource>(getResource(), entry);
        }
 
        @Override
@@ -63,7 +62,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle {
        public MonitorTextGridResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {
                DiagramResource DIA = DiagramResource.getInstance(graph);
 
-               Variable styleVariable = Variables.getVariable(graph, style);
+               Variable styleVariable = Variables.getVariable(graph, getResource());
                Function1<Resource,Tuple3> function = styleVariable.getPossiblePropertyValue(graph, DIA.ResourceSCLTextGridStyle_texts);
                Tuple3 result = Simantics.applySCLRead(graph, function, element);
                
@@ -79,7 +78,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle {
 
        @Override
        public String getNodeName() {
-               return "" + style.getResourceId();
+               return "" + getResource().getResourceId();
        }
 
 }
index 4401f2213c51aa0a58b0b0c8170ab5e9636d281c..f084799fdddf0d71dec97a3a7b940f3a17a886d9 100644 (file)
@@ -25,11 +25,10 @@ import org.simantics.utils.datastructures.Pair;
  */
 public class SCLTextGridStyle extends TextGridStyle {
 
-       final Resource style;
        final Font font;
 
        public SCLTextGridStyle(ReadGraph graph, Resource style) throws DatabaseException {
-               this.style = style;
+           super(style);
                G2DResource G2D = G2DResource.getInstance(graph);
         Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
                if(fontR != null) {
@@ -53,7 +52,7 @@ public class SCLTextGridStyle extends TextGridStyle {
 
        @Override
        protected Object getIdentity(Resource entry) {
-               return new Pair<Resource, Resource>(style, entry);
+               return new Pair<Resource, Resource>(getResource(), entry);
        }
 
        @Override
@@ -81,7 +80,7 @@ public class SCLTextGridStyle extends TextGridStyle {
                if (moduleVariable == null)
                        return null;
 
-               Variable styleVariable = Variables.getVariable(graph, style);
+               Variable styleVariable = Variables.getVariable(graph, getResource());
                Function1<Variable,Tuple3> function = styleVariable.getPossiblePropertyValue(graph, DIA.SCLTextGridStyle_texts);
                Tuple3 result = Simantics.applySCLRead(graph, function, moduleVariable);
                
@@ -97,7 +96,7 @@ public class SCLTextGridStyle extends TextGridStyle {
 
        @Override
        public String getNodeName() {
-               return "" + style.getResourceId();
+               return "" + getResource().getResourceId();
        }
 
 }
index 21071ba74bd9453e9c3bdf166c0240bd46156c54..28b03a1f66797c03e240d6896eeb0941ec57a955 100644 (file)
  *******************************************************************************/
 package org.simantics.diagram.profile;
 
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
 
 import org.simantics.databoard.Bindings;
 import org.simantics.db.ReadGraph;
@@ -44,8 +39,7 @@ import org.simantics.scenegraph.profile.Style;
 import org.simantics.scenegraph.profile.common.ObserverGroupListener;
 import org.simantics.scenegraph.profile.common.ObserverGroupValueListener;
 import org.simantics.scenegraph.profile.impl.DebugPolicy;
-import org.simantics.scl.runtime.tuple.Tuple;
-import org.simantics.scl.runtime.tuple.Tuple2;
+import org.simantics.scl.runtime.tuple.Tuple3;
 import org.simantics.utils.datastructures.Pair;
 
 /**
@@ -72,14 +66,48 @@ import org.simantics.utils.datastructures.Pair;
  */
 public abstract class StyleBase<Result> implements Style {
 
-    protected final Map<Tuple, Result> values   = new ConcurrentHashMap<Tuple, Result>();
-
-//    private Map<Resource,ObserverGroupListener>         listeners = new ConcurrentHashMap<Resource, ObserverGroupListener>();
+    private Object identity;
+    
+    public StyleBase(Object identity) {
+        this.identity = identity;
+    }
 
-    private Map<Pair<Resource, Group>, ObserverGroupListener> listeners = new HashMap<Pair<Resource, Group>, ObserverGroupListener>();
+    public StyleBase() {
+        this.identity = getClass();
+    }
     
+    protected <T> T getIdentity() {
+        return (T)identity;
+    }
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((identity == null) ? 0 : identity.hashCode());
+        return result;
+    }
 
-    private final List<Resource>                removals = new ArrayList<Resource>();
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        StyleBase other = (StyleBase) obj;
+        if (identity == null) {
+            if (other.identity != null)
+                return false;
+        } else if (!identity.equals(other.identity))
+            return false;
+        return true;
+    }
+
+    protected Resource getResource() {
+        return getIdentity();
+    }
 
     /**
      * For caching this simple base request that is done in every
@@ -175,9 +203,9 @@ public abstract class StyleBase<Result> implements Style {
      */
     public void styleResultChanged(Observer observer, Resource runtimeDiagram, Resource object, Result result) {
         if (result == null)
-            values.remove(new Tuple2(runtimeDiagram, object));
+            StyleBaseData.getInstance().removeValue(new Tuple3(this, runtimeDiagram, object));
         else
-            values.put(new Tuple2(runtimeDiagram, object), result);
+            StyleBaseData.getInstance().putValue(new Tuple3(this, runtimeDiagram, object), result);
         observer.update();
     }
 
@@ -283,12 +311,11 @@ public abstract class StyleBase<Result> implements Style {
               if (DebugPolicy.DEBUG_PROFILE_STYLE_GROUP_TRACKING)
                   System.out.println(style + ": removed from group " + group + ": " + item);
 
-              synchronized (style.removals) {
-                 style.removals.add(item);
-              }
+              StyleBaseData.getInstance().removeItem(style, item);
 
               // TODO: do something here to dispose of ObserverGroupValueListeners?
               super.remove(item);
+              
           }  
           
     }
@@ -308,7 +335,7 @@ public abstract class StyleBase<Result> implements Style {
 
             listener = new GroupListener<Result>(backend.getSession(), runtimeDiagram, entry, this, group, observer);
 
-            listeners.put(Pair.make(runtimeDiagram, group), listener);
+            StyleBaseData.getInstance().putListener(new Tuple3(this, runtimeDiagram, group), listener);
 
             group.trackItems(backend, runtimeDiagram, listener);
 
@@ -390,7 +417,7 @@ public abstract class StyleBase<Result> implements Style {
             listener.removeEntry(entry);
             if (!listener.hasEntries()) {
                 listener.dispose();
-                listeners.remove(Pair.make(runtimeDiagram, group));
+                StyleBaseData.getInstance().removeListener(new Tuple3(this, runtimeDiagram, group));
             }
 
             // This was too eager when multiple groups were tracked!
@@ -425,19 +452,13 @@ public abstract class StyleBase<Result> implements Style {
         if (DebugPolicy.DEBUG_PROFILE_STYLE_APPLICATION)
             System.out.println(StyleBase.this + ": applying style for items: " + listener.getItems());
 
-        if (!removals.isEmpty()) {
-            Resource[] removed;
-            synchronized (removals) {
-                removed = removals.toArray(Resource.NONE);
-                removals.clear();
-            }
-            for (Resource item : removed) {
-                cleanupStyleForItem(evaluationContext, map, item);
-            }
-        }
+        
+        StyleBaseData data = StyleBaseData.getInstance();
+        
+        data.applyRemovals(evaluationContext, this);
         
         for (Object item : listener.getItems()) {
-            Result value = values.get(new Tuple2(evaluationContext.getResource(), item));
+            Result value = data.getValue(new Tuple3(this, evaluationContext.getResource(), item));
             applyStyleForItem(evaluationContext, map, item, value);
         }
         
@@ -480,7 +501,7 @@ public abstract class StyleBase<Result> implements Style {
     }
     
     private ObserverGroupListener getListener(Resource runtime, Group group) {
-        return listeners.get(Pair.make(runtime, group));
+        return StyleBaseData.getInstance().getListener(new Tuple3(this, runtime, group));
     }
 
 }
diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java
new file mode 100644 (file)
index 0000000..5bd51b2
--- /dev/null
@@ -0,0 +1,84 @@
+package org.simantics.diagram.profile;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.simantics.db.Resource;
+import org.simantics.scenegraph.profile.DataNodeMap;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.Style;
+import org.simantics.scenegraph.profile.common.ObserverGroupListener;
+import org.simantics.scl.runtime.tuple.Tuple;
+import org.simantics.scl.runtime.tuple.Tuple3;
+
+public class StyleBaseData {
+
+    protected final Map<Tuple, Object> values   = new ConcurrentHashMap<>();
+
+    private Map<Tuple3, ObserverGroupListener> listeners = new HashMap<>();
+
+    private final Map<Style, List<Resource>> removals = new HashMap<>();
+
+    private StyleBaseData() {
+        
+    }
+    
+    private static StyleBaseData INSTANCE;
+    
+    public static StyleBaseData getInstance() {
+        if(INSTANCE == null) {
+            INSTANCE = new StyleBaseData();
+        }
+        return INSTANCE;
+    }
+    
+    public void removeValue(Tuple t) {
+        values.remove(t);
+    }
+    
+    public void putValue(Tuple t, Object o) {
+        values.put(t, o);
+    }
+    
+    public <T> T getValue(Tuple t) {
+        return (T)values.get(t);
+    }
+
+    public synchronized void removeItem(Style s, Resource r) {
+        List<Resource> l = removals.get(s);
+        if(l == null) {
+            l = new ArrayList<>();
+            removals.put(s, l);
+        }
+        l.add(r);
+    }
+    
+    public void putListener(Tuple3 key, ObserverGroupListener listener) {
+        listeners.put(key, listener);
+    }
+    
+    public void removeListener(Tuple3 key) {
+        listeners.remove(key);
+    }
+
+    public ObserverGroupListener getListener(Tuple3 key) {
+        return listeners.get(key);
+    }
+
+    public synchronized void applyRemovals(EvaluationContext evaluationContext, StyleBase s) {
+        
+        List<Resource> rs = removals.remove(s);
+        if(rs == null) return;
+        
+        DataNodeMap map = evaluationContext.getConstant(ProfileKeys.NODE_MAP);
+
+        for (Resource item : rs) {
+            s.cleanupStyleForItem(evaluationContext, map, item);
+        }
+        
+    }
+
+}
index 54972155d8d69579294e4d6e49718a453e14e66d..60e8fa6da7763767cd4a041ab9195d7c35078533 100644 (file)
@@ -38,17 +38,18 @@ public abstract class TextGridStyle extends StyleBase<MonitorTextGridResult> {
        private final Color BACKGROUND_COLOR = new Color(255, 255, 255, 192);
        private static final Rectangle2D EMPTY_BOUNDS = new Rectangle2D.Double(0, 0, 0, 0);
 
-       // NOTE: this is a hack
-       String id;
+//     // NOTE: this is a hack
+//     String id;
 
        protected double xOffset;
        protected double yOffset;
 
-       public TextGridStyle() {
-               this(0.0, 2.1);
+       public TextGridStyle(Resource r) {
+               this(r, 0.0, 2.1);
        }
 
-       public TextGridStyle(double xOffset, double yOffset) {
+       public TextGridStyle(Resource r, double xOffset, double yOffset) {
+           super(r);
                this.xOffset = xOffset;
                this.yOffset = yOffset;
        }
@@ -175,29 +176,33 @@ public abstract class TextGridStyle extends StyleBase<MonitorTextGridResult> {
 
                        // This assumes that this TextGridStyle instance will be devoted to
                        // this row ID until the end of its life.
-                       String id = result.getRowId();
-                       //System.out.println(this + " ID: " + id);
-                       if (!id.equals(this.id)) {
-                               //System.out.println(this + " SET ID: " + this.id + " -> " + id);
-                               this.id = id;
-                       }
+//                     String id = result.getRowId();
+//                     System.out.println(this + " ID: " + id);
+//                     if (!id.equals(this.id)) {
+//                             System.out.println(this + " SET ID: " + this.id + " -> " + id);
+//                             this.id = id;
+//                     }
+                       
 
                        Integer newRow = observer.getTemporaryProperty(_node, "location");
                        if (newRow == null)
                                newRow = 1;
 
-                       // Remove from existing row to add to another row if necessary.
-                       Integer row = observer.getProperty(_node, id);
+            // Remove from existing row to add to another row if necessary.
+            Integer row = getCurrentRowNumber(observer, _node);
                        if (row != null && row != newRow) {
                                String actualId = node.getRowId(row);
+                               String id = observer.getProperty(_node, rowIdKey());
                                if (id.equals(actualId)) {
                                        node.removeRow(row);
                                }
                        }
                        row = newRow;
 
-                       node.setRowId(row, id);
-                       observer.setProperty(_node, id, row);
+                       node.setRowId(row, result.getRowId());
+                       
+                       setCurrentRowNumber(observer, _node, result.getRowId(), row);
+                       
                        observer.setTemporaryProperty(_node, "location", row + 1);
 
                        node.setText(2, row, value2);
@@ -361,18 +366,45 @@ public abstract class TextGridStyle extends StyleBase<MonitorTextGridResult> {
 
        @Override
        protected void cleanupStyleForNode(EvaluationContext observer, INode _node) {
-               Integer row = observer.getProperty(_node, id);
+           Integer row = getCurrentRowNumber(observer, _node);
                //System.out.println(this + " cleanup(" + id + ", " + row + ")");
                //System.out.println(element);
                if (row == null)
                        return;
-               observer.setProperty(_node, id, null);
+               clearCurrentRowNumber(observer, _node);
                TextGridNode node = ProfileVariables.browseChild(_node, "TextGridStyle");
                if (node != null)
                        node.removeRow(row);
        }
+       
+       private Integer getCurrentRowNumber(EvaluationContext observer, INode _node) {
+        String rowId = observer.getProperty(_node, rowIdKey());
+        return observer.getProperty(_node, rowId);
+       }
+
+    private void setCurrentRowNumber(EvaluationContext observer, INode _node, String rowId, int row) {
+        // Mapping style identity -> rowId (resourceId)
+        observer.setProperty(_node, rowIdKey(), rowId);
+        // Mapping rowId (resourceId) -> row number
+        observer.setProperty(_node, rowId, row);
+    }
+
+       private void clearCurrentRowNumber(EvaluationContext observer, INode _node) {
+        String rowId = observer.getProperty(_node, rowIdKey());
+        if(rowId != null) {
+            observer.setProperty(_node, rowIdKey(), null);
+            Integer row = observer.getProperty(_node, rowId);
+            if(row != null) {
+                observer.setProperty(_node, rowId, null);
+            }
+        }
+    }
 
        protected void postProcessNode(TextGridNode node, int row) {
        }
+       
+       private String rowIdKey() {
+        return "style" + getIdentity().toString();
+       }
 
 }
index a891d62b70a360f7e750097f57cc2e0b26368ef5..f6fd5fe6ddab9067960d168a1c487161b1065e4c 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 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
@@ -8,6 +8,7 @@
  *
  * Contributors:
  *     VTT Technical Research Centre of Finland - initial API and implementation
+ *     Semantum Oy - gitlab #66 - parallel/spatial optimization
  *******************************************************************************/
 package org.simantics.g2d.diagram.handler.impl;
 
@@ -51,6 +52,8 @@ import org.slf4j.LoggerFactory;
 
 /**
  * @author Toni Kalajainen
+ * @author Jani Simomaa
+ * @author Tuukka Lehtonen
  */
 public class PickContextImpl implements PickContext {
 
@@ -62,6 +65,16 @@ public class PickContextImpl implements PickContext {
 
        private static final ThreadLocal<Rectangle2D> perThreadElementBounds = ThreadLocal.withInitial(() -> new Rectangle2D.Double());
 
+       private boolean useRTree;
+
+       public PickContextImpl() {
+               this(false);
+       }
+
+       public PickContextImpl(boolean useRTree) {
+               this.useRTree = useRTree;
+       }
+
        @Override
        public void pick(
                        IDiagram diagram, 
@@ -171,11 +184,11 @@ public class PickContextImpl implements PickContext {
                        return shape.getBounds2D();
        }
 
-       private static List<IElement> pickElements(IDiagram diagram, PickRequest request) {
+       private List<IElement> pickElements(IDiagram diagram, PickRequest request) {
                ILayers layers = diagram.getHint(DiagramHints.KEY_LAYERS);
 
                // Get the scene graph nodes that intersect the pick-requests pick shape
-               INode spatialRoot = request.pickContext != null
+               INode spatialRoot = useRTree && request.pickContext != null
                                ? request.pickContext.getSceneGraph().lookupNode(SceneGraphConstants.SPATIAL_ROOT_NODE_ID)
                                : null;
 
index 3fc0d46fa58cb34e2f5c77f39696b816cc244f67..b55bed028502be43b94962bd63d69414371cd001 100644 (file)
@@ -5,7 +5,7 @@ import java.util.Hashtable;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
 import org.simantics.modeling.scl.GraphModuleSourceRepository;
-import org.simantics.modeling.scl.OntologyModuleSourceRepository;
+import org.simantics.modeling.scl.ontologymodule.OntologyModuleSourceRepository;
 import org.simantics.scl.compiler.source.repository.ModuleSourceRepository;
 
 public class Activator implements BundleActivator {
index f3f5b917067a887a992b948a52760a3813b13f6e..8eed51aca7ed70401b7ddafb7da5a13bab85b2ff 100644 (file)
@@ -15,6 +15,7 @@ import org.simantics.db.request.Read;
 import org.simantics.layer0.Layer0;
 import org.simantics.modeling.ModelingUtils;
 import org.simantics.modeling.internal.Activator;
+import org.simantics.modeling.scl.ontologymodule.OntologyModuleSourceRepository;
 import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidatorFactory;
 import org.simantics.scl.compiler.module.repository.UpdateListener;
 import org.simantics.scl.compiler.module.repository.UpdateListener.Observable;
similarity index 98%
rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphEntityType.java
rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphEntityType.java
index d59ea605cb2f3f40e7f0e5ae6077b65063ae05de..8ea51cfd0f8559d366df707fbdbef92e8ed263b7 100644 (file)
@@ -1,4 +1,4 @@
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
 
 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.externalConstant;
 import gnu.trove.map.hash.THashMap;
similarity index 99%
rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/GraphRelation.java
rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRelation.java
index f1c8a79f8b9fcc6c1d8a596d7f78b2ef9a55f65e..5a4598ce3bc98773a050954fdaac31a20cf11a57 100644 (file)
@@ -1,4 +1,4 @@
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
 
 import org.simantics.db.Resource;
 import org.simantics.scl.compiler.common.names.Name;
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/GraphRequestDuringSCLCompilation.java
new file mode 100644 (file)
index 0000000..54533ad
--- /dev/null
@@ -0,0 +1,18 @@
+package org.simantics.modeling.scl.ontologymodule;
+
+import org.simantics.Simantics;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.scl.runtime.SCLContext;
+
+public class GraphRequestDuringSCLCompilation {
+
+    public static RequestProcessor getRequestProcessor() {
+        ReadGraph graph = (ReadGraph)SCLContext.getCurrent().get("graph");
+        if(graph != null)
+            return graph;
+        else
+            return Simantics.getSession();
+    }
+    
+}
similarity index 58%
rename from bundles/org.simantics.modeling/src/org/simantics/modeling/scl/OntologyModule.java
rename to bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/OntologyModule.java
index 39cf2f76555387e85091512c0f4844e6cdecb38f..ec698e670514984fa42128d3211238d503a93a35 100644 (file)
@@ -1,8 +1,9 @@
-package org.simantics.modeling.scl;
+package org.simantics.modeling.scl.ontologymodule;
 
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.function.Consumer;
@@ -16,29 +17,48 @@ import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.request.Read;
 import org.simantics.layer0.Layer0;
 import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.StringConstant;
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
 import org.simantics.scl.compiler.elaboration.expressions.EExternalConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.macros.MacroRule;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
 import org.simantics.scl.compiler.environment.filter.NamespaceFilter;
+import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.module.ImportDeclaration;
 import org.simantics.scl.compiler.module.LazyModule;
 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.exceptions.SCLTypeParseException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
 import org.simantics.scl.runtime.SCLContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import gnu.trove.map.hash.THashMap;
 import gnu.trove.procedure.TObjectProcedure;
 
 public class OntologyModule extends LazyModule {
-
+    private static final Logger LOGGER = LoggerFactory.getLogger(OntologyModule.class);
+    
     private static final String DB_MODULE = "Simantics/DB";
+    private static final String VARIABLE_MODULE = "Simantics/Variable";
     private static final Collection<ImportDeclaration> DEPENDENCIES = Arrays.asList(
-            new ImportDeclaration(DB_MODULE, null)
+            new ImportDeclaration(DB_MODULE, null),
+            new ImportDeclaration(VARIABLE_MODULE, null)
             );
     private static final TCon RESOURCE = Types.con(DB_MODULE, "Resource");
+    private static final TCon BROWSABLE = Types.con(DB_MODULE, "Browsable");
+    private static final TCon VARIABLE = Types.con(VARIABLE_MODULE, "Variable");
     
     Resource ontology;
     String defaultLocalName;
@@ -69,26 +89,55 @@ public class OntologyModule extends LazyModule {
         return Collections.emptyList();
     }
     
-    private Resource getResource(String name) {
+    private static interface ResourceSearchResult {}
+    private static class JustResource implements ResourceSearchResult {
+        public final Resource resource;
+        public JustResource(Resource resource) {
+            this.resource = resource;
+        }   
+    }
+    private static class ResourceAndSuffix implements ResourceSearchResult {
+        public final Resource resource;
+        public final String suffix;
+        public ResourceAndSuffix(Resource resource, String suffix) {
+            this.resource = resource;
+            this.suffix = suffix;
+        }  
+    }
+    
+    private ResourceSearchResult getResourceOrSuffixedResource(String name) {
         Map<String,Resource> localMap = childMaps.get(ontology); 
         if(localMap == null)
             return null;
+        Resource parent = ontology;
         while(true) {
             int p = name.indexOf('.');
             if(p < 0)
                 break;
             String localName = name.substring(0, p);
-            Resource newParent = localMap.get(localName);
-            if(newParent == null)
+            parent = localMap.get(localName);
+            if(parent == null)
                 return null;
             name = name.substring(p+1);
             
             // Get new local map
-            localMap = getLocalMap(newParent);
+            localMap = getLocalMap(parent);
             if(localMap == null)
                 return null;
         }
-        return localMap.get(name);
+        Resource child = localMap.get(name);
+        if(child != null)
+            return new JustResource(child);
+        else
+            return new ResourceAndSuffix(parent, name);
+    }
+    
+    private Resource getResource(String name) {
+        ResourceSearchResult searchResult = getResourceOrSuffixedResource(name);
+        if(searchResult instanceof JustResource)
+            return ((JustResource)searchResult).resource;
+        else
+            return null;
     }
     
     private Map<String, Resource> getLocalMap(Resource parent) {
@@ -129,16 +178,116 @@ public class OntologyModule extends LazyModule {
         }
     }
     
+    @FunctionalInterface
+    private static interface ResourceFunctionGenerator {
+        SCLValue createValue(Name name, Resource resource);
+    }
+    
+    private static class RelatedValueMacroRule implements MacroRule {
+        private final Resource relation;
+        private final SCLRelationInfo relationInfo;
+        private final boolean optionalValue;
+        
+        public RelatedValueMacroRule(Resource relation, SCLRelationInfo relationInfo, boolean optionalValue) {
+            this.relation = relation;
+            this.relationInfo = relationInfo;
+            this.optionalValue = optionalValue;
+        }
+
+        private Expression applyWithSubject(SimplificationContext context, Type subjectType, Expression evidence, Expression subject) {
+            if(Types.equals(subjectType, RESOURCE))
+                return new EApply(
+                        Locations.NO_LOCATION,
+                        Types.READ_GRAPH,
+                        context.getConstant(Name.create(DB_MODULE, optionalValue ? "possibleRelatedValue2" : "relatedValue2"), relationInfo.rangeType),
+                        subject,
+                        new EExternalConstant(relation, RESOURCE));
+            else if(Types.equals(subjectType, VARIABLE))
+                return new EApply(
+                        Locations.NO_LOCATION,
+                        Types.READ_GRAPH,
+                        context.getConstant(Name.create(DB_MODULE, optionalValue ? "untypedPossiblePropertyValue" : "untypedPropertyValue"), relationInfo.rangeType),
+                        subject,
+                        new ELiteral(new StringConstant(relationInfo.name)));
+            else
+                return new EApply(
+                        Locations.NO_LOCATION,
+                        Types.READ_GRAPH,
+                        context.getConstant(Name.create(DB_MODULE, optionalValue ? "genericPossibleRelatedValue" : "genericRelatedValue"), subjectType, relationInfo.rangeType),
+                        evidence,
+                        subject,
+                        new EExternalConstant(relation, RESOURCE));
+        }
+        
+        @Override
+        public Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+            Type subjectType = typeParameters[0];
+            if(apply.parameters.length == 1) {
+                Variable subject = new Variable("subject", subjectType);
+                return new ESimpleLambda(subject, applyWithSubject(context, subjectType, apply.parameters[0], new EVariable(subject)));
+            }
+            else if(apply.parameters.length >= 2) {
+                Expression valueReplacement = applyWithSubject(context, subjectType, apply.parameters[0], apply.parameters[1]);
+                if(apply.parameters.length == 2)
+                    return valueReplacement;
+                else {
+                    apply.set(valueReplacement, Arrays.copyOfRange(apply.parameters, 2, apply.parameters.length));
+                    return apply;
+                }
+            }
+            else {
+                LOGGER.error("Application of relation following functions should have at least one parameter (the evidence of Browsable).");
+                return null;
+            }
+        }
+    }
+    
+    private final static HashMap<String, ResourceFunctionGenerator> VALUE_GENERATOR_MAP = new HashMap<>();
+    static {
+        TVar A = Types.var(Kinds.STAR);
+        VALUE_GENERATOR_MAP.put("value", (name, resource) -> {
+            SCLRelationInfo relationInfo = SCLRelationInfoRequest.getRelationInfo(resource);
+            if(relationInfo == null)
+                return null;
+            
+            SCLValue value = new SCLValue(name);
+            value.setType(Types.forAll(A, Types.function(Types.pred(BROWSABLE, A), Types.functionE(A, Types.READ_GRAPH, relationInfo.rangeType))));
+            value.setMacroRule(new RelatedValueMacroRule(resource, relationInfo, false));
+            return value;
+        });
+        VALUE_GENERATOR_MAP.put("possibleValue", (name, resource) -> {
+            SCLRelationInfo relationInfo = SCLRelationInfoRequest.getRelationInfo(resource);
+            if(relationInfo == null)
+                return null;
+            
+            SCLValue value = new SCLValue(name);
+            value.setType(Types.forAll(A, Types.function(Types.pred(BROWSABLE, A), Types.functionE(A, Types.READ_GRAPH, Types.apply(Types.MAYBE, relationInfo.rangeType)))));
+            value.setMacroRule(new RelatedValueMacroRule(resource, relationInfo, true));
+            return value;
+        });
+    }
+   
     @Override
     protected SCLValue createValue(String name) {
-        Resource resource = getResource(name);
-        if(resource == null)
-            return null;        
-        SCLValue value = new SCLValue(Name.create(getName(), name));
-        value.setType(RESOURCE);
-        value.setExpression(new EExternalConstant(resource, RESOURCE));
-        value.setInlineInSimplification(true);
-        return value;
+        ResourceSearchResult searchResult = getResourceOrSuffixedResource(name);
+        if(searchResult instanceof JustResource) {
+            Resource resource = ((JustResource)searchResult).resource;
+            SCLValue value = new SCLValue(Name.create(getName(), name));
+            value.setType(RESOURCE);
+            value.setExpression(new EExternalConstant(resource, RESOURCE));
+            value.setInlineInSimplification(true);
+            return value;        
+        }
+        else if(searchResult instanceof ResourceAndSuffix){
+            ResourceAndSuffix resourceAndSuffix = (ResourceAndSuffix)searchResult;
+            ResourceFunctionGenerator generator = VALUE_GENERATOR_MAP.get(resourceAndSuffix.suffix);
+            if(generator == null)
+                return null;
+            else
+                return generator.createValue(Name.create(getName(), name), resourceAndSuffix.resource);
+        }
+        else
+            return null;
     }
     
     @Override
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfo.java
new file mode 100644 (file)
index 0000000..451a83e
--- /dev/null
@@ -0,0 +1,13 @@
+package org.simantics.modeling.scl.ontologymodule;
+
+import org.simantics.scl.compiler.types.Type;
+
+public class SCLRelationInfo {
+    public final Type rangeType;
+    public final String name;
+
+    public SCLRelationInfo(Type rangeType, String name) {
+        this.rangeType = rangeType;
+        this.name = name;
+    }
+}
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLRelationInfoRequest.java
new file mode 100644 (file)
index 0000000..6662463
--- /dev/null
@@ -0,0 +1,79 @@
+package org.simantics.modeling.scl.ontologymodule;
+
+import java.util.Collection;
+
+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.UnaryRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
+import org.simantics.scl.db.SCLCompilationRequestProcessor;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCLRelationInfoRequest extends UnaryRead<Resource,SCLRelationInfo> {
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLRelationInfoRequest.class);
+    
+    private SCLRelationInfoRequest(Resource resource) {
+        super(resource);
+    }
+
+    @Override
+    public SCLRelationInfo perform(ReadGraph graph) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        if(!graph.isSubrelationOf(parameter, L0.HasProperty))
+            return null;
+        
+        String name = graph.getPossibleRelatedValue(parameter, L0.HasName);
+        if(name == null)
+            return null;
+        
+        String valueType = graph.getPossibleRelatedValue(parameter, L0.RequiresValueType);
+        if(valueType == null) {
+            Collection<Resource> rangeTypes = graph.getObjects(parameter, L0.HasRange);
+            if(rangeTypes.size() != 1) {
+                LOGGER.warn("Couldn't find SCLtype for {} because it has multiple range types.", graph.getURI(parameter));
+                return null;
+            }
+            
+            Resource range = rangeTypes.iterator().next();
+            Collection<Resource> assertedValueTypes = graph.getAssertedObjects(range, L0.HasValueType);
+            if(assertedValueTypes.size() != 1) {
+                LOGGER.warn("Couldn't find SCL type for {} because its range {} has multiple asserted value types.", graph.getURI(parameter), graph.getURI(range));
+                return null;
+            }
+            
+            Resource assertedValueType = assertedValueTypes.iterator().next();
+            valueType = graph.getPossibleValue(assertedValueType, Bindings.STRING);
+            if(valueType == null) {
+                LOGGER.warn("Couldn't find SCL type for {} because value type assertion of {} is missing a value.", graph.getURI(parameter), graph.getURI(range));
+                return null;
+            }
+        }
+        
+        Type type;
+        try {
+            type = Types.parseType(valueType);
+        } catch (SCLTypeParseException e) {
+            LOGGER.warn("Couldn't parse the value type of relation {}. Definition was '{}'.", graph.getURI(parameter), valueType);
+            return null;
+        }
+        
+        return new SCLRelationInfo(type, name);
+    }
+    
+    public static SCLRelationInfo getRelationInfo(Resource resource) {
+        try {
+            return SCLCompilationRequestProcessor.getRequestProcessor().syncRequest(new SCLRelationInfoRequest(resource), TransientCacheListener.instance());
+        } catch(DatabaseException e) {
+            LOGGER.error("SCLRelationInfoRequest failed.", e);
+            return null;
+        }
+    }
+
+}
diff --git a/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java b/bundles/org.simantics.modeling/src/org/simantics/modeling/scl/ontologymodule/SCLReservedWordsEscapingChildMapOfResource.java
new file mode 100644 (file)
index 0000000..6e674e4
--- /dev/null
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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.modeling.scl.ontologymodule;
+
+import java.util.Collection;
+import java.util.Map;
+
+import org.simantics.databoard.Bindings;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.common.request.ResourceRead;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.layer0.Layer0;
+import org.simantics.scl.compiler.common.names.SCLReservedWords;
+import org.simantics.utils.Development;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class SCLReservedWordsEscapingChildMapOfResource extends ResourceRead<Map<String, Resource>> {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(SCLReservedWordsEscapingChildMapOfResource.class);
+
+       public SCLReservedWordsEscapingChildMapOfResource(Resource resource) {
+           super(resource);
+       }
+       
+       @Override
+       public Map<String, Resource> perform(ReadGraph graph) throws DatabaseException {
+           Layer0 L0 = Layer0.getInstance(graph);
+           Collection<Resource> objects = graph.getObjects(resource, L0.ConsistsOf);
+           CollectionSupport cs = graph.getService(CollectionSupport.class);
+           Map<String,Resource> result = cs.createObjectResourceMap(String.class, objects.size());
+           for(Resource r : objects) {
+               String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
+               if(name != null) {
+                   if(SCLReservedWords.RESERVED_WORDS_SET.contains(name))
+                       name = name + "_";
+                   Resource old = result.put(name, r);
+                   if (old != null)
+                       LOGGER.error("The database contains siblings with the same name " + name + " (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ", previous child=$" + old.getResourceId() + ").");
+               } else {
+                       if(Development.DEVELOPMENT)
+                           LOGGER.error("The database contains a child with no unique name (resource=$" + resource.getResourceId() + ", child=$" + r.getResourceId() + ").");
+               }
+           }
+           return result;
+       }       
+       
+}
index d4543c6d110546c08cf8709f94f3af81d9501810..9331a1edea5afea8ae5cc5b086d790bb92e02d95 100644 (file)
@@ -16,6 +16,7 @@ import java.awt.Composite;
 import java.awt.Graphics2D;
 import java.awt.Stroke;
 import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
 
 import org.simantics.diagram.connection.RouteGraph;
 import org.simantics.scenegraph.INode;
@@ -161,5 +162,17 @@ public class ConnectionNode extends SingleElementNode implements InitValueSuppor
     public void afterRender(Graphics2D g) {
         g.setRenderingHint(G2DRenderingHints.KEY_END_ELEMENT, "connection");
     }
-    
+
+    @Override
+    public Rectangle2D getBoundsInLocal() {
+        // #134: Route graph connections render their own selection.
+        // ElementPainter will place an empty G2DParentNode
+        // called "selection" under this ConnectionNode which
+        // should be ignored in bounds calculations.
+        // Otherwise this node will not support being inserted
+        // into a spatial search structure and further selections
+        // will fail.
+        return super.getBoundsInLocal(true);
+    }
+
 }
index eb3f5ca4a74ff3e192c7647153f5f1d14cd36bcd..25cc96019f95175787b63732979b7ce8f4a9bab0 100644 (file)
@@ -16,6 +16,7 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
 import org.simantics.scl.compiler.elaboration.java.DynamicConstructor;
+import org.simantics.scl.compiler.elaboration.macros.MacroRule;
 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
 import org.simantics.scl.compiler.errors.Locations;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
@@ -125,6 +126,14 @@ public class EConstant extends Expression {
             else
                 return value.getExpression().copy().simplify(context);
         }
+        else {
+            MacroRule macroRule = value.getMacroRule();
+            if(macroRule != null) {
+                Expression newExpression = macroRule.inline(context, typeParameters);
+                if(newExpression != null)
+                    return newExpression;
+            }
+        }
         return this;
     }
 
index 60d53acd2413bfb9538987003001518a5df8e2ae..21b836871db3a8100c9e06c4f26e80b2db10e1a5 100644 (file)
@@ -7,6 +7,12 @@ import org.simantics.scl.compiler.types.Type;
 
 public interface MacroRule {
 
-    Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply);
+    default Expression apply(SimplificationContext context, Type[] typeParameters, EApply apply) {
+        return null;
+    }
+
+    default Expression inline(SimplificationContext context, Type[] typeParameters) {
+        return null;
+    }
     
 }
index a400659ee0c940b18b129fadf0f9a572e1ff643d..2ff2f51acb11f455459bc64a8663e06961547129 100644 (file)
@@ -108,6 +108,9 @@ importJava "org.simantics.db.ReadGraph" where
     @JavaName getRelatedValue2
     relatedValue2 :: Resource -> Resource -> <ReadGraph> a
 
+    @JavaName getPossibleRelatedValue2
+    possibleRelatedValue2 :: Resource -> Resource -> <ReadGraph> Maybe a
+
     @JavaName getRelatedVariantValue2
     relatedVariantValue2 :: Resource -> Resource -> <ReadGraph> Variant
     
@@ -187,6 +190,9 @@ class Browsable a where
     
     valueOf :: Serializable v => a -> <ReadGraph> v
     
+    genericRelatedValue :: a -> Resource -> <ReadGraph> t
+    genericPossibleRelatedValue :: a -> Resource -> <ReadGraph> Maybe t
+    
     variantValueOf :: a -> <ReadGraph> Variant 
     
     children :: a -> <ReadGraph> [a]
@@ -206,6 +212,9 @@ instance Browsable Resource where
     valueOf r = valueOf_ r binding
     variantValueOf = variantValueOf_
     
+    genericRelatedValue = relatedValue2
+    genericPossibleRelatedValue = possibleRelatedValue2
+    
     children r = r # L0.ConsistsOf
     parent r = singleObject r L0.PartOf
     possibleParent r = possibleObject r L0.PartOf
index 43be6defbb6ee486957572caff2abe9d0a93f226..436e0a17357f32072ec80c2cea18f8f97d3bb734 100644 (file)
@@ -421,6 +421,9 @@ instance Browsable Variable where
     variantValueOf v = createVariant (datatype v) (untypedValue v :: Dynamic)
     child = child_
     possibleChild = possibleChild_
+    
+    genericRelatedValue v rel = untypedPropertyValue v (nameOf rel)
+    genericPossibleRelatedValue v rel = untypedPossiblePropertyValue v (nameOf rel)
 
 propertiesClassified :: Variable -> Resource -> <ReadGraph> [Variable]
 propertiesClassified parent classified = do
diff --git a/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java b/bundles/org.simantics.scl.db/src/org/simantics/scl/db/SCLCompilationRequestProcessor.java
new file mode 100644 (file)
index 0000000..b793b21
--- /dev/null
@@ -0,0 +1,15 @@
+package org.simantics.scl.db;
+
+import org.simantics.Simantics;
+import org.simantics.db.RequestProcessor;
+import org.simantics.scl.runtime.SCLContext;
+
+public class SCLCompilationRequestProcessor {
+    public static RequestProcessor getRequestProcessor() {
+        Object graph = SCLContext.getCurrent().get("graph");
+        if(graph != null)
+            return (RequestProcessor)graph;
+        else
+            return Simantics.getSession();
+    }
+}
index 04b6311eba4b916233ab64527de7f3fcd9a0b507..9e409d9df4bd04a0aef4c19008e9db92484b9508 100644 (file)
                <module>org.simantics.issues.ontology</module>
                <module>org.simantics.issues.ui</module>
                <module>org.simantics.issues.ui.ontology</module>
+               <module>org.simantics.jdbc</module>
+               <module>org.simantics.jdbc.ontology</module>
                <module>org.simantics.layer0</module>
                <module>org.simantics.layer0.utils</module>
                <module>org.simantics.layer0x.ontology</module>
index 66b53fac850f12d1614bb36fcaa63f07b3ddfa97..1665527b24f4dd2a00324b6c5ea4633e0de8fd33 100644 (file)
       [Enter License Description here.]
    </license>
 
-   <plugin
-         id="org.simantics.jdbc"
-         download-size="0"
-         install-size="0"
-         version="0.0.0"
-         unpack="false"/>
-
-   <plugin
+  <plugin
          id="org.simantics.simulator.toolkit"
          download-size="0"
          install-size="0"
          unpack="false"/>
 
    <plugin
-         id="org.simantics.jdbc.ontology"
+         id="org.simantics.jdbc"
          download-size="0"
          install-size="0"
          version="0.0.0"
          unpack="false"/>
-
    <plugin
-         id="org.simantics.jdbc.simupedia.sharedlibrary"
+         id="org.simantics.jdbc.ontology"
          download-size="0"
          install-size="0"
          version="0.0.0"
index 00a3b68b0b76ea00f607b6e80c0e112e51d324ad..ff6c75f80ad2fbc13928a66ad375fa5a86296c24 100644 (file)
          id="org.simantics.logging.ui.feature"
          version="0.0.0"/>
 
+   <includes
+         id="org.simantics.jdbc.feature"
+         version="0.0.0"/>
+
    <plugin
          id="org.simantics.fileimport"
          download-size="0"
index 4c19ccca4f224921948976fcb323a365064370e1..2503989cf1060996167302c7d5f198bc952d1e2e 100644 (file)
         <module>org.simantics.image.feature</module>
         <module>org.simantics.issues.feature</module>
         <module>org.simantics.issues.ui.feature</module>
+        <module>org.simantics.jdbc.feature</module>
         <module>org.simantics.layer0.feature</module>
         <module>org.simantics.logging.feature</module>
         <module>org.simantics.logging.ui.feature</module>