]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/binding/classfactory/SignatureVisitor.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / binding / classfactory / SignatureVisitor.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.databoard.binding.classfactory;\r
13 \r
14 import java.util.IdentityHashMap;\r
15 \r
16 import org.simantics.databoard.Datatypes;\r
17 import org.simantics.databoard.type.ArrayType;\r
18 import org.simantics.databoard.type.BooleanType;\r
19 import org.simantics.databoard.type.ByteType;\r
20 import org.simantics.databoard.type.Datatype;\r
21 import org.simantics.databoard.type.DoubleType;\r
22 import org.simantics.databoard.type.FloatType;\r
23 import org.simantics.databoard.type.IntegerType;\r
24 import org.simantics.databoard.type.LongType;\r
25 import org.simantics.databoard.type.MapType;\r
26 import org.simantics.databoard.type.OptionalType;\r
27 import org.simantics.databoard.type.RecordType;\r
28 import org.simantics.databoard.type.StringType;\r
29 import org.simantics.databoard.type.UnionType;\r
30 import org.simantics.databoard.type.VariantType;\r
31 \r
32 /**\r
33  * Signature Visitor builds a signature string from a datatype.\r
34  * The argument is StringBuilder.\r
35  * \r
36  * Signature is construtructed with the following notation.\r
37  * \r
38  *   s                        StringType\r
39  *   z                        BooleanType\r
40  *   d                        DoubleType\r
41  *   f                        FloatType\r
42  *   i                        IntegerType\r
43  *   b                        ByteType\r
44  *   j                        LongType\r
45  *   R                        Referable RecordType\r
46  *   o*                       OptionalType, * denotes componentType\r
47  *   a*                       ArrayType, * denotes componentType\r
48  *   r**e                     RecordType, ** denotes fields\r
49  *   u                        UnionType, * denotes components\r
50  *   m**                      MapType, ** denotes keyType and valueType\r
51  *   t                        Datatype\r
52  *   \r
53  * For example, The signature of UUID.class is "rjje" \r
54  * \r
55  * @author toni.kalajainen\r
56  */\r
57 public class SignatureVisitor implements Datatype.Visitor1 {\r
58         \r
59         public StringBuilder sb = new StringBuilder();\r
60         public int hashcode = 0xbcbcbca;\r
61         public IdentityHashMap<Datatype, Boolean> visited = new IdentityHashMap<Datatype, Boolean>();\r
62         \r
63         public static String toSignature(Datatype type)\r
64         {\r
65                 SignatureVisitor sv = new SignatureVisitor();\r
66                 type.accept( sv, null );\r
67                 String sig = sv.sb.toString();\r
68                 return sig;\r
69         }       \r
70 \r
71         @Override\r
72         public void visit(ArrayType b, Object obj) {\r
73                 sb.append('a');\r
74                 b.componentType.accept(this, obj);\r
75                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
76         }\r
77 \r
78         @Override\r
79         public void visit(BooleanType b, Object obj) {\r
80                 sb.append('z');\r
81                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
82         }\r
83 \r
84         @Override\r
85         public void visit(DoubleType b, Object obj) {\r
86                 sb.append('d');\r
87                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
88         }\r
89 \r
90         @Override\r
91         public void visit(FloatType b, Object obj) {\r
92                 sb.append('f');\r
93                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
94         }\r
95 \r
96         @Override\r
97         public void visit(IntegerType b, Object obj) {\r
98                 sb.append('i');\r
99                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
100         }\r
101 \r
102         @Override\r
103         public void visit(ByteType b, Object obj) {\r
104                 sb.append('b');\r
105                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
106         }\r
107 \r
108         @Override\r
109         public void visit(LongType b, Object obj) {\r
110                 sb.append('j');\r
111                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
112         }\r
113 \r
114         @Override\r
115         public void visit(OptionalType b, Object obj) {\r
116                 sb.append('o');\r
117                 b.componentType.accept(this, sb);\r
118                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
119         }\r
120 \r
121         @Override\r
122         public void visit(RecordType b, Object obj) {\r
123                 if ( wasVisited(b) ) {\r
124                         sb.append('R');\r
125                         return;\r
126                 }\r
127                 if ( b.isReferable() ) {\r
128                         sb.append('R');\r
129                         return;\r
130                 }\r
131                 \r
132                 sb.append('r');\r
133                 for (int i=0; i<b.getComponentCount(); i++) {\r
134                         b.getComponentType(i).accept(this, sb);\r
135                 }\r
136                 sb.append('e');\r
137 \r
138                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
139                 for (int i=0; i<b.getComponentCount(); i++) {\r
140                         hashcode = 13*hashcode + b.getComponent(i).name.hashCode();\r
141                 }\r
142         }\r
143 \r
144         @Override\r
145         public void visit(StringType b, Object obj) {\r
146                 sb.append('s');\r
147                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
148         }\r
149 \r
150         @Override\r
151         public void visit(UnionType b, Object obj) {\r
152                 if ( b.equals( Datatypes.getDatatypeUnchecked(Datatype.class) )) {\r
153                         sb.append("t");\r
154                         return;\r
155                 }\r
156                 if ( wasVisited(b) ) {\r
157                         sb.append('U');\r
158                         return;\r
159                 }\r
160                 sb.append('u');\r
161                 for (int i=0; i<b.getComponentCount(); i++) {\r
162                         b.getComponentType(i).accept(this, sb);\r
163                 }\r
164                 sb.append('e');\r
165                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
166         }\r
167 \r
168         @Override\r
169         public void visit(VariantType b, Object obj) {\r
170                 sb.append('v');\r
171                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
172         }\r
173 \r
174         @Override\r
175         public void visit(MapType b, Object obj) {\r
176                 if ( wasVisited(b) ) return;\r
177                 sb.append('m');\r
178                 b.keyType.accept(this, obj);\r
179                 b.valueType.accept(this, obj);\r
180                 hashcode = 13*hashcode + b.getClass().getName().hashCode() + 133*b.metadataHashCode();\r
181         }\r
182         \r
183         /**\r
184          * Visit and return if was visited\r
185          * @param type\r
186          * @return\r
187          */\r
188         boolean wasVisited(Datatype type) {\r
189                 Boolean result = visited.put(type, Boolean.TRUE);\r
190                 return result == null ? false : result;\r
191         }\r
192 }\r