001 /*
002 // $Id: //open/mondrian-release/3.0/src/main/mondrian/olap/type/TupleType.java#2 $
003 // This software is subject to the terms of the Common Public License
004 // Agreement, available at the following URL:
005 // http://www.opensource.org/licenses/cpl.html.
006 // Copyright (C) 2005-2008 Julian Hyde
007 // All Rights Reserved.
008 // You must accept the terms of that agreement to use this software.
009 */
010 package mondrian.olap.type;
011
012 import mondrian.olap.*;
013
014 import java.util.Arrays;
015 import java.util.ArrayList;
016 import java.util.List;
017
018 /**
019 * Tuple type.
020 *
021 * @author jhyde
022 * @since Feb 17, 2005
023 * @version $Id: //open/mondrian-release/3.0/src/main/mondrian/olap/type/TupleType.java#2 $
024 */
025 public class TupleType implements Type {
026 public final Type[] elementTypes;
027 private final String digest;
028
029 /**
030 * Creates a type representing a tuple whose fields are the given types.
031 *
032 * @param elementTypes Array of types of the members in this tuple
033 */
034 public TupleType(Type[] elementTypes) {
035 assert elementTypes != null;
036 this.elementTypes = elementTypes.clone();
037
038 final StringBuilder buf = new StringBuilder();
039 buf.append("TupleType<");
040 int k = 0;
041 for (Type elementType : elementTypes) {
042 if (k++ > 0) {
043 buf.append(", ");
044 }
045 buf.append(elementType);
046 }
047 buf.append(">");
048 digest = buf.toString();
049 }
050
051 public String toString() {
052 return digest;
053 }
054
055 public boolean equals(Object obj) {
056 if (obj instanceof TupleType) {
057 TupleType that = (TupleType) obj;
058 return Arrays.equals(this.elementTypes, that.elementTypes);
059 } else {
060 return false;
061 }
062 }
063
064 public int hashCode() {
065 return digest.hashCode();
066 }
067
068 public boolean usesDimension(Dimension dimension, boolean definitely) {
069 for (Type elementType : elementTypes) {
070 if (elementType.usesDimension(dimension, definitely)) {
071 return true;
072 }
073 }
074 return false;
075 }
076
077 public Dimension getDimension() {
078 throw new UnsupportedOperationException();
079 }
080
081 public Hierarchy getHierarchy() {
082 throw new UnsupportedOperationException();
083 }
084
085 public Level getLevel() {
086 throw new UnsupportedOperationException();
087 }
088
089 public Type getValueType() {
090 for (Type elementType : elementTypes) {
091 if (elementType instanceof MemberType) {
092 MemberType memberType = (MemberType) elementType;
093 Dimension dimension = memberType.getDimension();
094 if (dimension != null && dimension.isMeasures()) {
095 return memberType.getValueType();
096 }
097 }
098 }
099 return new ScalarType();
100 }
101
102 public Type computeCommonType(Type type, int[] conversionCount) {
103 if (type instanceof ScalarType) {
104 return getValueType().computeCommonType(type, conversionCount);
105 }
106 if (type instanceof MemberType) {
107 return commonTupleType(
108 new TupleType(new Type[]{type}),
109 conversionCount);
110 }
111 if (!(type instanceof TupleType)) {
112 return null;
113 }
114 return commonTupleType(type, conversionCount);
115 }
116
117 private Type commonTupleType(Type type, int[] conversionCount) {
118 TupleType that = (TupleType) type;
119
120 if(this.elementTypes.length < that.elementTypes.length){
121 return createCommonTupleType(that, conversionCount);
122 }
123 return that.createCommonTupleType(this, conversionCount);
124 }
125
126 private Type createCommonTupleType(TupleType that, int[] conversionCount) {
127 final List<Type> elementTypes = new ArrayList<Type>();
128 for (int i = 0; i < this.elementTypes.length; i++) {
129 Type commonType = this.elementTypes[i].computeCommonType(
130 that.elementTypes[i], conversionCount);
131 elementTypes.add(commonType);
132 if (commonType == null) {
133 return null;
134 }
135 }
136 if(elementTypes.size() < that.elementTypes.length){
137 for(int i=elementTypes.size();i< that.elementTypes.length;i++){
138 elementTypes.add(new ScalarType());
139 }
140 }
141 return new TupleType(
142 elementTypes.toArray(new Type[elementTypes.size()]));
143 }
144 }
145
146 // End TupleType.java