]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.databoard/src/org/simantics/databoard/type/Datatype.java
Added addFirst/After/Before + remove SCL functions for Ordered Sets
[simantics/platform.git] / bundles / org.simantics.databoard / src / org / simantics / databoard / type / Datatype.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.Iterator;
15 import java.util.Map.Entry;
16 import java.util.Set;
17 import java.util.TreeMap;
18
19 import org.simantics.databoard.Datatypes;
20 import org.simantics.databoard.accessor.error.ReferenceException;
21 import org.simantics.databoard.accessor.reference.ChildReference;
22 import org.simantics.databoard.annotations.Union;
23 import org.simantics.databoard.parser.unparsing.DataTypePrinter;
24 import org.simantics.databoard.util.IdentityPair;
25
26 @Union({BooleanType.class,
27         ByteType.class,
28         IntegerType.class,       
29         LongType.class,
30         FloatType.class,
31         DoubleType.class,
32         StringType.class,
33         RecordType.class,
34         ArrayType.class,
35         MapType.class,
36         OptionalType.class,
37         UnionType.class,
38         VariantType.class}) 
39 public abstract class Datatype implements Cloneable {
40         
41         public TreeMap<String, String> metadata = new TreeMap<String, String>();
42         
43         protected void collectSubtypes(Set<Datatype> subtypes, Set<Datatype> recursiveSubtypes) {               
44         }
45
46         /** 
47          * Get component type count
48          * @return component count
49          */
50         public abstract int getComponentCount();
51         
52         /**
53          * Get component type
54          * @param index component index
55          * @return datatype
56          */
57     public abstract Datatype getComponentType(int index);
58     
59     /**
60      * Get component type
61      * @param path child path or <tt>null</tt> to return this.
62      * @return datatype
63      * @throws IllegalArgumentException if path cannot be applied to this type 
64      */
65     public abstract Datatype getComponentType(ChildReference path);
66         
67         /**
68          * Print the type in data type notation.
69          * 
70          * <a href="http://dev.simantics.org/index.php/Data_type_notation">Datatype Notation</a>
71          * 
72          * See {@link Datatypes#getDatatype(String)} to parse string to data type.
73          * 
74          * @return type
75          */
76         @Override
77         public String toString() {
78                 return DataTypePrinter.toString(this, true);
79         }
80
81         /**
82          * Print the type in data type notation.
83          * 
84          * <a href="http://dev.simantics.org/index.php/Data_type_notation">Datatype Notation</a>
85          * 
86          * See {@link Datatypes#getDatatype(String)} to parse string to data type.
87          * 
88          * @return type
89          */
90         public String toSingleLineString() {
91                 return DataTypePrinter.toString(this, false);
92         }
93         
94     public interface Visitor1 {
95         void visit(ArrayType b, Object obj);
96         void visit(BooleanType b, Object obj);
97         void visit(DoubleType b, Object obj);
98         void visit(FloatType b, Object obj);
99         void visit(IntegerType b, Object obj);
100         void visit(ByteType b, Object obj);
101         void visit(LongType b, Object obj);
102         void visit(OptionalType b, Object obj);
103         void visit(RecordType b, Object obj);
104         void visit(StringType b, Object obj);
105         void visit(UnionType b, Object obj);
106         void visit(VariantType b, Object obj);
107         void visit(MapType b, Object obj);
108     }
109         
110     public abstract void accept(Visitor1 v, Object obj);
111     
112     public interface Visitor<T> {
113         T visit(ArrayType b);
114         T visit(BooleanType b);
115         T visit(DoubleType b);
116         T visit(FloatType b);
117         T visit(IntegerType b);
118         T visit(ByteType b);
119         T visit(LongType b);
120         T visit(OptionalType b);
121         T visit(RecordType b);
122         T visit(StringType b);
123         T visit(UnionType b);
124         T visit(VariantType b);
125         T visit(MapType b);
126     }
127     
128     public abstract <T> T accept(Visitor<T> v); 
129
130     protected boolean hasEqualMetadata(Object obj) {
131                 // Check metadata is equal
132                 Datatype other = (Datatype) obj;
133                 int s1 = metadata.size(), s2 = other.metadata.size();           
134                 if ( s1 != s2 ) return false;
135                 if ( s1>0 ) {
136                         Iterator<Entry<String, String>> i1 = metadata.entrySet().iterator();
137                         Iterator<Entry<String, String>> i2 = other.metadata.entrySet().iterator();
138                         
139                         while (i1.hasNext() && i2.hasNext()) {
140                                 if ( !i1.next().equals( i2.next() ) ) return false;
141                         }
142                 }                   
143                 return true;
144     }
145     
146     /**
147      * Deep equals-compare
148      * 
149      * @param obj object to compare with
150      * @return true if the object is equal (incl. structurally) with this object
151      */
152         @Override
153         public boolean equals(Object obj) {
154                 if (this==obj) return true;
155                 if (!this.getClass().isInstance(obj)) return false;             
156                 return deepEquals(obj, null);           
157         }
158         
159         @Override
160         public int hashCode() {
161                 return metadataHashCode();
162         }
163         
164         public int metadataHashCode() {
165                 int hash = 13;
166                 for (Entry<String, String> e : metadata.entrySet()) {
167                         hash *= 13; 
168                         hash += e.hashCode();
169                 }
170                 return hash;
171         }
172         
173 //      public boolean isSubtypeOf(DataType type) {
174 //              return equals(type);
175 //      }
176     
177     protected abstract boolean deepEquals(Object obj, Set<IdentityPair<Datatype, Datatype>> compareHistory);    
178     
179     /**
180      * Get child by reference
181      * @param reference type reference or null (for this instance)
182      * @return the child type 
183      * @throws ReferenceException if child was not found
184      */
185     public abstract <T extends Datatype> T getChildType( ChildReference reference ) throws ReferenceException;
186     
187 }
188