]> gerrit.simantics Code Review - simantics/sysdyn.git/commitdiff
Update vensim import with more subscript support
authorjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 9 Apr 2014 12:38:31 +0000 (12:38 +0000)
committerjkauttio <jkauttio@ac1ea38d-2e2b-0410-8846-a27921b304fc>
Wed, 9 Apr 2014 12:38:31 +0000 (12:38 +0000)
refs #2924

git-svn-id: https://www.simantics.org/svn/simantics/sysdyn/branches/dev-jkauttio@29264 ac1ea38d-2e2b-0410-8846-a27921b304fc

28 files changed:
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlParser.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/MdlUtil.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/MdlModel.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/Sketch.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SketchComment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SketchConnection.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SketchElement.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SketchObject.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SketchValve.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/SketchVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/Subscript.java [deleted file]
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/Model.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/WriteContext.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Auxiliary.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Cloud.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Comment.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Connection.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Dependency.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Flow.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/ModelVariable.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Shadow.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Stock.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Symbol.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/element/Valve.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/expression/EnumerationExpression.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/expression/Expression.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/expression/IntegralExpression.java
org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/model/support/Enumeration.java

index 82e8e07e2e59d0f2a4a8aa069b1029c562c3e9c5..62e8a6686a239ff81b1726ae6919baf0e59812fe 100644 (file)
@@ -28,7 +28,6 @@ import org.simantics.sysdyn.modelImport.mdl.SketchElement;
 import org.simantics.sysdyn.modelImport.mdl.SketchObject;\r
 import org.simantics.sysdyn.modelImport.mdl.SketchValve;\r
 import org.simantics.sysdyn.modelImport.mdl.SketchVariable;\r
-import org.simantics.sysdyn.modelImport.mdl.Subscript;\r
 import org.simantics.sysdyn.modelImport.model.Model;\r
 import org.simantics.sysdyn.modelImport.model.element.Auxiliary;\r
 import org.simantics.sysdyn.modelImport.model.element.Cloud;\r
@@ -41,30 +40,18 @@ import org.simantics.sysdyn.modelImport.model.element.Stock;
 import org.simantics.sysdyn.modelImport.model.element.Valve;\r
 import org.simantics.sysdyn.modelImport.model.expression.IntegralExpression;\r
 import org.simantics.sysdyn.modelImport.model.expression.NormalExpression;\r
