]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
First blood for g2d to h2d transition.
authorvillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 31 May 2010 10:32:29 +0000 (10:32 +0000)
committervillberg <villberg@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Mon, 31 May 2010 10:32:29 +0000 (10:32 +0000)
git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/trunk@15982 ac1ea38d-2e2b-0410-8846-a27921b304fc

13 files changed:
org.simantics.sysdyn.ui/META-INF/MANIFEST.MF
org.simantics.sysdyn.ui/adapters.xml
org.simantics.sysdyn.ui/plugin.xml
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SymbolsFeature.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java [new file with mode: 0644]
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/equation/EquationView.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/handlers/NewModelHandler.java
org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/trend/TrendView.java
org.simantics.sysdyn/src/org/simantics/sysdyn/SysdynResource.java
sysdyn_ontologies/sysdyn.graph

index 9fcc740cf6976a0c07335ea966ff7e867761dbcd..a253c6027ae0d551fbe7e55baa29cab87628b197 100644 (file)
@@ -28,6 +28,9 @@ Require-Bundle: org.simantics.h2d;bundle-version="1.0.0",
  org.simantics.graphviz.ui;bundle-version="1.0.0",
  org.simantics.graphviz;bundle-version="1.0.0",
  org.simantics.diagram;bundle-version="0.9.4",
- org.simantics.modeling;bundle-version="1.0.0"
+ org.simantics.modeling;bundle-version="1.0.0",
+ org.simantics.mapping;bundle-version="1.0.0",
+ org.simantics.structural.stubs;bundle-version="1.0.0",
+ gnu.trove2;bundle-version="2.0.4"
 Bundle-Activator: org.simantics.sysdyn.ui.Activator
 Bundle-ActivationPolicy: lazy
index 62f8e6df267677ba1624d941d9798ed37c040c96..61ee59d8daefd97729cb4077c0c2977e667e82ab 100644 (file)
         VTT Technical Research Centre of Finland - initial API and implementation\r
  -->\r
 
-<adapters>\r
+<adapters>\r\r   <target interface="org.simantics.layer0.utils.triggers.ITrigger">\r      <type uri = "http://www.simantics.org/Sysdyn-1.0/DiagramToCompositeMapping"\r          class = "org.simantics.sysdyn.ui.editor.DiagramToCompositeMapping3">\r         <graph/>\r           <this />\r       </type>\r        </target>\r\r
        <target\r
                interface="org.simantics.project.features.IProjectFeature">\r
                <resource\r
                        uri="http://www.simantics.org/Sysdyn-1.0/SysdynProject"\r
                        class="org.simantics.sysdyn.ui.project.SysdynProject" />\r
-       </target>\r      \r
+               <resource\r                      uri="http://www.simantics.org/Sysdyn-1.0/SysdynSymbols"\r                        class="org.simantics.sysdyn.ui.editor.SymbolsFeature" />\r       </target>\r      \r
        <target\r
                interface="org.simantics.scenegraph.adapters.ISceneGraphProvider">\r
                <type\r
index bdc19f6952400546333e1535cfb29032e9029c76..45c158bab2b7a1627159044858cb31ed7b5e82c4 100644 (file)
 <plugin>\r
    <extension\r
          point="org.eclipse.ui.editors">\r
+      <editor\r
+            class="org.simantics.sysdyn.ui.editor.DiagramViewer"\r
+            default="false"\r
+            id="org.simantics.sysdyn.ui.diagramViewer"\r
+            name="System dynamic diagram viewer">\r
+      </editor>\r
       <editor\r
             class="org.simantics.sysdyn.ui.editor.SysdynDiagramEditor"\r
             default="false"\r
    </extension>\r
    <extension\r
          point="org.simantics.ui.resourceEditorAdapter">\r
+         <adapterClass\r
+            class="org.simantics.sysdyn.ui.editor.OpenDiagramFromConfigurationAdapter"\r
+            priority="100">\r
+      </adapterClass>\r
       <adapter\r
             editorId="org.simantics.sysdyn.ui.diagramEditor"\r
             priority="3"\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramToCompositeMapping3.java
