]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/type/ArrayType.java
Added addFirst/After/Before + remove SCL functions for Ordered Sets
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / type / ArrayType.java
1 /*******************************************************************************
2  *  Copyright (c) 2010 Association for Decentralized Information Management in
3  *  Industry THTH ry.
4  *  All rights reserved. This program and the accompanying materials
5  *  are made available under the terms of the Eclipse Public License v1.0
6  *  which accompanies this distribution, and is available at
7  *  http://www.eclipse.org/legal/epl-v10.html
8  *
9  *  Contributors:
10  *      VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.databoard.type;
13
14 import java.util.Set;
15
16 import org.simantics.databoard.accessor.error.ReferenceException;
17 import org.simantics.databoard.accessor.reference.ChildReference;
18 import org.simantics.databoard.accessor.reference.IndexReference;
19 import org.simantics.databoard.accessor.reference.KeyReference;
20 import org.simantics.databoard.accessor.reference.LabelReference;
21 import org.simantics.databoard.accessor.reference.NameReference;
22 import org.simantics.databoard.util.IdentityPair;
23 import org.simantics.databoard.util.Limit;
24 import org.simantics.databoard.util.ObjectUtils;
25 import org.simantics.databoard.util.Range;
26 import org.simantics.databoard.util.RangeException;
27
28 public class ArrayType extends Datatype {
29     
30         /** Metadata key for array length */
31         public static final String KEY_LENGTH = "length";
32
33         private transient Range _length; 
34         private transient String _lengthIsForStr;
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;
46         setLength(length);
47     }
48
49     public ArrayType(Datatype componentType, Range length) {
50         this.componentType = componentType;
51         setLength(length);
52     }
53     
54     @Override
55     public int getComponentCount() {
56         return 1;
57     }
58     
59     @Override
60     public Datatype getComponentType(int index) {
61         if (index!=0) throw new IllegalArgumentException();
62         return componentType;
63     }
64     
65     @Override
66     public Datatype getComponentType(ChildReference path) {
67         if (path==null) return this;
68         if (path instanceof KeyReference) throw new IllegalArgumentException("KeyReference is not supported in ArrayType"); 
69         if (path instanceof NameReference) throw new IllegalArgumentException("NameReference is not supported in ArrayType"); 
70         if (path instanceof IndexReference && ((IndexReference) path).index!=0) throw new IllegalArgumentException("Index out of bounds");
71         if (path instanceof LabelReference && !((LabelReference) path).label.equals("v")) throw new IllegalArgumentException("Unknown label");
72         return componentType.getComponentType(path.childReference);
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;
83                 if ( !hasEqualMetadata(obj) ) return false;
84                 if (obj instanceof ArrayType == false) return false;
85                 ArrayType other = (ArrayType) obj;
86                 return componentType.deepEquals(other.componentType, compareHistory);
87         }
88         
89         @Override
90         public int hashCode() {
91                 if (componentType==this) return 0;              
92                 return 0x234ae + metadataHashCode() + 13* ObjectUtils.hashCode(componentType);
93         }       
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         }
108
109         @Deprecated
110         public Datatype getComponentType() {
111                 return componentType;
112         }
113
114         public void setComponentType(Datatype componentType) {
115                 this.componentType = componentType;
116         }
117
118     public int minLength() {
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();
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 );
138                 if (lengthStr == null) return null;
139                 if (_length != null && lengthStr!=null && lengthStr==_lengthIsForStr) return _length;
140                 try {
141                         _lengthIsForStr = lengthStr;
142                         _length = Range.valueOf( lengthStr );
143                 } catch (RangeException e) {
144                         _length = null;
145                 }
146                 return _length;
147         }
148
149         public String getLengthStr() {
150                 return metadata.get( KEY_LENGTH );
151         }
152         
153         public void setLength(String length) {
154                 _length = null;
155                 _lengthIsForStr = null;
156                 if ( length == null ) {
157                         metadata.remove( KEY_LENGTH ); 
158                 } else {
159                         metadata.put( KEY_LENGTH, length );
160                 }
161         }
162         
163         public void setLength(Range range) {
164                 if (range==null) {
165                         metadata.remove( KEY_LENGTH );
166                         _length = null;
167                         _lengthIsForStr = null;
168                 } else {
169                         _length = range;
170                         _lengthIsForStr = range.toString();
171                         metadata.put( KEY_LENGTH, _lengthIsForStr );
172                 }
173         }
174
175         @SuppressWarnings("unchecked")
176         @Override
177         public <T extends Datatype> T getChildType(ChildReference reference) throws ReferenceException {
178                 if (reference==null) return (T) this;
179                 
180                 if (reference instanceof LabelReference) {
181                         LabelReference lr = (LabelReference) reference;
182                         try {
183                                 Integer.valueOf( lr.label );
184                                 return componentType.getChildType(reference.getChildReference());
185                         } catch ( NumberFormatException nfe ) {
186                                 throw new ReferenceException(nfe);
187                         }                       
188                 } else if (reference instanceof IndexReference) {
189                         return componentType.getChildType(reference.getChildReference());
190                 } 
191                 throw new ReferenceException(reference.getClass().getName()+" is not a reference of an array"); 
192         }
193         
194 }