001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/type/TupleType.java#12 $ 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/src/main/mondrian/olap/type/TupleType.java#12 $ 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