+import org.simantics.sysdyn.modelImport.model.support.Enumeration;\r
 import org.simantics.sysdyn.modelImport.model.support.Variable;\r
 \r
 public class MdlParser {\r
 \r
-       private static final String UTF_8 = "{UTF-8}";\r
-       private static final String SKETCH_VERSION = "V300";\r
-\r
-       private static final String CATEGORY_CONTROL = "Control";\r
-\r
-       // each .mdl is divided into three sections, these are the the delimiter\r
-       // strings used to identify where each section starts\r
-       private static final String SKETCH_START = "\\\\\\---///";\r
-       private static final String SKETCH_END = "///---\\\\\\";\r
-\r
-       private static final double H_SPACE = 0;\r
-       private static final double V_SPACE = 10;\r
-\r
        public static Model parse(File file) {\r
                // generate a mdl model based on the contents of the file\r
                MdlModel mdl;\r
                try {\r
                        mdl = parseFile(file);\r
                }\r
-               catch (IOException e) {\r
+               catch (Exception e) {\r
                        e.printStackTrace();\r
                        return null;\r
                }\r
@@ -73,106 +60,65 @@ public class MdlParser {
                Model model = new Model(mdl.getName());\r
 \r
                double offset = 0;\r
-\r
-               // do this in several passes\r
-\r
-               HashMap<Variable, Symbol> variableToElement = new HashMap<Variable, Symbol>();\r
-\r
+               \r
+               // add anumerations\r
+               for (Enumeration enumeration : mdl.getSubscripts()) {\r
+                       model.addEnumeration(enumeration);\r
+               }\r
+               \r
                // add sketch labels and independent elements\r
                for (Sketch sketch : mdl.getSketches()) {\r
-                       sketch.setEdges();\r
-\r
-                       sketch.hOffset = 0;\r
-                       sketch.vOffset = 0 - sketch.topEdge + 10 + offset;\r
-\r
-                       model.addElement(new Comment(0, offset, -1, -1, sketch.getName()));\r
-\r
-                       for (SketchComment comment : sketch.getComments()) {\r
-                               if (comment.isInputOutput()) {\r
-                                       // input / output objects are not supported yet\r
-                                       System.err.println("input / output objects are not supported yet");\r
-                                       continue;\r
-                               }\r
-\r
-                               Symbol modelElement = comment.getModelElement(sketch.hOffset, sketch.vOffset);\r
-                               model.addElement(modelElement);\r
-                               sketch.elements.put(comment.getId(), modelElement);\r
-                       }\r
-\r
-                       for (SketchValve valve : sketch.getValves()) {\r
-                               Symbol modelElement = valve.getModelElement(sketch.hOffset, sketch.vOffset);\r
-                               model.addElement(modelElement);\r
-                               sketch.elements.put(valve.getId(), modelElement);\r
-                               sketch.elements.put(valve.getAttachedVariable().getId(), modelElement);\r
-                               variableToElement.put(valve.getAttachedVariable().getVariable(), modelElement);\r
+                       \r
+                       sketch.setOffset(0, offset);\r
+\r
+                       model.addSymbol(new Comment(0, offset, -1, -1, sketch.getName()));\r
+                       \r
+                       for (SketchElement element : sketch.getIndependentElements()) {\r
+                               Symbol symbol = element.getSymbol(sketch);\r
+                               element.setModelObject(symbol);\r
+                               model.addSymbol(symbol);\r
                        }\r
-\r
-                       for (SketchVariable variable : sketch.getVariables()) {\r
-                               if (!variable.allowsIn()) {\r
-                                       // the variable is a shadow variable, skip these for now\r
-                                       continue;\r
-                               }\r
-\r
-                               if (variable.isAttached()) {\r
-                                       // the variable is attached to a valve, already handled\r
-                                       continue;\r
-                               }\r
-\r
-                               Symbol modelElement = variable.getModelElement(sketch.hOffset, sketch.vOffset);\r
-                               model.addElement(modelElement);\r
-                               sketch.elements.put(variable.getId(), modelElement);\r
-                               variableToElement.put(variable.getVariable(), modelElement);\r
-                       }\r
-\r
-                       offset += (sketch.bottomEdge - sketch.topEdge + V_SPACE);\r
+                       \r
+                       offset += 200;\r
                }\r
 \r
                // add dependent elements\r
                for (Sketch sketch : mdl.getSketches()) {\r
-                       for (SketchVariable variable : sketch.getVariables()) {\r
-                               if (!variable.allowsIn()) {\r
-                                       // the variable is a shadow variable\r
-                                       Symbol original = variableToElement.get(variable.getVariable());\r
-                                       if (original == null) {\r
-                                               System.err.println("original not found for "+variable.getVariable().getName());\r
-                                               Symbol modelElement = variable.getModelElement(sketch.hOffset, sketch.vOffset);\r
-                                               model.addElement(modelElement);\r
-                                               sketch.elements.put(variable.getId(), modelElement);\r
-                                               variableToElement.put(variable.getVariable(), modelElement);\r
-                                       } \r
-                                       else {\r
-                                               Shadow modelElement = new Shadow(\r
-                                                               variable.getSysdyndX() + sketch.hOffset, \r
-                                                               variable.getSysdyndY() + sketch.vOffset, \r
-                                                               variable.getSysdynWidth(),\r
-                                                               variable.getSysdynHeight(),\r
-                                                               (ModelVariable)variableToElement.get(variable.getVariable()));\r
-                                               model.addShadow(modelElement);\r
-                                               sketch.elements.put(variable.getId(), modelElement);\r
-                                       }\r
+                       for (SketchVariable variable : sketch.getShadowVariables()) {\r
+                               if (variable.getVariable() == null) {\r
+                                       System.err.println("null variable");\r
+                                       continue;\r
                                }\r
+                               ModelVariable original = model.getVariable(variable.getVariable().getName());\r
+                               System.err.println("original variable "+original);\r
+                               Symbol symbol = original != null ? new Shadow(variable.getDimensions(sketch), original) : variable.getSymbol(sketch);\r
+                               variable.setModelObject(symbol);\r
+                               model.addSymbol(symbol);\r
                        }\r
 \r
                        for (SketchConnection connection : sketch.getConnections()) {\r
-                               Symbol head = sketch.elements.get(connection.getTo());\r
-                               Symbol tail = sketch.elements.get(connection.getFrom());\r
-                               Connection c = connection.getWriteableConnection(head, tail, sketch.vOffset);\r
-                               if (c != null) {\r
-                                       model.addConnection(c);\r
+                               Connection conn = connection.getConnection(sketch);\r
+                               if (conn != null) {\r
+                                       connection.setModelObject(conn);\r
+                                       model.addConnection(conn);\r
                                }\r
                        }\r
                }\r
+               \r
+               // Set simulation parameters\r
 \r
                return model;\r
        }\r
+       \r
+       private static final String UTF_8 = "{UTF-8}";\r
+       private static final String SKETCH_VERSION = "V300";\r
+       private static final String SKETCH_START = "\\\\\\---///";\r
+       private static final String SKETCH_END = "///---\\\\\\";\r
 \r
        private static MdlModel parseFile(File file) \r
-                       throws IOException {\r
+                       throws Exception {\r
                MdlModel mdl = new MdlModel(file.getName());\r
                \r
-               // TODO: do this somewhere else and more controlled\r
-               mdl.addVariable(new Variable("Time", new NormalExpression("time"), "", null, ""), null);\r
-\r
                // peek at the first line to see if we need to use UTF-8\r
                BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));\r
                String line = reader.readLine();\r
@@ -212,25 +158,23 @@ public class MdlParser {
                        } while ((line = reader.readLine()) != null);\r
                        String str = buffer.toString();\r
 \r
+                       ArrayList<Variable> variables = new ArrayList<Variable>();\r
+                       \r
                        String cat;\r
                        Variable var;\r
-                       Subscript sub;\r
+                       Enumeration sub;\r
 \r
                        // parse the (possible) variable declaration\r
                        if ((cat = MdlUtil.getPossibleCategory(str)) != null) {\r
                                category = cat;\r
                        }\r
-                       else if ((var = MdlUtil.getPossibleVariable(str, category)) != null) {\r
+                       else if ((var = MdlUtil.getPossibleNormalVariable(str)) != null) {\r
                                mdl.addVariable(var, category);\r
                        }\r
-                       else if ((var = MdlUtil.getPossibleSubscriptVariable(str, category, mdl)) != null) {\r
-                               Variable orig = mdl.getVariable(var.getName());\r
-                               if (orig != null)\r
-                                       orig.mergeWithVariable(var);\r
-                               else\r
-                                       mdl.addVariable(var, category);\r
+                       else if ((var = MdlUtil.getPossibleSubscriptVariable(str)) != null) {\r
+                               mdl.addVariable(var, category);\r
                        }\r
-                       else if ((var = MdlUtil.getPossibleLookUpVariable(str, category)) != null) {\r
+                       else if ((var = MdlUtil.getPossibleLookUpVariable(str)) != null) {\r
                                mdl.addVariable(var, category);\r
                        }\r
                        else if ((var = MdlUtil.getPossibleNoExpressionVariable(str)) != null) {\r
@@ -241,17 +185,17 @@ public class MdlParser {
                        }\r
                        else {\r
                                // if we got this far, the variable could not be parsed\r
-                               System.err.println("unrecognized variable "+str);\r
+                               throw new Exception("unrecognized variable "+str);\r
                        }\r
 \r
                } while ((line = reader.readLine()) != null && !line.startsWith(SKETCH_START));\r
+               \r
+               // add all variables to the model\r
 \r
                // END READING VARIABLE DATA\r
 \r
                if (line == null) {\r
-                       System.err.println("unexpected end of file");\r
-                       reader.close();\r
-                       return null;\r
+                       throw new Exception("unexpected end of file");\r
                }\r
 \r
                // START READING SKETCH DATA\r
@@ -283,19 +227,17 @@ public class MdlParser {
                                sketch.addConnection((SketchConnection)so);\r
                        }\r
                        else if ((so = MdlUtil.getPossibleSketchVariable(line, mdl)) != null) {\r
-                               SketchVariable variable = (SketchVariable)so;\r
-                               sketch.addVariable(variable);\r
+                               sketch.addVariable((SketchVariable)so);\r
                        }\r
                        else if ((so = MdlUtil.getPossibleSketchValve(line)) != null) {\r
                                SketchValve valve = (SketchValve)so;\r
                                // the next row after a valve should always the variable associated with the valve\r
                                SketchVariable attached = MdlUtil.getPossibleSketchVariable(reader.readLine(), mdl);\r
                                if (attached == null || !attached.isAttached()) {\r
-                                       System.err.println("attached variable not found for valve");\r
+                                       throw new Exception("attached variable not found for valve");\r
                                }\r
                                valve.setAttachedVariable(attached);\r
-                               sketch.addValve((SketchValve)valve);\r
-                               sketch.addVariable(attached);\r
+                               sketch.addValve(valve);\r
                        }\r
                        else if ((so = MdlUtil.getPossibleSketchComment(line)) != null) {\r
                                SketchComment comment = (SketchComment)so;\r
@@ -306,7 +248,7 @@ public class MdlParser {
                        }\r
                        else {\r
                                // if we got this far, the element could not be parsed\r
-                               System.err.println("unrecognized element "+line);\r
+                               throw new Exception("unrecognized element "+line);\r
                        }\r
 \r
                } while ((line = reader.readLine()) != null && !line.startsWith(SKETCH_END));\r
@@ -314,9 +256,7 @@ public class MdlParser {
                // END READING SKETCH DATA\r
 \r
                if (line == null) {\r
-                       System.err.println("unexpected end of file");\r
-                       reader.close();\r
-                       return null;\r
+                       throw new Exception("unexpected end of file");\r
                }\r
 \r
                // START READING OTHER DATA\r
index 51d104e3cbac94f944739fac94387672568e4fae..d1787bbd02806248964b2be01a172742e2f751f9 100644 (file)
@@ -10,7 +10,6 @@ import org.simantics.sysdyn.modelImport.mdl.SketchConnection;
 import org.simantics.sysdyn.modelImport.mdl.SketchElement;\r
 import org.simantics.sysdyn.modelImport.mdl.SketchValve;\r
 import org.simantics.sysdyn.modelImport.mdl.SketchVariable;\r
-import org.simantics.sysdyn.modelImport.mdl.Subscript;\r
 import org.simantics.sysdyn.modelImport.model.element.Valve.TextPosition;\r
 import org.simantics.sysdyn.modelImport.model.expression.DelayExpression;\r
 import org.simantics.sysdyn.modelImport.model.expression.Expression;\r
@@ -18,6 +17,7 @@ import org.simantics.sysdyn.modelImport.model.expression.IntegralExpression;
 import org.simantics.sysdyn.modelImport.model.expression.LookupExpression;\r
 import org.simantics.sysdyn.modelImport.model.expression.NormalExpression;\r
 import org.simantics.sysdyn.modelImport.model.expression.EnumerationExpression;\r
+import org.simantics.sysdyn.modelImport.model.support.Enumeration;\r
 import org.simantics.sysdyn.modelImport.model.support.Range;\r
 import org.simantics.sysdyn.modelImport.model.support.Variable;\r
 \r
@@ -44,12 +44,32 @@ public class MdlUtil {
                        "\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"";\r
        private static final String VAR_NAME_SIMPLE =\r
                        "[A-Za-z](?![ \\w]*\\()(?: *\\w+)*";\r
-       private static final String VAR_NAME =\r
+       private static final String VAR_NAME_NORMAL =\r
                        "("+VAR_NAME_QUOTED+"|"+VAR_NAME_SIMPLE+")";\r
        \r
-       private static final String VARIABLE_PATTERN =\r
-                       VAR_NAME+"\\s*=\\s*";\r
-       private static final String EQUATION_PATTERN =\r
+       // a subscript variable is a variable that has a different equation\r
+       // depending on the value of the subscript it references\r
+       private static final String VAR_NAME_SUBSCRIPT =\r
+                       "("+VAR_NAME_SIMPLE+")\\[("+VAR_NAME_SIMPLE+"(?:,"+VAR_NAME_SIMPLE+")*)\\]";\r
+       \r
+       // a lookup variable contains a set of points\r
+       private static final String LOOKUP_NAME =\r
+                       "([A-Za-z](?: *\\w+)*)";\r
+       private static final String LOOKUP_RANGE =\r
+                       "\\[\\(("+NUMBER+"),("+NUMBER+")\\)-\\(("+NUMBER+"),("+NUMBER+")\\)\\]";\r
+       private static final String LOOKUP_POINTS =\r
+                       "(\\("+NUMBER+","+NUMBER+"\\)(?:,\\("+NUMBER+","+NUMBER+"\\))*)";\r
+       \r
+       private static final String NORMAL_NAME_PATTERN =\r
+                       VAR_NAME_NORMAL+"\\s*=\\s*";\r
+       private static final String SUBSCRIPT_NAME_PATTERN =\r
+                       VAR_NAME_SUBSCRIPT+"\\s*=\\s*";\r
+       private static final String LOOKUP_NAME_PATTERN =\r
+                       LOOKUP_NAME+"\\s*\\(\\s*"+LOOKUP_RANGE+","+LOOKUP_POINTS+"\\s*\\)\\s*~\\s*";\r
+       public static final String NO_EXPRESSION_NAME_PATTERN = \r
+                       VAR_NAME_NORMAL+"\\s*~\\s*";\r
+       \r
+       private static final String EXPRESSION_PATTERN =\r
                        "([^~]*?(?:"+VAR_NAME_QUOTED+"[^~]*?)*)\\s*~\\s*";\r
        \r
        private static final String UNIT_PATTERN =\r
@@ -57,52 +77,45 @@ public class MdlUtil {
        private static final String DESC_PATTERN =\r
                        "([^\\|]*?)\\s*\\|";\r
        \r
-       public static final String variablePattern = \r
-                       VARIABLE_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+       public static final String normalVariablePattern = \r
+                       NORMAL_NAME_PATTERN   +EXPRESSION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+       public static final String subscriptVariablePattern = \r
+                       SUBSCRIPT_NAME_PATTERN+EXPRESSION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+       public static final String lookupVariablePattern = \r
+                       LOOKUP_NAME_PATTERN                      +UNIT_PATTERN+DESC_PATTERN;\r
+       public static final String noExpressionVariablePattern = \r
+                       NO_EXPRESSION_NAME_PATTERN               +UNIT_PATTERN+DESC_PATTERN;\r
        \r
-       private static final int variableName = 1;\r
-       private static final int variableEquation = 2;\r
-       private static final int variableUnit = 3;\r
-       private static final int variableDesc = 4;\r
+       private static final int normalVariableName = 1;\r
+       private static final int normalVariableExpression = 2;\r
        \r
-       public static Variable getPossibleVariable(String line, String category) {\r
-               Matcher matcher = Pattern.compile(variablePattern).matcher(line);\r
+       private static final int subscriptVariableName = 1;\r
+       private static final int subscriptVariableIndices = 2;\r
+       private static final int subscriptVariableExpression = 3;\r
+       \r
+       private static final int lookupVariableName = 1;\r
+       private static final int lookupVariableRangeXMin = 2;\r
+       private static final int lookupVariableRangeYMin = 3;\r
+       private static final int lookupVariableRangeXMax = 4;\r
+       private static final int lookupVariableRangeYMax = 5;\r
+       private static final int lookupVariablePoints = 6;\r
+       \r
+       private static final int noExpressionVariableName = 1;\r
+       \r
+       public static Variable getPossibleNormalVariable(String line) {\r
+               Matcher matcher = Pattern.compile(normalVariablePattern).matcher(line);\r
                \r
                if (!matcher.matches()) {\r
                        return null;\r
                }\r
                \r
-               String name = normalize(matcher.group(variableName));\r
-               Expression expression = parseExpression(matcher.group(variableEquation));\r
+               String name = normalize(matcher.group(normalVariableName));\r
+               Expression expression = parseExpression(matcher.group(normalVariableExpression));\r
                \r
-               String unit = matcher.group(variableUnit);\r
-               Range range = parseRange(unit);\r
-               if (range != null) {\r
-                       unit = unit.substring(0, unit.indexOf(range.originalString())).trim();\r
-               }\r
-               String description = matcher.group(variableDesc);\r
-               \r
-               return new Variable(name, expression, unit, range, description);\r
+               return getVariable(matcher, 2, name, expression);\r
        }\r
        \r
-       // a subscript variable is a variable that has a different equation\r
-       // depending on the value of the subscript it references\r
-       private static final String VAR_NAME_SUBSCRIPT =\r
-                       "("+VAR_NAME_SIMPLE+")\\[("+VAR_NAME_SIMPLE+"(?:,"+VAR_NAME_SIMPLE+")*)\\]";\r
-\r
-       private static final String SUBSCRIPT_VARIABLE_PATTERN =\r
-                       VAR_NAME_SUBSCRIPT+"\\s*=\\s*";\r
-\r
-       public static final String subscriptVariablePattern = \r
-                       SUBSCRIPT_VARIABLE_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
-       \r
-       private static final int subscriptVariableName = 1;\r
-       private static final int subscriptVariableIndices = 2;\r
-       private static final int subscriptVariableEquation = 3;\r
-       private static final int subscriptVariableUnit = 4;\r
-       private static final int subscriptVariableDesc = 5;\r
-       \r
-       public static Variable getPossibleSubscriptVariable(String line, String category, MdlModel mdl) {\r
+       public static Variable getPossibleSubscriptVariable(String line) {\r
                Matcher matcher = Pattern.compile(subscriptVariablePattern).matcher(line);\r
                \r
                if (!matcher.matches()) {\r
@@ -110,45 +123,14 @@ public class MdlUtil {
                }\r
                \r
                String name = normalize(matcher.group(subscriptVariableName));\r
-               // TODO: find out if subscript indices can contain commas and update\r
-               // this method accordingly\r
-               String[] indices = matcher.group(subscriptVariableIndices).split(",");\r
-               Expression expression = parseExpression(matcher.group(subscriptVariableEquation));\r
-               EnumerationExpression e = new EnumerationExpression(indices, expression);\r
+               String[] indices = normalize(matcher.group(subscriptVariableIndices)).split(",");\r
+               Expression expression = parseExpression(matcher.group(subscriptVariableExpression));\r
+               EnumerationExpression e = new EnumerationExpression(expression, indices);\r
                \r
-               String unit = matcher.group(subscriptVariableUnit);\r
-               Range range = parseRange(unit);\r
-               if (range != null) {\r
-                       unit = unit.substring(0, unit.indexOf(range.originalString())).trim();\r
-               }\r
-               String description = matcher.group(subscriptVariableDesc);\r
-               \r
-               return new Variable(name, e, unit, range, description);\r
+               return getVariable(matcher, 3, name, e);\r
        }\r
        \r
-       private static final String LOOKUP_NAME =\r
-                       "([A-Za-z](?: *\\w+)*)";\r
-       private static final String LOOKUP_RANGE =\r
-                       "\\[\\(("+NUMBER+"),("+NUMBER+")\\)-\\(("+NUMBER+"),("+NUMBER+")\\)\\]";\r
-       private static final String LOOKUP_POINTS =\r
-                       "(\\("+NUMBER+","+NUMBER+"\\)(?:,\\("+NUMBER+","+NUMBER+"\\))*)";\r
-       \r
-       private static final String LOOKUP_PATTERN =\r
-                       LOOKUP_NAME+"\\s*\\(\\s*"+LOOKUP_RANGE+","+LOOKUP_POINTS+"\\s*\\)\\s*~\\s*";\r
-\r
-       public static final String lookupVariablePattern = \r
-                       LOOKUP_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
-       \r
-       private static final int lookupVariableName = 1;\r
-       private static final int lookupVariableRangeXMin = 2;\r
-       private static final int lookupVariableRangeYMin = 3;\r
-       private static final int lookupVariableRangeXMax = 4;\r
-       private static final int lookupVariableRangeYMax = 5;\r
-       private static final int lookupVariablePoints = 6;\r
-       private static final int lookupVariableUnit = 7;\r
-       private static final int lookupVariableDesc = 8;\r
-       \r
-       public static Variable getPossibleLookUpVariable(String line, String category) {\r
+       public static Variable getPossibleLookUpVariable(String line) {\r
                Matcher matcher = Pattern.compile(lookupVariablePattern).matcher(line);\r
                \r
                if (!matcher.matches()) {\r
@@ -161,17 +143,9 @@ public class MdlUtil {
                double yMin = Double.parseDouble(matcher.group(lookupVariableRangeXMax));\r
                double yMax = Double.parseDouble(matcher.group(lookupVariableRangeYMax));\r
                double[] points = parseLookup(matcher.group(lookupVariablePoints));\r
+               LookupExpression expression = new LookupExpression(xMin, yMin, xMax, yMax, points);\r
                \r
-               LookupExpression e = new LookupExpression(xMin, yMin, xMax, yMax, points);\r
-               \r
-               String unit = matcher.group(lookupVariableUnit);\r
-               Range range = parseRange(unit);\r
-               if (range != null) {\r
-                       unit = unit.substring(0, unit.indexOf(range.originalString())).trim();\r
-               }\r
-               String description = matcher.group(lookupVariableDesc);\r
-               \r
-               return new Variable(name, e, unit, range, description);\r
+               return getVariable(matcher, 6, name, expression);\r
        }\r
        \r
        private static double[] parseLookup(String points) {\r
@@ -185,16 +159,6 @@ public class MdlUtil {
                return result;\r
        }\r
        \r
-       public static final String NO_EXP_PATTERN = \r
-                       VAR_NAME+"\\s*~\\s*";\r
-       \r
-       public static final String noExpressionVariablePattern = \r
-                       NO_EXP_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
-       \r
-       private static final int noExpVariableName = 1;\r
-       private static final int noExpVariableUnit = 2;\r
-       private static final int noExpVariableDesc = 3;\r
-       \r
        public static Variable getPossibleNoExpressionVariable(String line) {\r
                Matcher matcher = Pattern.compile(noExpressionVariablePattern).matcher(line);\r
                \r
@@ -202,29 +166,32 @@ public class MdlUtil {
                        return null;\r
                }\r
                \r
-               String name = normalize(matcher.group(noExpVariableName));\r
+               String name = normalize(matcher.group(noExpressionVariableName));\r
                \r
-               String unit = matcher.group(noExpVariableUnit);\r
+               return getVariable(matcher, 1, name, null);\r
+       }\r
+       \r
+       public static Variable getVariable(Matcher matcher, int groups, String name, Expression expression) {\r
+               String unit = matcher.group(groups + 1);\r
                Range range = parseRange(unit);\r
                if (range != null) {\r
                        unit = unit.substring(0, unit.indexOf(range.originalString())).trim();\r
                }\r
-               String description = matcher.group(noExpVariableDesc);\r
-               \r
-               return new Variable(name, null, unit, range, description);\r
+               String description = matcher.group(groups + 2);\r
+               return new Variable(name, expression, unit, range, description);\r
        }\r
 \r
        private static final String SUBSCRIPT_PATTERN =\r
                        "("+VAR_NAME_SIMPLE+")\\s*(:|<->)\\s*";\r
        \r
        public static final String subscriptPattern = \r
-                       SUBSCRIPT_PATTERN+EQUATION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
+                       SUBSCRIPT_PATTERN+EXPRESSION_PATTERN+UNIT_PATTERN+DESC_PATTERN;\r
        \r
        private static final int subscriptName = 1;\r
        private static final int subscriptType = 2;\r
-       private static final int subscriptEquation = 3;\r
+       private static final int subscriptExpression = 3;\r
        \r
-       public static Subscript getPossibleSubscript(String line, MdlModel mdl) {\r
+       public static Enumeration getPossibleSubscript(String line, MdlModel mdl) {\r
                Matcher matcher = Pattern.compile(subscriptPattern).matcher(line);\r
                \r
                if (!matcher.matches()) {\r
@@ -233,13 +200,13 @@ public class MdlUtil {
                \r
                String name = normalize(matcher.group(subscriptName));\r
                boolean equivalence = matcher.group(subscriptType).equals("<->");\r
-               String expression = matcher.group(subscriptEquation);\r
+               String expression = normalize(matcher.group(subscriptExpression));\r
                \r
                if (equivalence) {\r
-                       return new Subscript(name, mdl.getSubscript(normalize(expression)));\r
+                       return new Enumeration(name, mdl.getSubscript(expression));\r
                }\r
                else {\r
-                       return new Subscript(name, expression.split(","));\r
+                       return new Enumeration(name, expression.split(","));\r
                }\r
        }\r
        \r
@@ -278,7 +245,7 @@ public class MdlUtil {
                                System.err.println("malformed game expression: "+equation);\r
                                return null;\r
                        }\r
-                       // game expressions are currently not supported\r
+                       // game expressions are currently treated as normal expressions\r
                        return new NormalExpression(normalize(parameters[0]));\r
                }\r
                else {\r
@@ -405,7 +372,7 @@ public class MdlUtil {
        \r
        public static final String sketchVariable =\r
                //   n,   id,  name,        x,y,w,h,sh,bits,hid,hasf,tpos,bw,nav1,nav2(,box,fill,font)\r
-                       "10,"+SAVE+VAR_NAME+","+COMMON;\r
+                       "10,"+SAVE+VAR_NAME_NORMAL+","+COMMON;\r
        public static final String sketchValve =\r
                        "11,"+SAVE+SAVE+        COMMON;\r
        public static final String sketchComment =\r
@@ -430,7 +397,7 @@ public class MdlUtil {
                }\r
                \r
                int id = Integer.parseInt(matcher.group(elementId));\r
-               Variable var = mdl.getVariable((normalize(matcher.group(elementName))));\r
+               Variable var = mdl.getVariable(normalize(matcher.group(elementName)));\r
                if (var == null) {\r
                        System.err.println("could not find variable corresponding to "+normalize(matcher.group(elementName)));\r
                }\r
@@ -618,13 +585,17 @@ public class MdlUtil {
                \r
                int offset = 0;\r
 \r
-               Matcher matcher = Pattern.compile(VAR_NAME).matcher(str);\r
+               Matcher matcher = Pattern.compile(VAR_NAME_NORMAL).matcher(str);\r
                while (matcher.find()) {\r
                        result.append(str.substring(offset, matcher.start()));\r
 \r
                        String replacement = matcher.group();\r
                        \r
-                       if (replacement.startsWith("\"")) {\r
+                       // TODO: comment this\r
+                       if (replacement.equalsIgnoreCase("time")) {\r
+                               replacement = "time";\r
+                       }\r
+                       else if (replacement.startsWith("\"")) {\r
                                // if the variable name is quoted, change the quotes to modelica syntax\r
                                replacement = "'" + replacement.substring(1, replacement.length() - 1) + "'";\r
                        }\r
index 89e68cbfa75e4e6ffd338a760d6833bf50408bc7..7bf61c52d464314f1b66069121724b9cc36abbae 100644 (file)
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 import java.util.HashMap;\r
 import java.util.List;\r
 \r
+import org.simantics.sysdyn.modelImport.model.support.Enumeration;\r
 import org.simantics.sysdyn.modelImport.model.support.Variable;\r
 \r
 public class MdlModel {\r
@@ -12,7 +13,7 @@ public class MdlModel {
        \r
        private HashMap<String, Variable> variables;\r
        private HashMap<String, ArrayList<Variable>> groups;\r
-       private HashMap<String, Subscript> subscripts;\r
+       private HashMap<String, Enumeration> subscripts;\r
        private ArrayList<Sketch> sketches;\r
        \r
        public MdlModel(String name) {\r
@@ -20,7 +21,7 @@ public class MdlModel {
                \r
                this.variables = new HashMap<String, Variable>();\r
                this.groups = new HashMap<String, ArrayList<Variable>>();\r
-               this.subscripts = new HashMap<String, Subscript>();\r
+               this.subscripts = new HashMap<String, Enumeration>();\r
                this.sketches = new ArrayList<Sketch>();\r
        }\r
        \r
@@ -31,6 +32,8 @@ public class MdlModel {
        public void addVariable(Variable variable, String group) {\r
                if (variables.get(variable.getName()) != null) {\r
                        System.err.println("warning, duplicate variable "+variable.getName());\r
+                       variables.get(variable.getName()).mergeWithVariable(variable);\r
+                       return;\r
                }\r
                \r
                variables.put(variable.getName(), variable);\r
@@ -51,16 +54,16 @@ public class MdlModel {
                return new ArrayList<Variable>(variables.values());\r
        }\r
        \r
-       public void addSubscript(Subscript subscript) {\r
+       public void addSubscript(Enumeration subscript) {\r
                subscripts.put(subscript.getName(), subscript);\r
        }\r
        \r
-       public Subscript getSubscript(String name) {\r
+       public Enumeration getSubscript(String name) {\r
                return subscripts.get(name);\r
        }\r
        \r
-       public List<Subscript> getSubscripts() {\r
-               return new ArrayList<Subscript>(subscripts.values());\r
+       public List<Enumeration> getSubscripts() {\r
+               return new ArrayList<Enumeration>(subscripts.values());\r
        }\r
        \r
        public void addSketch(Sketch sketch) {\r
index 619b1f0077ccb0d6b95ff250c0fb893eb5739702..28405d647d2a48393205f11a1d83ef31030dd5af 100644 (file)
@@ -2,6 +2,7 @@ package org.simantics.sysdyn.modelImport.mdl;
 \r
 import java.util.ArrayList;\r
 import java.util.HashMap;\r
+import java.util.Iterator;\r
 import java.util.List;\r
 \r
 import org.simantics.sysdyn.modelImport.model.element.Symbol;\r
@@ -21,6 +22,8 @@ public class Sketch {
        private ArrayList<SketchValve> valves;\r
        private ArrayList<SketchVariable> variables;\r
        \r
+       private HashMap<Integer, SketchObject> objects;\r
+       \r
        public Sketch() {\r
                edgesOutOfDate = true;\r
                \r
@@ -28,6 +31,8 @@ public class Sketch {
                connections = new ArrayList<SketchConnection>();\r
                valves = new ArrayList<SketchValve>();\r
                variables = new ArrayList<SketchVariable>();\r
+               \r
+               objects = new HashMap<Integer, SketchObject>();\r
        }\r
        \r
        public String getName() {\r
@@ -82,12 +87,22 @@ public class Sketch {
                return bottomEdge - topEdge;\r
        }\r
        \r
-       public void addObject(SketchComment comment) {\r
-               \r
+       public void setOffset(double horizontal, double vertical) {\r
+               hOffset = horizontal;\r
+               vOffset = vertical;\r
+       }\r
+       \r
+       public double getHorizontalOffset() {\r
+               return hOffset;\r
+       }\r
+       \r
+       public double getVerticalOffset() {\r
+               return vOffset;\r
        }\r
        \r
        public void addComment(SketchComment comment) {\r
                comments.add(comment);\r
+               objects.put(comment.getId(), comment);\r
        }\r
        \r
        public List<SketchComment> getComments() {\r
@@ -96,6 +111,7 @@ public class Sketch {
        \r
        public void addConnection(SketchConnection connection) {\r
                connections.add(connection);\r
+               objects.put(connection.getId(), connection);\r
        }\r
        \r
        public List<SketchConnection> getConnections() {\r
@@ -104,6 +120,10 @@ public class Sketch {
        \r
        public void addValve(SketchValve valve) {\r
                valves.add(valve);\r
+               objects.put(valve.getId(), valve);\r
+               // replace the attached variable with the valve in order to redirect \r
+               // possible connections to the variable to the valve\r
+               objects.put(valve.getAttachedVariable().getId(), valve);\r
        }\r
        \r
        public List<SketchValve> getValves() {\r
@@ -112,12 +132,27 @@ public class Sketch {
        \r
        public void addVariable(SketchVariable variable) {\r
                variables.add(variable);\r
+               objects.put(variable.getId(), variable);\r
        }\r
        \r
        public List<SketchVariable> getVariables() {\r
                return variables;\r
        }\r
        \r
+       public SketchObject getObject(int id) {\r
+               return objects.get(id);\r
+       }\r
+       \r
+       public List<SketchVariable> getShadowVariables() {\r
+               List<SketchVariable> variables = new ArrayList<SketchVariable>();\r
+               for (SketchVariable var : getVariables()) {\r
+                       if (!var.allowsIn()) {\r
+                               variables.add(var);\r
+                       }\r
+               }\r
+               return variables;\r
+       }\r
+       \r
        public List<SketchElement> getAllElements() {\r
                ArrayList<SketchElement> list = new ArrayList<SketchElement>();\r
                list.addAll(getComments());\r
@@ -126,6 +161,13 @@ public class Sketch {
                return list;\r
        }\r
        \r
+       public List<SketchElement> getIndependentElements() {\r
+               List<SketchElement> elements = new ArrayList<SketchElement>();\r
+               elements.addAll(getAllElements());\r
+               elements.removeAll(getShadowVariables());\r
+               return elements;\r
+       }\r
+       \r
        // relevant for sysdyn model creation, this is not the cleanest place to\r
        // store this information but it works\r
        \r
index 53ef8f7e530bb8f88e4c1147798e39025326d2f2..9aaac03c82092fdb7a9d9d65ab01dd83f512debe 100644 (file)
@@ -27,21 +27,18 @@ public class SketchComment extends SketchElement {
                return icon;\r
        }\r
        \r
-       public Symbol getModelElement(double hOffset, double vOffset) {\r
-               if (icon.equals(CommentIcon.CLOUD)) {\r
-                       return new Cloud(\r
-                                       getSysdyndX() + hOffset, \r
-                                       getSysdyndY() + vOffset, \r
-                                       getSysdynWidth(),\r
-                                       getSysdynHeight());\r
+       @Override\r
+       public Symbol getSymbol(Sketch sketch) {\r
+               double[] dimensions = getDimensions(sketch);\r
+               \r
+               if (isInputOutput()) {\r
+                       return new Comment(dimensions, "input / output objects are not supported yet");\r
                }\r
-               else {\r
-                       return new Comment(\r
-                                       getSysdyndX() + hOffset, \r
-                                       getSysdyndY() + vOffset, \r
-                                       getSysdynWidth(),\r
-                                       getSysdynHeight(),\r
-                                       text);\r
+               \r
+               switch (icon) {\r
+               case CLOUD: return new Cloud(dimensions);\r
+               case OTHER: return new Comment(dimensions, text);\r
+               default: return null;\r
                }\r
        }\r
        \r
index 58f23af43778c58d68b5e154c6161763954e26dd..bfd3406651739b6b8c673c62578631ce47db6735 100644 (file)
@@ -32,36 +32,48 @@ public class SketchConnection extends SketchObject {
        public ConnectionType getType() {\r
                return type;\r
        }\r
+       \r
+       public int[] getPoints() {\r
+               return points;\r
+       }\r
 \r
-       public Connection getWriteableConnection(Symbol head, Symbol tail, double offset) {\r
-               if (type.equals(ConnectionType.ARROW)) {\r
-                       return new Dependency(head, tail, false, false, getSysdynAngle(tail, head, offset));\r
+       public Connection getConnection(Sketch sketch) {\r
+               Symbol tail = (Symbol)sketch.getObject(from).getModelObject();\r
+               if (tail == null) {\r
+                       System.err.println("connection tail not created");\r
+                       return null;\r
                }\r
-               else if (type.equals(ConnectionType.LINE_ARROW)) {\r
-                       return new Flow(head, tail);\r
+               Symbol head = (Symbol)sketch.getObject(to).getModelObject();\r
+               if (head == null) {\r
+                       System.err.println("connection head not created");\r
+                       return null;\r
                }\r
-               else if (type.equals(ConnectionType.LINE_SEGMENT)) {\r
-                       // TODO: what is this I don't even...\r
-                       return new Flow(tail, head);\r
+               \r
+               switch (type) {\r
+               case ARROW:        return new Dependency(tail, head, true, false, getAngle(sketch));\r
+               case LINE_ARROW:   return new Flow(tail, head);\r
+               case LINE_SEGMENT: return new Flow(head, tail);\r
+               default: return null;\r
                }\r
-               return null;\r
        }\r
 \r
-       // TODO: comment this?\r
-       public double getSysdynAngle(Symbol from, Symbol to, double voffset) {\r
-               if (points == null || points.length == 0) {\r
+       public double getAngle(Sketch sketch) {\r
+               if (points == null || points.length < 2) {\r
                        return 0;\r
                }\r
                \r
+               SketchElement tail = (SketchElement)sketch.getObject(from);\r
+               SketchElement head = (SketchElement)sketch.getObject(to);\r
+               \r
                // 'from' element is in (x0, y0) and 'to' element is in (x2, y2)\r
-               double x0 = from.getX() + (from.getWidth() / 2);\r
-               double y0 = from.getY() + (from.getHeight() / 2);\r
-               double x2 = to.getX() + (to.getWidth() / 2);\r
-               double y2 = to.getY() + (to.getHeight() / 2);\r
+               double x0 = tail.getX();\r
+               double y0 = tail.getY();\r
+               double x2 = head.getX();\r
+               double y2 = head.getY();\r
                \r
                // treat the first points in points as the control point (x1, y1)\r
-               double x1 = (double)points[0] * SCALE_MULTIPLIER;\r
-               double y1 = (double)points[1] * SCALE_MULTIPLIER + voffset;\r
+               double x1 = (double)points[0];\r
+               double y1 = (double)points[1];\r
                \r
                //System.err.println("("+x0+","+y0+") -> ("+x1+","+y1+") -> ("+x2+","+y2+")");\r
 \r
@@ -82,8 +94,8 @@ public class SketchConnection extends SketchObject {
                else {\r
                        // (p1-p0) * (p1-p2) / dd\r
                        double offset = (dx0*dx1 + dy0*dy1) / dd;\r
-                       double angle = Math.PI*0.5 - Math.atan(offset);\r
-                       if (dd > 0.0)\r
+                       double angle = Math.PI/2 - Math.atan(offset);\r
+                       if (dd > 0)\r
                                angle = angle - Math.PI;\r
                        return angle;\r
                }\r
index 2af38c2a6675ca32c9ea230210b1ae360ae2cc44..3ab316ffd01353397cabc89662e56e8ad6172d2d 100644 (file)
@@ -105,6 +105,25 @@ public abstract class SketchElement extends SketchObject {
                return textLine;\r
        }\r
 \r
-       public abstract Symbol getModelElement(double hOffset, double vOffset);\r
+       public abstract Symbol getSymbol(Sketch sketch);\r
+       \r
+       private static final double SCALE_MULTIPLIER = 0.4;\r
+       \r
+       public double[] getDimensions(Sketch sketch) {\r
+               double[] dimensions = getDimensions();\r
+               dimensions[0] = dimensions[0] + sketch.getHorizontalOffset();\r
+               dimensions[1] = dimensions[1] + sketch.getVerticalOffset();\r
+               return dimensions;\r
+       }\r
+       \r
+       // get element dimensions, [x, y, width, height]\r
+       public double[] getDimensions() {\r
+               double[] dimensions = new double[4];\r
+               dimensions[0] = (getX() - getWidth()) * SCALE_MULTIPLIER;\r
+               dimensions[1] = (getY() - getHeight()) * SCALE_MULTIPLIER;\r
+               dimensions[2] = getWidth() * 2 * SCALE_MULTIPLIER;\r
+               dimensions[3] = getHeight() * 2 * SCALE_MULTIPLIER;\r
+               return dimensions;\r
+       }\r
        \r
 }\r
index d554ec5947c64ec76324a074fcb239e8cc241b0c..62eba88089b30a583ec31683831505f4da941409 100644 (file)
@@ -1,10 +1,11 @@
 package org.simantics.sysdyn.modelImport.mdl;\r
 \r
+import org.simantics.sysdyn.modelImport.model.IWriteableObject;\r
+\r
 public abstract class SketchObject {\r
-       \r
-       protected static final double SCALE_MULTIPLIER = 0.4;\r
 \r
        private int id;\r
+       private IWriteableObject modelObject;\r
        \r
        public SketchObject(int id) {\r
                this.id = id;\r
@@ -14,4 +15,12 @@ public abstract class SketchObject {
                return id;\r
        }\r
        \r
+       public void setModelObject(IWriteableObject modelObject) {\r
+               this.modelObject = modelObject;\r
+       }\r
+       \r
+       public IWriteableObject getModelObject() {\r
+               return modelObject;\r
+       }\r
+       \r
 }\r
index 7685c0568ea9f718d3c33183f0fcf2d55502df81..c393d1ba237ecedd59ce92c7cc7f864424675f0c 100644 (file)
@@ -1,5 +1,6 @@
 package org.simantics.sysdyn.modelImport.mdl;\r
 \r
+import org.simantics.sysdyn.modelImport.model.IWriteableObject;\r
 import org.simantics.sysdyn.modelImport.model.element.Symbol;\r
 import org.simantics.sysdyn.modelImport.model.element.Valve;\r
 import org.simantics.sysdyn.modelImport.model.element.Valve.TextPosition;\r
@@ -22,15 +23,20 @@ public class SketchValve extends SketchElement {
                this.variable = variable;\r
        }\r
        \r
+       public TextPosition getTextPosition() {\r
+               return textPosition;\r
+       }\r
+       \r
+       @Override\r
+       public Symbol getSymbol(Sketch sketch) {\r
+               return new Valve(getDimensions(sketch), variable.getVariable(), textPosition);\r
+       }\r
+       \r
+       // TODO: do we really want to do this?\r
        @Override\r
-       public Symbol getModelElement(double hOffset, double vOffset) {\r
-               return new Valve(\r
-                               getSysdyndX() + hOffset, \r
-                               getSysdyndY() + vOffset, \r
-                               getSysdynWidth(),\r
-                               getSysdynHeight(), \r
-                               variable.getVariable(),\r
-                               textPosition);\r
+       public void setModelObject(IWriteableObject modelObject) {\r
+               super.setModelObject(modelObject);\r
+               variable.setModelObject(modelObject);\r
        }\r
 \r
 }\r
index 2770b5e1deb26de864b155ed653d43cdc62472f4..9cef818499c8c06971c7bcf134b2060bc2f9f027 100644 (file)
@@ -20,23 +20,13 @@ public class SketchVariable extends SketchElement {
        }\r
        \r
        @Override\r
-       public Symbol getModelElement(double hOffset, double vOffset) {\r
+       public Symbol getSymbol(Sketch sketch) {\r
                if (variable.getExpression() instanceof IntegralExpression) {\r
-                       return new Stock(\r
-                                       getSysdyndX() + hOffset, \r
-                                       getSysdyndY() + vOffset, \r
-                                       getSysdynWidth(),\r
-                                       getSysdynHeight(),\r
-                                       variable);\r
+                       return new Stock(getDimensions(sketch), variable);\r
                }\r
                else {\r
-                       return new Auxiliary(\r
-                                       getSysdyndX() + hOffset, \r
-                                       getSysdyndY() + vOffset,  \r
-                                       getSysdynWidth(),\r
-                                       getSysdynHeight(),\r
-                                       variable);\r
+                       return new Auxiliary(getDimensions(sketch), variable);\r
                }\r
        }\r
        \r
-}\r
+}
\ No newline at end of file
diff --git a/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/Subscript.java b/org.simantics.sysdyn/src/org/simantics/sysdyn/modelImport/mdl/Subscript.java
deleted file mode 100644 (file)
index eb6e885..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-package org.simantics.sysdyn.modelImport.mdl;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Arrays;\r
-\r
-public class Subscript {\r
-       \r
-       // TODO: THIS IS PROBABLY NOT NEEDED AT ALL, COULD USE ENUMERATION DIRECTLY\r
-       \r
-       private String name;\r
-       private ArrayList<String> values;\r
-       \r
-       public Subscript(String name, String...values) {\r
-               this.name = name;\r
-               this.values = new ArrayList<String>(Arrays.asList(values));\r
-       }\r
-       \r
-       public Subscript(String name, Subscript other) {\r
-               this.name = name;\r
-               this.values = other.getValues();\r
-       }\r
-       \r
-       public String getName() {\r
-               return name;\r
-       }\r
-       \r
-       public ArrayList<String> getValues() {\r
-               return values;\r
-       }\r
-\r
-}\r
index 2cc8e282fadc17b06242edf9e6e89604f421e727..a0727b8810502ffe7e262411c35ad39f0ccb2761 100644 (file)
@@ -38,10 +38,10 @@ public class Model implements IWriteableObject {
        private double start, stop, step;\r
        \r
        // the structure of the model\r
-       private HashMap<String, Enumeration> enumerations;\r
        private HashMap<String, ModelVariable> variables;\r
+       private HashMap<String, Enumeration> enumerations;\r
        \r
-       private ArrayList<Symbol> elements;\r
+       private ArrayList<Symbol> symbols;\r
        private ArrayList<Shadow> shadows;\r
        private ArrayList<Connection> connections;\r
        \r
@@ -50,10 +50,10 @@ public class Model implements IWriteableObject {
        public Model(String name) {\r
                this.name = name;\r
                \r
-               enumerations = new HashMap<String, Enumeration>();\r
                variables = new HashMap<String, ModelVariable>();\r
+               enumerations = new HashMap<String, Enumeration>();\r
                \r
-               elements = new ArrayList<Symbol>();\r
+               symbols = new ArrayList<Symbol>();\r
                shadows = new ArrayList<Shadow>();\r
                connections = new ArrayList<Connection>();\r
        }\r
@@ -82,13 +82,6 @@ public class Model implements IWriteableObject {
                this.step = step;\r
        }\r
        \r
-       public void addEnumeration(Enumeration enumeration) {\r
-               if (enumerations.get(enumeration.getName()) != null) {\r
-                       System.err.println("enumeration "+enumeration.getName()+" already defined");\r
-               }\r
-               enumerations.put(enumeration.getName(), enumeration);\r
-       }\r
-       \r
        public Enumeration getEnumeration(String name) {\r
                return enumerations.get(name);\r
        }\r
@@ -97,15 +90,6 @@ public class Model implements IWriteableObject {
                return enumerations.values();\r
        }\r
        \r
-       public void addVariable(ModelVariable variable) {\r
-               if (enumerations.get(variable.getName()) != null) {\r
-                       System.err.println("variable "+variable.getName()+" already defined");\r
-               }\r
-               variables.put(variable.getName(), variable);\r
-               \r
-               addElement(variable);\r
-       }\r
-       \r
        public ModelVariable getVariable(String name) {\r
                return variables.get(name);\r
        }\r
@@ -113,18 +97,37 @@ public class Model implements IWriteableObject {
        public Collection<ModelVariable> getVariables() {\r
                return variables.values();\r
        }\r
+       \r
+       public void addSymbol(ModelVariable variable) {\r
+               if (variables.get(variable.getName()) != null) {\r
+                       System.err.println("variable "+variable.getName()+" already defined");\r
+               }\r
+               variables.put(variable.getName(), variable);\r
+               \r
+               System.err.println("variable added "+variable.getName());\r
                \r
-       public void addElement(Symbol element) {\r
-               elements.add(element);\r
+               symbols.add(variable);\r
        }\r
        \r
-       public void addShadow(Shadow shadow) {\r
+       public void addSymbol(Shadow shadow) {\r
                shadows.add(shadow);\r
        }\r
+               \r
+       public void addSymbol(Symbol element) {\r
+               symbols.add(element);\r
+       }\r
        \r
        public void addConnection(Connection connection) {\r
+               // TODO: make sure connection head and tail exist\r
                connections.add(connection);\r
        }\r
+       \r
+       public void addEnumeration(Enumeration enumeration) {\r
+               if (enumerations.get(enumeration.getName()) != null) {\r
+                       System.err.println("enumeration "+enumeration.getName()+" already defined");\r
+               }\r
+               enumerations.put(enumeration.getName(), enumeration);\r
+       }\r
 \r
        @Override\r
        public Resource write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException {\r
@@ -144,7 +147,7 @@ public class Model implements IWriteableObject {
                        e.write(graph, configuration, context);\r
                }\r
                \r
-               for (Symbol e : elements) {\r
+               for (Symbol e : symbols) {\r
                        e.write(graph, configuration, context);\r
                }\r
                \r
index 39e978e441c8e72eded3df7635a58e2d1f513952..1cc4f3d27c1c5ba384547f2319fc252f2adfd974 100644 (file)
@@ -1,7 +1,12 @@
 package org.simantics.sysdyn.modelImport.model;\r
 \r
+import java.util.Arrays;\r
+import java.util.Collections;\r
 import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
 \r
+import org.simantics.db.Resource;\r
 import org.simantics.sysdyn.modelImport.model.support.Enumeration;\r
 \r
 public class WriteContext {\r
@@ -14,6 +19,7 @@ public class WriteContext {
        private long flowCount;\r
        \r
        private HashMap<String, Enumeration> enumerations;\r
+       private HashMap<String, Set<Enumeration>> enumerationValues;\r
        \r
        public WriteContext() {\r
                objectCount = 0;\r
@@ -24,6 +30,7 @@ public class WriteContext {
                flowCount = 0;\r
                \r
                enumerations = new HashMap<String, Enumeration>();\r
+               enumerationValues = new HashMap<String, Set<Enumeration>>();\r
        }\r
        \r
        public String getNextObject() {\r
@@ -50,18 +57,49 @@ public class WriteContext {
                return "Flow" + flowCount++;\r
        }\r
        \r
-       // register an enumeration, necessary for enumeration expressions\r
-       public void registerEnumeration(Enumeration enumeration) {\r
-               \r
+       public void registerEnumeration(Enumeration enumeration, boolean copy) {\r
+               enumerations.put(enumeration.getName(), enumeration);\r
+               if (enumerationValues.get(enumeration.getName()) == null) {\r
+                       enumerationValues.put(enumeration.getName(), new HashSet<Enumeration>());\r
+               }\r
+               enumerationValues.get(enumeration.getName()).add(enumeration);\r
+               if (!copy) {\r
+                       for (String value : enumeration.getValues()) {\r
+                               if (enumerationValues.get(value) == null) {\r
+                                       enumerationValues.put(value, new HashSet<Enumeration>());\r
+                               }\r
+                               enumerationValues.get(value).add(enumeration);\r
+                       }\r
+               }\r
        }\r
-       \r
-       // attempt to obtain a reference to an enumeration based on either the \r
-       // name of the enumeration or the name of one of the elements of the \r
-       // enumeration\r
-       // (TODO: this must be updated to something more clever if there are\r
-       // collisions between names of enumerations and elements of enumerations)\r
-       public Enumeration resolveEnumeration(String lookup) {\r
-               return null;\r
+               \r
+       public Enumeration getEnumeration(Set<String> indices) {\r
+               System.err.println("size is "+indices.size());\r
+               if (indices.size() == 1) {\r
+                       Enumeration enumeration = enumerations.get(indices.iterator().next());\r
+                       if (enumeration != null) {\r
+                               return enumeration;\r
+                       }\r
+               }\r
+               \r
+               // the set of potential matches is the intersection of all sets of\r
+               // enumerations that contain any of the given indices as elements\r
+               Set<Enumeration> potential = new HashSet<Enumeration>(enumerations.values());\r
+               for (String index : indices) {\r
+                       potential.retainAll(enumerationValues.get(index));\r
+               }\r
+               \r
+               // if there is more than one potential match, the enumerations are not\r
+               // well defined (there are multiple enumerations with similar indices)\r
+               if (potential.size() == 1) {\r
+                       return potential.iterator().next();\r
+               }\r
+               else {\r
+                       System.err.println("enumeration could not be resolved "+potential.size());\r
+                       for (String index : indices)\r
+                               System.err.println("  "+index);\r
+                       return null;\r
+               }\r
        }\r
 \r
 }\r
index add03008160b8bb7ec5d3232672355b28f5f328a..11ddf9d3442c42dc4adf474f706060d51626bd8c 100644 (file)
@@ -14,6 +14,10 @@ public class Auxiliary extends ModelVariable {
                super(x, y, w, h, name, expression, range, unit, description);\r
        }\r
        \r
+       public Auxiliary(double[] dimensions, Variable variable) {\r
+               super(dimensions, variable);\r
+       }\r
+       \r
        public Auxiliary(double x, double y, double w, double h, Variable variable) {\r
                super(x, y, w, h, variable);\r
        }\r
index bb1f2723ca738350d0fe4ff48049025a229fac31..10050518ce8a88d58c89341bf9d35c1286e61ef5 100644 (file)
@@ -17,6 +17,10 @@ public class Cloud extends Symbol {
        public Cloud(double x, double y, double w, double h) {\r
                super(x, y, w, h);\r
        }\r
+       \r
+       public Cloud(double[] dimensions) {\r
+               super(dimensions);\r
+       }\r
 \r
        @Override\r
        public Resource write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException {\r
index fb737ba763da04fbbf91f797a56e0416b1d8adad..2c72455398d362fc6028506662aa4e3ad4c004db 100644 (file)
@@ -17,6 +17,11 @@ public class Comment extends Symbol {
                super(x, y, w, h);\r
                this.text = text;\r
        }\r
+       \r
+       public Comment(double[] dimensions, String text) {\r
+               super(dimensions);\r
+               this.text = text;\r
+       }\r
 \r
        @Override\r
        public Resource write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException {\r
index d920ea7501cf3a02cbb58f260879b376ca7e34f1..967bd04bbc6b9d146a23d491b398bc95d7c01c4c 100644 (file)
@@ -22,9 +22,9 @@ public abstract class Connection implements IWriteableObject {
        private Resource connection;\r
        private Resource diagramConnection;\r
 \r
-       public Connection(Symbol head, Symbol tail) {\r
-               this.head = head;\r
+       public Connection(Symbol tail, Symbol head) {\r
                this.tail = tail;\r
+               this.head = head;\r
        }\r
        \r
        @Override\r
index 72e34cb61bc4c0609aac261c97eb78d724f98a88..8da35e27c3a68bd3b37e7363c6fd50b21d510548 100644 (file)
@@ -15,8 +15,8 @@ public class Dependency extends Connection {
        private boolean showDelay;\r
        private double angle;\r
        \r
-       public Dependency(Symbol head, Symbol tail, boolean showArrow, boolean showDelay, double angle) {\r
-               super(head, tail);\r
+       public Dependency(Symbol tail, Symbol head, boolean showArrow, boolean showDelay, double angle) {\r
+               super(tail, head);\r
                this.showArrow = showArrow;\r
                this.showDelay = showDelay;\r
                this.angle = angle;\r
index da51170f2f269ba35ffccdd7359ce46ad6667904..747819da3d35403f1b7af5607e5fa9cbbd75a876 100644 (file)
@@ -11,8 +11,8 @@ import org.simantics.sysdyn.modelImport.model.WriteContext;
 \r
 public class Flow extends Connection {\r
        \r
-       public Flow(Symbol head, Symbol tail) {\r
-               super(head, tail);\r
+       public Flow(Symbol tail, Symbol head) {\r
+               super(tail, head);\r
        }\r
 \r
        @Override\r
index cd2f452f28434d45f6da8ba87cbcc073636c5142..c297535f851167d883538efbb761166c81ef0936 100644 (file)
@@ -34,6 +34,15 @@ public abstract class ModelVariable extends Symbol {
                this.description = description;\r
        }\r
        \r
+       public ModelVariable(double[] dimensions, Variable variable) {\r
+               super(dimensions);\r
+               this.name = variable.getName();\r
+               this.expression = variable.getExpression();\r
+               this.range = variable.getRange();\r
+               this.unit = variable.getUnit();\r
+               this.description = variable.getDescription();\r
+       }\r
+       \r
        public ModelVariable(double x, double y, double w, double h, Variable variable) {\r
                super(x, y, w, h);\r
                this.name = variable.getName();\r
@@ -61,7 +70,7 @@ public abstract class ModelVariable extends Symbol {
                // TODO: write references to enumerations here?\r
                \r
                if (expression != null) {\r
-                       Resource expressionList = expression.write(graph, variable, context);\r
+                       expression.write(graph, variable, context);\r
                }\r
                if (range != null) {\r
                        range.write(graph, variable, context);\r
index 8f3e33eb0f2bc92090caa098e4f14873cb007fed..0ad1822e3d80f7427494d02fe76588ae36a0ae69 100644 (file)
@@ -22,6 +22,11 @@ public class Shadow extends Symbol {
                this.original = original;\r
        }\r
        \r
+       public Shadow(double[] dimensions, ModelVariable original) {\r
+               super(dimensions);\r
+               this.original = original;\r
+       }\r
+       \r
        public Shadow(SketchVariable variable, double hOffset, double vOffset, ModelVariable original) {\r
                super(variable, hOffset, vOffset);\r
                this.original = original;\r
index 03351daa8512a3c6e0061603aaca537e91cb3859..0272567fe5d65497a06619196539527cc74dc1ed 100644 (file)
@@ -18,6 +18,10 @@ public class Stock extends ModelVariable {
                super(x, y, w, h, variable);\r
        }\r
        \r
+       public Stock(double[] dimensions, Variable variable) {\r
+               super(dimensions, variable);\r
+       }\r
+       \r
        @Override\r
        public Resource getVariableType(ReadGraph graph) {\r
                return SysdynResource.getInstance(graph).Stock;\r
index 58e9917470589cfbde1e8a8f0f6f38e90557b7eb..70fc07092ef490929f85f9a5e85d3878bcc23256 100644 (file)
@@ -31,6 +31,13 @@ public abstract class Symbol implements IWriteableObject {
                this.height = height;\r
        }\r
        \r
+       public Symbol(double[] dimensions) {\r
+               this.x = dimensions[0];\r
+               this.y = dimensions[1];\r
+               this.width = dimensions[2];\r
+               this.height = dimensions[3];\r
+       }\r
+       \r
        public Symbol(SketchElement element, double hOffset, double vOffset) {\r
                this.x = element.getSysdyndX() + hOffset;\r
                this.y = element.getSysdyndY() + vOffset;\r
index 521fc1e39d5d2eab540d01b3c2cc0250f40121f9..72cd912422f02a61efe3731b43efdbc54e12e0f3 100644 (file)
@@ -28,6 +28,11 @@ public class Valve extends ModelVariable {
                this.position = position;\r
        }\r
        \r
+       public Valve(double[] dimensions, Variable variable, TextPosition position) {\r
+               super(dimensions, variable);\r
+               this.position = position;\r
+       }\r
+       \r
        public Valve(double x, double y, double w, double h, Variable variable, TextPosition position) {\r
                super(x, y, w, h, variable);\r
                this.position = position;\r
index bdb43e10807058110b6c44785327b247d78566f2..a39be3c39e666b4eef8d1acdf93464dc11c90e44 100644 (file)
@@ -1,8 +1,9 @@
 package org.simantics.sysdyn.modelImport.model.expression;\r
 \r
 import java.util.ArrayList;\r
-import java.util.Arrays;\r
+import java.util.HashSet;\r
 import java.util.List;\r
+import java.util.Set;\r
 \r
 import org.simantics.databoard.Bindings;\r
 import org.simantics.db.ReadGraph;\r
@@ -10,88 +11,87 @@ import org.simantics.db.Resource;
 import org.simantics.db.WriteGraph;\r
 import org.simantics.db.common.utils.ListUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.layer0.utils.direct.GraphUtils;\r
 import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.modelImport.model.WriteContext;\r
 \r
 public class EnumerationExpression extends Expression {\r
        \r
-       private SubscriptSubExpression active;\r
-       private ArrayList<SubscriptSubExpression> subExpressions;\r
+       private List<SubscriptSubExpression> subExpressions;\r
        \r
-       public EnumerationExpression(String[] indices, Expression expression) {\r
-               active = new SubscriptSubExpression(indices, expression);\r
+       public EnumerationExpression(Expression expression, String...indices) {\r
                subExpressions = new ArrayList<SubscriptSubExpression>();\r
-               subExpressions.add(active);\r
+               addExpression(expression, indices);\r
        }\r
        \r
-       public void addExpression(String[] indices, Expression expression) {\r
-               subExpressions.add(new SubscriptSubExpression(indices, expression));\r
-       }\r
-       \r
-       public List<SubscriptSubExpression> getExpressions() {\r
-               return subExpressions;\r
+       public void addExpression(Expression expression, String...indices) {\r
+               subExpressions.add(new SubscriptSubExpression(expression, indices));\r
        }\r
        \r
        public void addExpressions(List<SubscriptSubExpression> expressions) {\r
                subExpressions.addAll(expressions);\r
        }\r
        \r
+       public List<SubscriptSubExpression> getExpressions() {\r
+               return subExpressions;\r
+       }\r
+       \r
        @Override\r
        public Resource write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException {\r
                SysdynResource sr = SysdynResource.getInstance(graph);\r
                \r
-               for (SubscriptSubExpression subexpr : subExpressions) {\r
-                       subexpr.write(graph, parent, context);\r
-               }\r
-               \r
-               // write array index list\r
-               //graph.claim(parent, sr.Variable_arrayIndexesList, ListUtils.create(graph, Arrays.asList()));\r
-               \r
-               // set active expression?\r
-               \r
-               return active.getResource();\r
-       }\r
-       \r
-       private class SubscriptSubExpression extends Expression {\r
-               private String[] indices;\r
-               private Expression expression;\r
-               \r
-               public SubscriptSubExpression(String[] indices, Expression expression) {\r
-                       this.indices = indices;\r
-                       this.expression = expression;\r
+               ArrayList<Set<String>> enumerationIndices = new ArrayList<Set<String>>();\r
+               for (int i = 0; i < subExpressions.get(0).indices.length; i++) {\r
+                       enumerationIndices.add(new HashSet<String>());\r
                }\r
                \r
-               @Override\r
-               public Resource write(WriteGraph graph, Resource parent, WriteContext context) throws DatabaseException {\r
-                       SysdynResource sr = SysdynResource.getInstance(graph);\r
-                       \r
+               for (SubscriptSubExpression subexpr : subExpressions) {\r
                        StringBuilder range = new StringBuilder();\r
                        range.append('[');\r
-                       for (String index : indices) {\r
-                               if (range.length() > 1)\r
+                       for (int i = 0; i < subexpr.indices.length; i++) {\r
+                               if (i > 0)\r
                                        range.append(',');\r
-                               range.append(index);\r
+                               range.append(subexpr.indices[i]);\r
+                               \r
+                               enumerationIndices.get(i).add(subexpr.indices[i]);\r
                        }\r
                        range.append(']');\r
                        \r
-                       Resource expr = super.write(graph, parent, context);\r
-                       \r
-                       graph.claimLiteral(expr, sr.Expression_arrayRange, range.toString(), Bindings.STRING);\r
+                       Resource res = subexpr.expression.write(graph, parent, context);\r
                        \r
-                       return expr;\r
+                       graph.claimLiteral(res, sr.Expression_arrayRange, range.toString(), Bindings.STRING);\r
                }\r
-\r
-               @Override\r
-               public Resource getExpressionType(ReadGraph graph) {\r
-                       return expression.getExpressionType(graph);\r
+               \r
+               ArrayList<Resource> enumerations = new ArrayList<Resource>();\r
+               for (Set<String> set : enumerationIndices) {\r
+                       enumerations.add(context.getEnumeration(set).getResource());\r
                }\r
                \r
+               // write array index list\r
+               graph.claim(parent, sr.Variable_arrayIndexesList, ListUtils.create(graph, enumerations));\r
+               \r
+               // set active expression?\r
+               \r
+               return getResource();\r
+       }\r
+       \r
+       private class SubscriptSubExpression {\r
+               \r
+               Expression expression;\r
+               String[] indices;\r
+               \r
+               public SubscriptSubExpression(Expression expression, String...indices) {\r
+                       this.expression = expression;\r
+                       this.indices = indices;\r
+               }\r
        }\r
 \r
        @Override\r
        public Resource getExpressionType(ReadGraph graph) {\r
-               return active.getExpressionType(graph);\r
+               return subExpressions.get(0).expression.getExpressionType(graph);\r
+       }\r
+       \r
+       @Override\r
+       public Resource getResource() {\r
+               return subExpressions.get(0).expression.getResource();\r
        }\r
 }\r
index 4bac0c810b3fc88e020861a6f3a7bd4d4454102f..84eac6638fae61bb0ad7bc043fa17b01ffa53c04 100644 (file)
@@ -28,11 +28,13 @@ public abstract class Expression implements IWriteableObject {
                // insert the expression into the expression list of the variable \r
                // (necessary because of enumeration expressions)\r
                Resource list = graph.getPossibleObject(parent, sr.Variable_expressionList);\r
-               if (list != null)\r
+               if (list != null) {\r
                        ListUtils.insertBack(graph, list, Arrays.asList(expr));\r
-               else\r
+               }\r
+               else {\r
                        graph.claim(parent, sr.Variable_expressionList, ListUtils.create(graph, Arrays.asList(expr)));\r
-\r
+               }\r
+               \r
                return expr;\r
        }\r
        \r
index 3a1441173b360c04a96c4b3a441a7025b36812f0..bc75c359c5040b98787eeeb63b97df4007635c80 100644 (file)
@@ -26,6 +26,7 @@ public class IntegralExpression extends Expression {
                \r
                graph.claimLiteral(expr, sr.StockExpression_integralEquation, integral, Bindings.STRING);\r
                graph.claimLiteral(expr, sr.StockExpression_initialEquation, initial, Bindings.STRING);\r
+               graph.claim(expr, sr.StockExpression_useCustomIntegral, expr);\r
                \r
                return expr;\r
        }\r
index 64d9df06950eea3d1340d24e6d22e72650008f83..de793edbdb88d9ddc19f8fd2a18902772dfcacf2 100644 (file)
@@ -1,39 +1,76 @@
 package org.simantics.sysdyn.modelImport.model.support;\r
 \r
-import java.util.ArrayList;\r
+import java.util.Arrays;\r
+import java.util.HashSet;\r
+import java.util.Set;\r
 \r
 import org.simantics.db.Resource;\r
 import org.simantics.db.WriteGraph;\r
+import org.simantics.db.common.utils.ListUtils;\r
 import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.layer0.Layer0;\r
+import org.simantics.layer0.utils.direct.GraphUtils;\r
+import org.simantics.sysdyn.SysdynResource;\r
 import org.simantics.sysdyn.modelImport.model.IWriteableObject;\r
 import org.simantics.sysdyn.modelImport.model.WriteContext;\r
 \r
 public class Enumeration implements IWriteableObject {\r
        \r
        private String name;\r
-       private ArrayList<String> values;\r
+       private Set<String> values;\r
+       private boolean copy;\r
        \r
-       private Resource resource;\r
+       private Resource enumeration;\r
        \r
-       public Enumeration(String name, ArrayList<String> values) {\r
+       public Enumeration(String name, String...values) {\r
                this.name = name;\r
-               this.values = values;\r
+               this.values = new HashSet<String>(Arrays.asList(values));\r
+               \r
+               copy = false;\r
+       }\r
+       \r
+       public Enumeration(String name, Enumeration other) {\r
+               this.name = name;\r
+               this.values = other.getValues();\r
+               \r
+               copy = true;\r
        }\r
        \r
        public String getName() {\r
                return name;\r
        }\r
+       \r
+       public Set<String> getValues() {\r
+               return values;\r
+       }\r
 \r
        @Override\r
        public Resource write(WriteGraph graph, Resource parent, WriteContext context)\r
                        throws DatabaseException {\r
-               System.err.println("write enumeration");\r
-               return null;\r
+               Layer0 l0 = Layer0.getInstance(graph);\r
+               SysdynResource sr = SysdynResource.getInstance(graph);\r
+               \r
+               enumeration = GraphUtils.create2(graph, sr.Enumeration,\r
+                               l0.HasName, name,\r
+                               l0.PartOf, parent);\r
+               \r
+               Set<Resource> indices = new HashSet<Resource>();\r
+               for (String index : values) {\r
+                       indices.add(GraphUtils.create2(graph, sr.EnumerationIndex,\r
+                                       l0.HasName, index));\r
+               }\r
+               \r
+               graph.claim(enumeration, sr.Enumeration_enumerationIndexList, ListUtils.create(graph, indices));\r
+               \r
+               // register this enumeration with the context\r
+               context.registerEnumeration(this, copy);\r
+               \r
+               return enumeration;\r
        }\r
        \r
        @Override\r
        public Resource getResource() {\r
-               return resource;\r
+               return enumeration;\r
        }\r
 \r
 }\r