new file mode 100644 (file)
index 0000000..347803f
--- /dev/null
@@ -0,0 +1,92 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.utils.binaryPredicates.InversePredicate;\r
+import org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate;\r
+import org.simantics.mapping.constraint.instructions.IInstruction;\r
+import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction;\r
+import org.simantics.mapping.rule.instructions.IRuleInstruction;\r
+import org.simantics.modeling.mapping.NamingCreationInstruction;\r
+import org.simantics.sysdyn.SysdynResource;\r
+\r
+public class DiagramToCompositeMapping3 extends org.simantics.modeling.mapping.DiagramToCompositeMapping3 {\r
+\r
+       private SysdynResource sdr;\r
+\r
+       public DiagramToCompositeMapping3(ReadGraph g, Resource mapping)\r
+       throws DatabaseException {\r
+               super(g, mapping);\r
+       }\r
+\r
+       @Override\r
+       protected void setup(ReadGraph graph) {\r
+               sdr = SysdynResource.getInstance(graph);\r
+       }\r
+\r
+       @Override\r
+       protected Resource getConfigurationConnectionType() {\r
+               return sdr.Flow;\r
+       }\r
+\r
+       public CreationInstruction componentCreationInstruction(int component, int componentType, int configuration) {\r
+               return new SysdynCreationInstruction(project, configurationRoot, component, componentType, configuration);\r
+       }\r
+       \r
+       @Override\r
+       protected IRuleInstruction destructiveRule() {\r
+               return\r
+               if_(and(bf(b.ConsistsOf, Configuration, Component),\r
+                b(mapped, Component) // handle only mapped components\r
+            ),\r
+            query(\r
+                if_(and(bf(mr.ComponentToElement, Component, Element),\r
+                        bf(new InversePredicate(OrderedSetElementsPredicate.INSTANCE), Element, Diagram)\r
+                    ),\r
+                    // If component has a corresponding element in the diagram\r
+                    if_(and(statement_bff(Component, ConnectionRelation, Connection, sr.IsConnectedTo),\r
+                            b(mapped, Connection)\r
+                        ),\r
+                        // If component has a mapped connection\r
+                        unless(\r
+                            bf(mr.ConnectionToDiagramConnection, Connection, DiagramConnectionRelation),\r
+                            // If the configuration connection does not have a correspondence in the diagram remove it\r
+                            and(deny(exists(Connection)))\r
+                        )\r
+                    ),\r
+\r
+                    unless(\r
+                               bf(mr.ConnectionToDiagramConnection, Component, Element),\r
+                            // If the configuration connection does not have a correspondence in the diagram remove it\r
+                               and(deny(exists(Component)))\r
+                        )\r
+                    \r
+                )\r
+            )\r
+        );\r
+       }\r
+       \r
+       protected IInstruction claimBasicConnection() {\r
+               return and(exists(\r
+                bf(mr.DiagramConnectionToConnection, Element, Connection),\r
+                Connection\r
+            ),\r
+            b(getConfigurationConnectionType(), Connection),\r
+            b(mapped, Connection),\r
+            bb(b.PartOf, Connection, Configuration)\r
+        );\r
+       }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/DiagramViewer.java
new file mode 100644 (file)
index 0000000..54e8ba0
--- /dev/null
@@ -0,0 +1,59 @@
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.diagram.handler.ConnectionCommandHandler;\r
+import org.simantics.diagram.handler.CopyPasteHandler;\r
+import org.simantics.diagram.synchronization.IModifiableSynchronizationContext;\r
+import org.simantics.g2d.canvas.ICanvasContext;\r
+import org.simantics.g2d.canvas.impl.CanvasContext;\r
+import org.simantics.g2d.diagram.participant.DeleteHandler;\r
+import org.simantics.modeling.ui.diagramEditor.PopulateElementDropParticipant;\r
+import org.simantics.modeling.ui.diagramEditor.PopulateElementMonitorDropParticipant;\r
+import org.simantics.modeling.ui.diagramEditor.handlers.WorkbenchStructuralSelectionProvider2;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ */\r
+public class DiagramViewer extends org.simantics.modeling.ui.diagramEditor.DiagramViewer {\r
+\r
+    @SuppressWarnings("unchecked")\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+//        if (adapter == IPropertyPage.class)\r
+//            return new AprosPropertyPage(getSite());\r
+        return super.getAdapter(adapter);\r
+    }\r
+\r
+    @Override\r
+    protected void addKeyBindingParticipants(CanvasContext ctx) {\r
+//        ctx.add(new KeyToCommand(AprosKeyBindings.BINDINGS));\r
+        ctx.add(new DeleteHandler(getEditorSite().getActionBars().getStatusLineManager()));\r
+        ctx.add(new CopyPasteHandler(getEditorSite().getActionBars().getStatusLineManager()));\r
+        ctx.add(new ConnectionCommandHandler());\r
+    }\r
+\r
+    @Override\r
+    protected void initializeSynchronizationContext(ReadGraph graph, IModifiableSynchronizationContext context) {\r
+        super.initializeSynchronizationContext(graph, context);\r
+//        context.set(AprosDiagramSynchronizationHints.APROS_RESOURCE, AprosBuiltins.getInstance(graph));\r
+    }\r
+\r
+    @Override\r
+    protected void addDropParticipants(ICanvasContext ctx) {\r
+        // FIXME This is a workaround so that this participant can be disabled\r
+        // for SymbolViewer\r
+        ctx.add(new PopulateElementDropParticipant(synchronizer));\r
+        ctx.add(new PopulateElementMonitorDropParticipant(synchronizer, 0.15, 0.15));\r
+    }\r
+\r
+    @Override\r
+    protected void addStructureParticipants(ICanvasContext ctx) {\r
+        structuralPath = getResourceInput().getResourceArray().removeFromBeginning(1);\r
+\r
+        ctx.add(new WorkbenchStructuralSelectionProvider2(swt, getSite(), structuralPath));\r
+        // Add visual browsing capabilities for structural models\r
+//        ctx.add(new StructuralBrowsingHandler(getSite(), sessionContext, structuralPath));\r
+//        ctx.add(new LinkBrowsingHandler(getSite(), this, sessionContext));\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/OpenDiagramFromConfigurationAdapter.java
new file mode 100644 (file)
index 0000000..c2fcda8
--- /dev/null
@@ -0,0 +1,17 @@
+package org.simantics.sysdyn.ui.editor;\r
+\r
+\r
+public class OpenDiagramFromConfigurationAdapter extends org.simantics.modeling.ui.diagramEditor.OpenDiagramFromConfigurationAdapter {\r
+\r
+    private static final String EDITOR_ID = "org.simantics.sysdyn.ui.diagramViewer";\r
+\r
+    public OpenDiagramFromConfigurationAdapter() {\r
+        super();\r
+    }\r
+\r
+    @Override\r
+    protected String getEditorId() {\r
+        return EDITOR_ID;\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SymbolsFeature.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SymbolsFeature.java
new file mode 100644 (file)
index 0000000..83bf313
--- /dev/null
@@ -0,0 +1,326 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007 VTT Technical Research Centre of Finland and others.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.Comparator;\r
+import java.util.List;\r
+\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.RequestProcessor;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.common.procedure.adapter.MultiProcedureAdapter;\r
+import org.simantics.db.common.request.ResourceRead;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.exception.ResourceNotFoundException;\r
+import org.simantics.db.request.Read;\r
+import org.simantics.diagram.query.DiagramRequests;\r
+import org.simantics.diagram.stubs.DiagramResource;\r
+import org.simantics.diagram.symbollibrary.ISymbolGroup;\r
+import org.simantics.diagram.symbollibrary.ISymbolItem;\r
+import org.simantics.diagram.symbollibrary.ISymbolManager;\r
+import org.simantics.g2d.element.ElementClass;\r
+import org.simantics.g2d.element.handler.StaticSymbol;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.layer0.utils.direct.GraphUtils.ResourceTester;\r
+import org.simantics.project.IProject;\r
+import org.simantics.project.exception.ProjectException;\r
+import org.simantics.project.features.AbstractProjectFeature;\r
+import org.simantics.project.features.IGraphProjectFeature;\r
+import org.simantics.utils.datastructures.cache.ProvisionException;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+\r
+/**\r
+ * @author Tuukka Lehtonen\r
+ *\r
+ * TODO: live tracking of symbol libraries based on selected model, since they can contain their own local symbols\r
+ * Currently the code only provides the symbols that are in the ontology\r
+ */\r
+public class SymbolsFeature extends AbstractProjectFeature implements IGraphProjectFeature {\r
+\r
+    Collection<ISymbolGroup> symbolGroups = Collections.emptySet();\r
+\r
+    Collection<ISymbolGroup> toSymbolGroups(Resource... rs) {\r
+        Collection<ISymbolGroup> result = new ArrayList<ISymbolGroup>(rs.length);\r
+        for (int i = 0; i < rs.length; ++i) {\r
+            result.add(new SymbolGroup(rs[i]));\r
+        }\r
+        return result;\r
+    }\r
+\r
+    @Override\r
+    public void configure(ReadGraph g) throws ProjectException {\r
+//        IProject p = getProject();\r
+//        ISymbolManager sm = p.getHint(ISymbolManager.KEY_SYMBOL_MANAGER);\r
+//        if (sm != null) {\r
+//            Collection<Resource> grps;\r
+//            try {\r
+//                grps = g.syncRequest(new GroupDiscoveryQuery(p));\r
+//                AprosSymbolsFeature.this.symbolGroups = toSymbolGroups(grps.toArray(Resource.NONE));\r
+//                sm.addEntryPoints(symbolGroups);\r
+//            } catch (DatabaseException e) {\r
+//                throw new ProjectException(e);\r
+//            }\r
+//        }\r
+    }\r
+\r
+    @Override\r
+    public void deconfigure() throws ProjectException {\r
+        ISymbolManager sm = getProject().getHint(ISymbolManager.KEY_SYMBOL_MANAGER);\r
+        if (sm != null) {\r
+            sm.removeEntryPoints(symbolGroups);\r
+            symbolGroups = Collections.emptySet();\r
+        }\r
+    }\r
+\r
+    public class SymbolGroup implements ISymbolGroup {\r
+        final Resource r;\r
+\r
+        public SymbolGroup(Resource r) {\r
+            this.r = r;\r
+        }\r
+\r
+        @Override\r
+        public ISymbolItem[] getItems() {\r
+            RequestProcessor sgrp = getGraphRequestProcessor();\r
+            IProject project = peekProject();\r
+            if (project == null || sgrp == null)\r
+                return new ISymbolItem[0];\r
+            Collection<Resource> items;\r
+            try {\r
+                items = sgrp.syncRequest(new ElementDiscoveryQuery(r));\r
+                List<ISymbolItem> result = new ArrayList<ISymbolItem>();\r
+                for (Resource r : items) {\r
+                    result.add(new SymbolItem(this, r));\r
+                }\r
+                Collections.sort(result, new Comparator<ISymbolItem>() {\r
+                    @Override\r
+                    public int compare(ISymbolItem o1, ISymbolItem o2) {\r
+                        String n1 = o1.getName();\r
+                        String n2 = o2.getName();\r
+                        return n1.compareTo(n2);\r
+                    }\r
+                });\r
+                return result.toArray(new ISymbolItem[result.size()]);\r
+            } catch (DatabaseException e) {\r
+                throw new RuntimeException(e);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            try {\r
+                RequestProcessor sgrp = getGraphRequestProcessor();\r
+                IProject project = peekProject();\r
+                if (project == null || sgrp == null)\r
+                    return "(no project)";\r
+                return sgrp.syncRequest(new SafeLabelQuery(r));\r
+            } catch (DatabaseException e) {\r
+                throw new RuntimeException(e);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            return r.hashCode();\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj)\r
+                return true;\r
+            if (obj == null)\r
+                return false;\r
+            if (getClass() != obj.getClass())\r
+                return false;\r
+            SymbolGroup other = (SymbolGroup) obj;\r
+            return r.equals(other.r);\r
+        }\r
+    }\r
+\r
+    public class SymbolItem implements ISymbolItem {\r
+\r
+        final ISymbolGroup group;\r
+        final Resource r;\r
+\r
+        public SymbolItem(ISymbolGroup group, Resource r) {\r
+            this.group = group;\r
+            this.r = r;\r
+        }\r
+\r
+        @Override\r
+        public ISymbolGroup getGroup() {\r
+            return group;\r
+        }\r
+\r
+        @Override\r
+        public ElementClass getElementClass(IHintObservable hints) {\r
+            RequestProcessor sgrp = getGraphRequestProcessor();\r
+            if (sgrp == null)\r
+                throw new ProvisionException("No RequestProcessor available for querying an ElementClass for resource " + r);\r
+            try {\r
+                ElementClass ec = sgrp.syncRequest(DiagramRequests.getElementClass(r, hints));\r
+                if (ec == null)\r
+                    throw new ProvisionException("ElementClass query failed, returned null");\r
+                if (!ec.containsClass(StaticSymbol.class))\r
+                    throw new ProvisionException("ElementClass " + ec + " does not provide a StaticSymbol handler");\r
+                return ec;\r
+            } catch (DatabaseException e) {\r
+                throw new ProvisionException(e);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public String getName() {\r
+            try {\r
+                RequestProcessor sgrp = getGraphRequestProcessor();\r
+                // Return a safe "" if the query cannot be performed.\r
+                return sgrp != null ? sgrp.syncRequest(new SafeLabelQuery(r)) : "";\r
+            } catch (DatabaseException e) {\r
+                throw new RuntimeException(e);\r
+            }\r
+        }\r
+\r
+        @SuppressWarnings("unchecked")\r
+        @Override\r
+        public Object getAdapter(Class adapter) {\r
+            //if (adapter == ElementClass.class)\r
+            //    return getElementClass();\r
+            if (adapter == Resource.class)\r
+                return r;\r
+            return null;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + group.hashCode();\r
+            result = prime * result + r.hashCode();\r
+            return result;\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj)\r
+                return true;\r
+            if (obj == null)\r
+                return false;\r
+            if (getClass() != obj.getClass())\r
+                return false;\r
+            SymbolItem other = (SymbolItem) obj;\r
+            if (!group.equals(other.group))\r
+                return false;\r
+            return r.equals(other.r);\r
+        }\r
+    }\r
+\r
+    static class SafeLabelQuery extends ResourceRead<String> {\r
+        public SafeLabelQuery(Resource resource) {\r
+            super(resource);\r
+        }\r
+\r
+        @Override\r
+        public String perform(ReadGraph g) throws DatabaseException {\r
+            try {\r
+                return g.adapt(resource, String.class);\r
+            } catch (DatabaseException e) {\r
+                return GraphUtils.getReadableName(g, resource);\r
+            }\r
+        }\r
+    }\r
+\r
+    public static class GroupDiscoveryQuery implements Read<Collection<Resource>> {\r
+\r
+        IProject project;\r
+\r
+        GroupDiscoveryQuery(IProject project) {\r
+            assert project != null;\r
+            this.project = project;\r
+        }\r
+\r
+        @Override\r
+        public Collection<Resource> perform(ReadGraph g) throws DatabaseException {\r
+            try {\r
+                Resource[] eps = new Resource[] {\r
+                        g.getResource("http://www.simantics.org/Sysdyn-1.0/SymbolReferences")\r
+                };\r
+\r
+                final DiagramResource dr = DiagramResource.getInstance(g);\r
+                final ArrayList<Resource> groups = new ArrayList<Resource>();\r
+                for (Resource ep : eps) {\r
+                    GraphUtils.findResources(g, Collections.singletonList(ep), g.getBuiltins().ConsistsOf, new ResourceTester() {\r
+                        @Override\r
+                        public boolean test(ReadGraph g, Resource r) throws DatabaseException {\r
+                            return g.isInstanceOf(r, g.getBuiltins().Library)\r
+                            || g.isInstanceOf(r, dr.SymbolReferenceLibrary);\r
+                        }\r
+                    }, new MultiProcedureAdapter<Resource>() {\r
+                        @Override\r
+                        public void execute(Resource result) {\r
+                            groups.add(result);\r
+                        }\r
+                        @Override\r
+                        public void exception(Throwable t) {\r
+                            new Exception().printStackTrace();\r
+                            t.printStackTrace();\r
+                        }\r
+                    });\r
+                }\r
+                return groups;\r
+\r
+            } catch (ResourceNotFoundException e) {\r
+                throw new RuntimeException(e);\r
+            }\r
+        }\r
+\r
+        @Override\r
+        public boolean equals(Object obj) {\r
+            if (this == obj)\r
+                return true;\r
+            if (obj == null || getClass() != obj.getClass())\r
+                return false;\r
+            GroupDiscoveryQuery other = (GroupDiscoveryQuery) obj;\r
+            if (!project.equals(other.project))\r
+                return false;\r
+            return true;\r
+        }\r
+\r
+        @Override\r
+        public int hashCode() {\r
+            final int prime = 31;\r
+            int result = 1;\r
+            result = prime * result + ((project == null) ? 0 : project.hashCode());\r
+            return result;\r
+        }\r
+    }\r
+\r
+    static public class ElementDiscoveryQuery extends ResourceRead<Collection<Resource>> {\r
+        public ElementDiscoveryQuery(Resource resource) {\r
+            super(resource);\r
+        }\r
+        @Override\r
+        public Collection<Resource> perform(ReadGraph g) throws DatabaseException {\r
+            DiagramResource dr = DiagramResource.getInstance(g);\r
+            Collection<Resource> objs = g.getObjects(resource, g.getBuiltins().DependsOn);\r
+            // Filter out everything besides Elements.\r
+            ArrayList<Resource> result = new ArrayList<Resource>(objs.size());\r
+            for (Resource r : objs) {\r
+                if (g.isInheritedFrom(r, dr.Element))\r
+                    result.add( r );\r
+            }\r
+            return result;\r
+        }\r
+    }\r
+\r
+}\r
diff --git a/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java b/org.simantics.sysdyn.ui/src/org/simantics/sysdyn/ui/editor/SysdynCreationInstruction.java
new file mode 100644 (file)
index 0000000..ac3a25b
--- /dev/null
@@ -0,0 +1,65 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.sysdyn.ui.editor;\r
+\r
+import gnu.trove.TIntIntHashMap;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.URIStringUtils;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.mapping.constraint.instructions.TypedBracketInstruction.CreationInstruction;\r
+import org.simantics.modeling.services.ComponentNamingUtil;\r
+import org.simantics.modeling.services.NamingException;\r
+import org.simantics.project.IProject;\r
+\r
+public class SysdynCreationInstruction extends CreationInstruction {\r
+\r
+    IProject project;\r
+    Resource configurationRoot;\r
+    int lComponentType;\r
+    int lConfiguration;\r
+\r
+    public SysdynCreationInstruction(IProject project, Resource configurationRoot, int variableId, int componentType,\r
+            int configuration) {\r
+        super(variableId);\r
+        this.project = project;\r
+        this.configurationRoot = configurationRoot;\r
+        lComponentType = componentType;\r
+        lConfiguration = configuration;\r
+    }\r
+\r
+    @Override\r
+    public Resource create(WriteGraph g, Object[] bindings) throws DatabaseException {\r
+        Resource componentType = (Resource) bindings[lComponentType];\r
+        Resource configuration = (Resource) bindings[lConfiguration];\r
+\r
+        try {\r
+            String proposition = URIStringUtils.escape(ComponentNamingUtil.findFreshInstanceName(g, project, configurationRoot, configuration, componentType));\r
+            Resource result = GraphUtils.create(g,\r
+                    g.getBuiltins().HasName, proposition\r
+            );\r
+            return result;\r
+        } catch (NamingException e1) {\r
+            throw new DatabaseException(e1);\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void mapVariables(TIntIntHashMap map) {\r
+        super.mapVariables(map);\r
+        lComponentType = map.get(lComponentType);\r
+        lConfiguration = map.get(lConfiguration);\r
+    }\r
+\r
+}\r
index 6ace86f6c930dd84866921b9aa3604c95be4723f..967fc89cd04173800729ee2f626b847a7d350ddc 100644 (file)
@@ -55,6 +55,7 @@ import org.simantics.db.Resource;
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.db.procedure.Listener;\r
 import org.simantics.db.request.Read;\r
+import org.simantics.modeling.ModelingResources;\r
 import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.expressionParser.ExpressionParser;\r
 import org.simantics.sysdyn.expressionParser.ParseException;\r
@@ -68,6 +69,7 @@ import org.simantics.sysdyn.ui.equation.expressions.ExpressionField;
 import org.simantics.sysdyn.ui.equation.expressions.StockExpressionViewFactor;\r
 import org.simantics.ui.SimanticsUI;\r
 import org.simantics.ui.workbench.ResourceEditorInput;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
 import org.eclipse.jface.text.Position;\r
 \r
 public class EquationView extends ViewPart implements ISelectionListener {\r
@@ -173,6 +175,11 @@ public class EquationView extends ViewPart implements ISelectionListener {
         public Auxiliary perform(ReadGraph graph) throws DatabaseException {\r
             Builtins b = graph.getBuiltins();\r
             SysdynResource sr = SysdynResource.getInstance(graph);\r
+            ModelingResources mr = ModelingResources.getInstance(graph);\r
+            \r
+            Resource map = graph.getPossibleObject(resource, mr.ElementToComponent);\r
+            if(map != null) resource = map;\r
+            \r
             Auxiliary a = new Auxiliary();\r
             variable = resource;\r
             a.configuration = graph.getPossibleObject(variable, b.PartOf);\r
@@ -192,10 +199,11 @@ public class EquationView extends ViewPart implements ISelectionListener {
             IStructuredSelection structuredSelection = \r
                 (IStructuredSelection)selection;\r
             if(structuredSelection.size() == 1) {\r
-                Object element = structuredSelection.getFirstElement();\r
-                if(element instanceof Resource)\r
+//                Object element = structuredSelection.getFirstElement();\r
+                Resource res = ISelectionUtils.filterSingleSelection(structuredSelection, Resource.class);\r
+                if(res != null)\r
                     SimanticsUI.getSession().asyncRequest(\r
-                            new UpdateViewRequest((Resource)element),\r
+                            new UpdateViewRequest(res),\r
                             new Listener<Auxiliary>() {\r
 \r
                                 @Override\r
index 19d0611e98ea09fec96b9f4fdd76a6173587b20b..2168b7b6bacb552b18dbee6f002b0847d6d1d991 100644 (file)
@@ -55,7 +55,7 @@ public class NewModelHandler extends AbstractHandler {
                 graph.claim(model, b.HasConfiguration, conf);\r
                 \r
                 Resource mapping = graph.newResource();\r
-                graph.claim(mapping, b.InstanceOf, null, mr.DiagramToCompositeMapping);\r
+                graph.claim(mapping, b.InstanceOf, null, sr.DiagramToCompositeMapping);\r
                 graph.claim(diagram, b.HasTrigger, mapping);\r
             }\r
         });\r
index 255a6df5333cec0fd1fb463e6288d00af55a6bef..0a04685d3229e428fdf84dbda0a371fd0195b1a5 100644 (file)
@@ -13,6 +13,7 @@ package org.simantics.sysdyn.ui.trend;
 \r
 import java.awt.Frame;\r
 import java.util.HashMap;\r
+import java.util.Set;\r
 \r
 import javax.swing.SwingUtilities;\r
 \r
@@ -38,6 +39,7 @@ import org.simantics.db.common.request.ReadRequest;
 import org.simantics.db.exception.DatabaseException;\r
 import org.simantics.modelica.data.DataSet;\r
 import org.simantics.modelica.data.SimulationResult;\r
+import org.simantics.modeling.ModelingResources;\r
 import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.manager.SysdynModel;\r
 import org.simantics.sysdyn.manager.SysdynModelManager;\r
@@ -45,6 +47,7 @@ import org.simantics.sysdyn.representation.IElement;
 import org.simantics.sysdyn.representation.Variable;\r
 import org.simantics.sysdyn.ui.simulation.SimulationScheduler;\r
 import org.simantics.ui.SimanticsUI;\r
+import org.simantics.utils.ui.ISelectionUtils;\r
 import org.simantics.utils.ui.jface.ActiveSelectionProvider;\r
 \r
 public class TrendView extends ViewPart {\r
@@ -126,16 +129,17 @@ public class TrendView extends ViewPart {
             public void selectionChanged(IWorkbenchPart part, ISelection selection) {\r
                 if(selection.isEmpty() || Boolean.TRUE.equals(PinTrend.getState()))\r
                     return;\r
-                if(selection instanceof IStructuredSelection) {                    \r
-                    Object[] els = ((IStructuredSelection) selection).toArray();\r
-                    Resource[] resources = new Resource[els.length];\r
-                    for(int i=0;i<els.length;++i) {\r
-                        if(els[i] instanceof Resource)\r
-                            resources[i] = (Resource)els[i];\r
-                        else\r
-                            return;\r
-                    }\r
-                    setSelection(resources);\r
+                if(selection instanceof IStructuredSelection) {\r
+                       Set<Resource> ress = ISelectionUtils.filterSetSelection(selection, Resource.class);\r
+//                    Object[] els = ((IStructuredSelection) selection).toArray();\r
+//                    Resource[] resources = new Resource[els.length];\r
+//                    for(int i=0;i<els.length;++i) {\r
+//                        if(els[i] instanceof Resource)\r
+//                            resources[i] = (Resource)els[i];\r
+//                        else\r
+//                            return;\r
+//                    }\r
+                    setSelection(ress.toArray(Resource.NONE));\r
                 }                \r
             }\r
         });\r
@@ -216,6 +220,11 @@ public class TrendView extends ViewPart {
     protected DataSet load(ReadGraph g, Resource resource) throws DatabaseException {\r
         Builtins b = g.getBuiltins();\r
         SysdynResource sr = SysdynResource.getInstance(g);\r
+        \r
+        ModelingResources mr = ModelingResources.getInstance(g);\r
+        Resource map = g.getPossibleObject(resource, mr.ElementToComponent);\r
+        if(map != null) resource = map;\r
+        \r
         if(g.isInstanceOf(resource, sr.Variable)) {\r
             Resource configuration = g.getPossibleObject(resource, b.PartOf);\r
             if(g.isInstanceOf(configuration, sr.Configuration)) {\r
index 3e0218acf3fa198b30e3e53ea326622eda5d52af..d24dac9a9a5d74a8c581218519ed0bdd0bb40421 100644 (file)
@@ -28,6 +28,7 @@ public class SysdynResource {
     public final Resource ConstantExpression;\r
     public final Resource DelayExpression;\r
     public final Resource Dependency;\r
+    public final Resource DiagramToCompositeMapping;\r
     public final Resource Expression;\r
     public final Resource Flow;\r
     public final Resource HasAngle;\r
@@ -51,12 +52,15 @@ public class SysdynResource {
     public final Resource Module;\r
     public final Resource NormalExpression;\r
     public final Resource ParameterExpression;\r
+    public final Resource PhantomTerminal;\r
     public final Resource RefersTo;\r
     public final Resource Stock;\r
     public final Resource StockExpression;\r
     public final Resource StockSymbol;\r
+    public final Resource SysdynConnectionType;\r
     public final Resource SysdynModel;\r
     public final Resource SysdynProject;\r
+    public final Resource SysdynSymbols;\r
     public final Resource Terminal;\r
     public final Resource Valve;\r
     public final Resource ValveSymbol;\r
@@ -72,6 +76,7 @@ public class SysdynResource {
         public static final String ConstantExpression = "http://www.simantics.org/Sysdyn-1.0/ConstantExpression";\r
         public static final String DelayExpression = "http://www.simantics.org/Sysdyn-1.0/DelayExpression";\r
         public static final String Dependency = "http://www.simantics.org/Sysdyn-1.0/Dependency";\r
+        public static final String DiagramToCompositeMapping = "http://www.simantics.org/Sysdyn-1.0/DiagramToCompositeMapping";\r
         public static final String Expression = "http://www.simantics.org/Sysdyn-1.0/Expression";\r
         public static final String Flow = "http://www.simantics.org/Sysdyn-1.0/Flow";\r
         public static final String HasAngle = "http://www.simantics.org/Sysdyn-1.0/HasAngle";\r
@@ -95,12 +100,15 @@ public class SysdynResource {
         public static final String Module = "http://www.simantics.org/Sysdyn-1.0/Module";\r
         public static final String NormalExpression = "http://www.simantics.org/Sysdyn-1.0/NormalExpression";\r
         public static final String ParameterExpression = "http://www.simantics.org/Sysdyn-1.0/ParameterExpression";\r
+        public static final String PhantomTerminal = "http://www.simantics.org/Sysdyn-1.0/PhantomTerminal";\r
         public static final String RefersTo = "http://www.simantics.org/Sysdyn-1.0/RefersTo";\r
         public static final String Stock = "http://www.simantics.org/Sysdyn-1.0/Stock";\r
         public static final String StockExpression = "http://www.simantics.org/Sysdyn-1.0/StockExpression";\r
         public static final String StockSymbol = "http://www.simantics.org/Sysdyn-1.0/StockSymbol";\r
+        public static final String SysdynConnectionType = "http://www.simantics.org/Sysdyn-1.0/SysdynConnectionType";\r
         public static final String SysdynModel = "http://www.simantics.org/Sysdyn-1.0/SysdynModel";\r
         public static final String SysdynProject = "http://www.simantics.org/Sysdyn-1.0/SysdynProject";\r
+        public static final String SysdynSymbols = "http://www.simantics.org/Sysdyn-1.0/SysdynSymbols";\r
         public static final String Terminal = "http://www.simantics.org/Sysdyn-1.0/Terminal";\r
         public static final String Valve = "http://www.simantics.org/Sysdyn-1.0/Valve";\r
         public static final String ValveSymbol = "http://www.simantics.org/Sysdyn-1.0/ValveSymbol";\r
@@ -126,6 +134,7 @@ public class SysdynResource {
         ConstantExpression = getResourceOrNull(graph, URIs.ConstantExpression);\r
         DelayExpression = getResourceOrNull(graph, URIs.DelayExpression);\r
         Dependency = getResourceOrNull(graph, URIs.Dependency);\r
+        DiagramToCompositeMapping = getResourceOrNull(graph, URIs.DiagramToCompositeMapping);\r
         Expression = getResourceOrNull(graph, URIs.Expression);\r
         Flow = getResourceOrNull(graph, URIs.Flow);\r
         HasAngle = getResourceOrNull(graph, URIs.HasAngle);\r
@@ -149,12 +158,15 @@ public class SysdynResource {
         Module = getResourceOrNull(graph, URIs.Module);\r
         NormalExpression = getResourceOrNull(graph, URIs.NormalExpression);\r
         ParameterExpression = getResourceOrNull(graph, URIs.ParameterExpression);\r
+        PhantomTerminal = getResourceOrNull(graph, URIs.PhantomTerminal);\r
         RefersTo = getResourceOrNull(graph, URIs.RefersTo);\r
         Stock = getResourceOrNull(graph, URIs.Stock);\r
         StockExpression = getResourceOrNull(graph, URIs.StockExpression);\r
         StockSymbol = getResourceOrNull(graph, URIs.StockSymbol);\r
+        SysdynConnectionType = getResourceOrNull(graph, URIs.SysdynConnectionType);\r
         SysdynModel = getResourceOrNull(graph, URIs.SysdynModel);\r
         SysdynProject = getResourceOrNull(graph, URIs.SysdynProject);\r
+        SysdynSymbols = getResourceOrNull(graph, URIs.SysdynSymbols);\r
         Terminal = getResourceOrNull(graph, URIs.Terminal);\r
         Valve = getResourceOrNull(graph, URIs.Valve);\r
         ValveSymbol = getResourceOrNull(graph, URIs.ValveSymbol);\r
index 843342aeff1aeecd19fcbfaad9ee9674f7758c5e..1b9d238878d95d70358d865fe0e5d6b1d2f1f4c8 100644 (file)
@@ -36,6 +36,17 @@ SysdynProject : PROJ.Feature
     L0.HasDescription """System dynamics modelling project. Create system dynamics models and simulate them with OpenModelica.""" : L0.String\r
     L0.PartOf Sysdyn\r
     L0.PartOf PROJ.PublishedProjectFeatures\r
+    PROJ.RequiresFeature\r
+      ImportedOntologies : PROJ.OntologyRequirementValidationFeature\r
+        L0.HasDescription "Specifies the ontologies required by a Sysdyn project." : L0.String\r
+        PROJ.RequiresNamespace\r
+          "http://www.simantics.org/Sysdyn-1.0" : L0.URI\r
+      SysdynSymbols\r
+\r
+SysdynSymbols : PROJ.Feature\r
+    L0.PartOf Sysdyn\r
+    L0.HasLabel "Sysdyn symbols" : L0.String\r
+    L0.HasDescription """Sysdyn symbols.""" : L0.String\r
     PROJ.RequiresFeature WORKBENCH.SymbolManager\r
 \r
 ######################################################################\r
@@ -49,6 +60,14 @@ SysdynModel <T SIMU.Model
 ######################################################################\r
 # Configuration\r
 ######################################################################\r
+\r
+Sysdyn \r
+  L0.ConsistsOf\r
+    Symbols : L0.Library\r
+    SysdynConnectionType : ST.ConnectionType\r
+\r
+DiagramToCompositeMapping <T L0.Trigger\r
+  L0.PartOf Sysdyn\r
        \r
 ConfigurationDiagram <T DIA.Diagram\r
   L0.PartOf Sysdyn\r
@@ -56,7 +75,7 @@ ConfigurationDiagram <T DIA.Diagram
   DIA.HasSymbolContribution _ : DIA.BasicSymbolContribution\r
     DIA.BasicSymbolContributionHasSymbolLibrary\r
        BasicSymbolLibrary\r
-       \r
+\r
 SysdynDiagramModelingRules : MOD.MappedModelingRules\r
   MOD.HasBaseRules ST.StandardModelingRules\r
   \r
@@ -91,7 +110,7 @@ HasY <R L0.HasProperty : L0.FunctionalRelation
 HasExpression <R L0.IsRelatedTo : L0.FunctionalRelation\r
     L0.HasRange Expression\r
     \r
-HasType <R L0.HasProperty\r
+HasType <R L0.HasProperty : L0.FunctionalRelation\r
     L0.HasRange L0.String\r
 \r
 HasUnit <R L0.HasProperty\r
@@ -106,8 +125,14 @@ IndependentVariable <T Variable
 Auxiliary <T IndependentVariable\r
 \r
 Valve <T IndependentVariable\r
+  L0.Asserts _ : L0.Assertion\r
+    L0.HasPredicate L0.HasType\r
+    L0.HasObject "Real" : L0.String\r
     \r
 Stock <T IndependentVariable\r
+  L0.Asserts _ : L0.Assertion\r
+    L0.HasPredicate L0.HasType\r
+    L0.HasObject "Real" : L0.String\r
 \r
 Cloud <T Variable      \r
 \r
@@ -128,10 +153,14 @@ IsTailOf <R ST.IsConnectedTo
     L0.HasDomain Variable\r
     L0.HasRange Dependency\r
     L0.InverseOf HasTail \r
+    ST.AllowsConnectionType SysdynConnectionType\r
+    ST.HasAttachmentRelation DIA.HasInput\r
 IsHeadOf <R ST.IsConnectedTo\r
     L0.HasDomain Variable\r
     L0.HasRange Dependency\r
     L0.InverseOf HasHead\r
+    ST.AllowsConnectionType SysdynConnectionType\r
+    ST.HasAttachmentRelation DIA.HasOutput\r
 \r
 Dependency <T ST.Connection\r
     [HasAngle card "1"]\r
@@ -190,18 +219,105 @@ WithLookupExpression <T Expression
 # Symbols\r
 ######################################################################\r
 \r
-Auxiliary\r
-  MOD.ComponentTypeToSymbol AuxiliarySymbol <T DIA.DefinedElement\r
-    L0.HasLabel "Auxiliary" : L0.String\r
-    L0.IsDependencyOf BasicSymbolLibrary\r
-    ST.IsDefinedBy %list : DIA.Composite <R L0.HasNext\r
+#Auxiliary\r
+#  MOD.ComponentTypeToSymbol AuxiliarySymbol <T DIA.DefinedElement\r
+#    L0.HasLabel "Auxiliary" : L0.String\r
+#    L0.IsDependencyOf BasicSymbolLibrary\r
+#    ST.IsDefinedBy %list : DIA.Composite <R L0.HasNext\r
+#      _ : DIA.SVGElement\r
+#        G2D.HasSVGDocument """<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+#<svg xmlns="http://www.w3.org/2000/svg" overflow="visible">\r
+#<ellipse cx="0" cy="0" rx="8" ry="4" stroke="black" stroke-width="0.2" fill="none" />\r
+#</svg>""" : L0.String\r
+\r
+#Stock\r
+#  MOD.ComponentTypeToSymbol StockSymbol <T DIA.DefinedElement\r
+#    L0.HasLabel "Stock" : L0.String\r
+#    L0.IsDependencyOf BasicSymbolLibrary\r
+#    ST.IsDefinedBy %list : DIA.Composite <R L0.HasNext\r
+#      _ : DIA.SVGElement\r
+#        G2D.HasSVGDocument """<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+#<svg xmlns="http://www.w3.org/2000/svg" overflow="visible">\r
+#<rect x="-8" y="-4" width="16" height="8" stroke="black" stroke-width="0.2" fill="none"/>\r
+#</svg>""" : L0.String\r
+\r
+\r
+#Valve\r
+#  MOD.ComponentTypeToSymbol ValveSymbol <T DIA.DefinedElement\r
+#    L0.HasLabel "Valve" : L0.String\r
+#    L0.IsDependencyOf BasicSymbolLibrary\r
+#    ST.IsDefinedBy %list : DIA.Composite <R L0.HasNext\r
+#      _ : DIA.SVGElement\r
+#        G2D.HasSVGDocument """<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+#<svg xmlns="http://www.w3.org/2000/svg" overflow="visible">\r
+#<path\r
+#     stroke="black" stroke-width="0.2" fill="none"\r
+#     d="M-3 3 L3 -3 L-3 -3 L3 3 Z" />     \r
+#</svg>""" : L0.String\r
+\r
+\r
+\r
+\r
+\r
+######################################################################\r
+# Terminal\r
+######################################################################\r
+\r
+PhantomTerminal <T DIA.DefinedElement <T DIA.Terminal\r
+  ST.IsDefinedBy %list : DIA.Composite <R L0.IsRelatedTo\r
+    _ : DIA.SVGElement\r
+      G2D.HasSVGDocument """<?xml version="1.0" encoding="UTF-8" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" overflow="visible" version="1.1"><ellipse cx="0.0" cy="0.0" rx="1.0" ry="1.0" fill="none" stroke-width="0.1" stroke="none"/></svg>""" : L0.String\r
+  L0.PartOf Sysdyn      \r
+\r
+######################################################################\r
+# Macros for component types\r
+######################################################################\r
+\r
+%define def()\r
+  $subject <T ST.Component\r
+    L0.PartOf Sysdyn\r
+\r
+%define connection($relation)\r
+  $subject\r
+    ST.HasParameter _ : ST.ConnectionVariable\r
+      ST.Binds $relation\r
+\r
+######################################################################\r
+# Macros for symbols\r
+######################################################################\r
+\r
+%define defSymbol($library, $svg)\r
+  $subject <T DIA.DefinedElement\r
+    L0.IsDependencyOf $library\r
+    ST.IsDefinedBy %list : DIA.Composite <R L0.IsRelatedTo\r
       _ : DIA.SVGElement\r
-        G2D.HasSVGDocument """<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
-<svg xmlns="http://www.w3.org/2000/svg" overflow="visible">\r
-<ellipse cx="0" cy="0" rx="8" ry="4" stroke="black" stroke-width="0.2" fill="none" />\r
-</svg>""" : L0.String\r
+        G2D.HasSVGDocument $svg : L0.String\r
+\r
+%define terminal($transform, $parent, $target)\r
+  $subject\r
+    G2D.HasTransform $transform : G2D.Transform\r
+    DIA.HasConnectionVariable _ : ST.ConnectionVariable\r
+      ST.Binds _ <R ST.IsConnectedTo\r
+        MOD.DiagramConnectionRelationToConnectionRelation $target\r
+      ST.IsParameterOf $parent\r
+\r
 \r
+######################################################################\r
+# Component types\r
+######################################################################\r
+\r
+%define defConnectionPoint($connectionType, $attachmentRelation)\r
+  $subject <R ST.IsConnectedTo \r
+      ST.AllowsConnectionType $connectionType\r
+      ST.HasAttachmentRelation $attachmentRelation\r
+\r
+\r
+######################################################################\r
 Stock\r
+  def()\r
+  connection(IsTailOf)\r
+  connection(IsHeadOf)\r
+  # symbol\r
   MOD.ComponentTypeToSymbol StockSymbol <T DIA.DefinedElement\r
     L0.HasLabel "Stock" : L0.String\r
     L0.IsDependencyOf BasicSymbolLibrary\r
@@ -211,9 +327,17 @@ Stock
 <svg xmlns="http://www.w3.org/2000/svg" overflow="visible">\r
 <rect x="-8" y="-4" width="16" height="8" stroke="black" stroke-width="0.2" fill="none"/>\r
 </svg>""" : L0.String\r
+      _ : PhantomTerminal\r
+        terminal("1,0,0,1,-7,0", StockSymbol , IsHeadOf)\r
+      _ : PhantomTerminal\r
+        terminal("1,0,0,1,7,0", StockSymbol , IsTailOf)\r
 \r
-\r
+######################################################################\r
 Valve\r
+  def()\r
+  connection(IsTailOf)\r
+  connection(IsHeadOf)\r
+  # symbol\r
   MOD.ComponentTypeToSymbol ValveSymbol <T DIA.DefinedElement\r
     L0.HasLabel "Valve" : L0.String\r
     L0.IsDependencyOf BasicSymbolLibrary\r
@@ -225,4 +349,28 @@ Valve
      stroke="black" stroke-width="0.2" fill="none"\r
      d="M-3 3 L3 -3 L-3 -3 L3 3 Z" />     \r
 </svg>""" : L0.String\r
+      _ : PhantomTerminal\r
+        terminal("1,0,0,1,-7,0", ValveSymbol, IsHeadOf)\r
+      _ : PhantomTerminal\r
+        terminal("1,0,0,1,7,0", ValveSymbol, IsTailOf)\r
+\r
+######################################################################\r
+Auxiliary\r
+  def()\r
+  connection(IsTailOf)\r
+  connection(IsHeadOf)\r
+  # symbol\r
+  MOD.ComponentTypeToSymbol AuxiliarySymbol <T DIA.DefinedElement\r
+    L0.HasLabel "Valve" : L0.String\r
+    L0.IsDependencyOf BasicSymbolLibrary\r
+    ST.IsDefinedBy %list : DIA.Composite <R L0.HasNext\r
+      _ : DIA.SVGElement\r
+        G2D.HasSVGDocument """<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<svg xmlns="http://www.w3.org/2000/svg" overflow="visible">\r
+<ellipse cx="0" cy="0" rx="8" ry="4" stroke="black" stroke-width="0.2" fill="none" />\r
+</svg>""" : L0.String\r
+      _ : PhantomTerminal\r
+        terminal("1,0,0,1,-7,0", AuxiliarySymbol, IsHeadOf)\r
+      _ : PhantomTerminal\r
+        terminal("1,0,0,1,7,0", AuxiliarySymbol, IsTailOf)\r
 \r