]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/type/ArrayType.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / type / ArrayType.java
1 /*******************************************************************************\r
2  *  Copyright (c) 2010 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.type;
13
14 import java.util.Set;\r
15 \r
16 import org.simantics.databoard.accessor.error.ReferenceException;\r
17 import org.simantics.databoard.accessor.reference.ChildReference;\r
18 import org.simantics.databoard.accessor.reference.IndexReference;\r
19 import org.simantics.databoard.accessor.reference.KeyReference;\r
20 import org.simantics.databoard.accessor.reference.LabelReference;\r
21 import org.simantics.databoard.accessor.reference.NameReference;\r
22 import org.simantics.databoard.util.IdentityPair;\r
23 import org.simantics.databoard.util.Limit;\r
24 import org.simantics.databoard.util.ObjectUtils;\r
25 import org.simantics.databoard.util.Range;\r
26 import org.simantics.databoard.util.RangeException;\r
27
28 public class ArrayType extends Datatype {
29     \r
30         /** Metadata key for array length */\r
31         public static final String KEY_LENGTH = "length";\r
32 \r
33         private transient Range _length; \r
34         private transient String _lengthIsForStr;\r
35         
36     public Datatype componentType;
37     
38     public ArrayType() {}
39     
40     public ArrayType(Datatype componentType) {
41         this.componentType = componentType;
42     }
43     
44     public ArrayType(Datatype componentType, String length) {
45         this.componentType = componentType;\r
46         setLength(length);
47     }
48
49     public ArrayType(Datatype componentType, Range length) {
50         this.componentType = componentType;
51         setLength(length);
52     }\r
53     \r
54     @Override\r
55     public int getComponentCount() {\r
56         return 1;\r
57     }\r
58     \r
59     @Override\r
60     public Datatype getComponentType(int index) {\r
61         if (index!=0) throw new IllegalArgumentException();\r
62         return componentType;\r
63     }\r
64     \r
65     @Override\r
66     public Datatype getComponentType(ChildReference path) {\r
67         if (path==null) return this;\r
68         if (path instanceof KeyReference) throw new IllegalArgumentException("KeyReference is not supported in ArrayType"); \r
69         if (path instanceof NameReference) throw new IllegalArgumentException("NameReference is not supported in ArrayType"); \r
70         if (path instanceof IndexReference && ((IndexReference) path).index!=0) throw new IllegalArgumentException("Index out of bounds");\r
71         if (path instanceof LabelReference && !((LabelReference) path).label.equals("v")) throw new IllegalArgumentException("Unknown label");\r
72         return componentType.getComponentType(path.childReference);\r
73     }
74     
75         @Override
76         protected void collectSubtypes(Set<Datatype> subtypes, Set<Datatype> recursiveSubtypes) {
77                 componentType.collectSubtypes(subtypes, recursiveSubtypes);
78         }
79         
80         @Override
81         protected boolean deepEquals(Object obj, Set<IdentityPair<Datatype, Datatype>> compareHistory) {
82                 if ( this==obj ) return true;\r
83                 if ( !hasEqualMetadata(obj) ) return false;\r
84                 if (obj instanceof ArrayType == false) return false;
85                 ArrayType other = (ArrayType) obj;\r
86                 return componentType.deepEquals(other.componentType, compareHistory);
87         }
88         
89         @Override
90         public int hashCode() {\r
91                 if (componentType==this) return 0;              \r
92                 return 0x234ae + metadataHashCode() + 13* ObjectUtils.hashCode(componentType);
93         }       \r
94         
95         @Override
96         public void accept(Visitor1 v, Object obj) {
97             v.visit(this, obj);        
98         }
99
100         @Override
101         public <T> T accept(Visitor<T> v) {
102             return v.visit(this);
103         }
104
105         public Datatype componentType() {
106                 return componentType;
107         }\r
108 \r
109         @Deprecated\r
110         public Datatype getComponentType() {\r
111                 return componentType;\r
112         }\r
113
114         public void setComponentType(Datatype componentType) {
115                 this.componentType = componentType;
116         }
117
118     public int minLength() {\r
119         Range length = getLength();
120         if (length==null) return 0;
121         Limit l = length.getLower();
122         int value = l.getValue().intValue();
123         if (l.isExclusive()) value++;
124         return value;
125     }
126     
127     public int maxLength() {
128         Range length = getLength();\r
129         if (length==null) return Integer.MAX_VALUE;
130         Limit l = length.getUpper();
131         int value = l.getValue().intValue();
132         if (l.isExclusive()) value--;
133         return value;
134     }
135         
136         public Range getLength() {
137                 String lengthStr = metadata.get( KEY_LENGTH );\r
138                 if (lengthStr == null) return null;\r
139                 if (_length != null && lengthStr!=null && lengthStr==_lengthIsForStr) return _length;\r
140                 try {\r
141                         _lengthIsForStr = lengthStr;\r
142                         _length = Range.valueOf( lengthStr );\r
143                 } catch (RangeException e) {\r
144                         _length = null;\r
145                 }\r
146                 return _length;\r
147         }
148
149         public String getLengthStr() {
150                 return metadata.get( KEY_LENGTH );
151         }
152         
153         public void setLength(String length) {\r
154                 _length = null;\r
155                 _lengthIsForStr = null;\r
156                 if ( length == null ) {\r
157                         metadata.remove( KEY_LENGTH ); \r
158                 } else {\r
159                         metadata.put( KEY_LENGTH, length );\r
160                 }
161         }
162         
163         public void setLength(Range range) {\r
164                 if (range==null) {\r
165                         metadata.remove( KEY_LENGTH );\r
166                         _length = null;\r
167                         _lengthIsForStr = null;\r
168                 } else {\r
169                         _length = range;\r
170                         _lengthIsForStr = range.toString();\r
171                         metadata.put( KEY_LENGTH, _lengthIsForStr );\r
172                 }
173         }
174 \r
175         @SuppressWarnings("unchecked")\r
176         @Override\r
177         public <T extends Datatype> T getChildType(ChildReference reference) throws ReferenceException {\r
178                 if (reference==null) return (T) this;\r
179                 \r
180                 if (reference instanceof LabelReference) {\r
181                         LabelReference lr = (LabelReference) reference;\r
182                         try {\r
183                                 Integer.valueOf( lr.label );\r
184                                 return componentType.getChildType(reference.getChildReference());\r
185                         } catch ( NumberFormatException nfe ) {\r
186                                 throw new ReferenceException(nfe);\r
187                         }                       \r
188                 } else if (reference instanceof IndexReference) {\r
189                         return componentType.getChildType(reference.getChildReference());\r
190                 } \r
191                 throw new ReferenceException(reference.getClass().getName()+" is not a reference of an array"); \r
192         }\r
193         
194 }