1 /*******************************************************************************
2 * Copyright (c) 2010 Association for Decentralized Information Management in
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
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.databoard.type;
14 import java.util.Iterator;
15 import java.util.Map.Entry;
17 import java.util.TreeMap;
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;
26 @Union({BooleanType.class,
39 public abstract class Datatype implements Cloneable {
41 public TreeMap<String, String> metadata = new TreeMap<String, String>();
43 protected void collectSubtypes(Set<Datatype> subtypes, Set<Datatype> recursiveSubtypes) {
47 * Get component type count
48 * @return component count
50 public abstract int getComponentCount();
54 * @param index component index
57 public abstract Datatype getComponentType(int index);
61 * @param path child path or <tt>null</tt> to return this.
63 * @throws IllegalArgumentException if path cannot be applied to this type
65 public abstract Datatype getComponentType(ChildReference path);
68 * Print the type in data type notation.
70 * <a href="http://dev.simantics.org/index.php/Data_type_notation">Datatype Notation</a>
72 * See {@link Datatypes#getDatatype(String)} to parse string to data type.
77 public String toString() {
78 return DataTypePrinter.toString(this, true);
82 * Print the type in data type notation.
84 * <a href="http://dev.simantics.org/index.php/Data_type_notation">Datatype Notation</a>
86 * See {@link Datatypes#getDatatype(String)} to parse string to data type.
90 public String toSingleLineString() {
91 return DataTypePrinter.toString(this, false);
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);
110 public abstract void accept(Visitor1 v, Object obj);
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);
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);
128 public abstract <T> T accept(Visitor<T> v);
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;
136 Iterator<Entry<String, String>> i1 = metadata.entrySet().iterator();
137 Iterator<Entry<String, String>> i2 = other.metadata.entrySet().iterator();
139 while (i1.hasNext() && i2.hasNext()) {
140 if ( !i1.next().equals( i2.next() ) ) return false;
147 * Deep equals-compare
149 * @param obj object to compare with
150 * @return true if the object is equal (incl. structurally) with this object
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);
160 public int hashCode() {
161 return metadataHashCode();
164 public int metadataHashCode() {
166 for (Entry<String, String> e : metadata.entrySet()) {
168 hash += e.hashCode();
173 // public boolean isSubtypeOf(DataType type) {
174 // return equals(type);
177 protected abstract boolean deepEquals(Object obj, Set<IdentityPair<Datatype, Datatype>> compareHistory);
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
185 public abstract <T extends Datatype> T getChildType( ChildReference reference ) throws ReferenceException;