001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2006-2012 Pentaho 008// All Rights Reserved. 009*/ 010package mondrian.rolap; 011 012import mondrian.olap.*; 013import mondrian.resource.MondrianResource; 014import mondrian.spi.CellFormatter; 015import mondrian.spi.Dialect; 016 017import java.util.*; 018 019/** 020 * Measure which is computed from a SQL column (or expression) and which is 021 * defined in a non-virtual cube. 022 * 023 * @see RolapVirtualCubeMeasure 024 * 025 * @author jhyde 026 * @since 24 August, 2006 027 */ 028public class RolapBaseCubeMeasure 029 extends RolapMemberBase 030 implements RolapStoredMeasure 031{ 032 static enum DataType { 033 Integer, 034 Numeric, 035 String 036 } 037 038 /** 039 * For SQL generator. Column which holds the value of the measure. 040 */ 041 private final MondrianDef.Expression expression; 042 043 /** 044 * For SQL generator. Has values "SUM", "COUNT", etc. 045 */ 046 private final RolapAggregator aggregator; 047 048 private final RolapCube cube; 049 private final Map<String, Annotation> annotationMap; 050 051 /** 052 * Holds the {@link mondrian.rolap.RolapStar.Measure} from which this 053 * member is computed. Untyped, because another implementation might store 054 * it somewhere else. 055 */ 056 private Object starMeasure; 057 058 private RolapResult.ValueFormatter formatter; 059 060 /** 061 * Creates a RolapBaseCubeMeasure. 062 * 063 * @param cube Cube 064 * @param parentMember Parent member 065 * @param level Level this member belongs to 066 * @param name Name of this member 067 * @param caption Caption 068 * @param description Description 069 * @param formatString Format string 070 * @param expression Expression 071 * @param aggregatorName Aggregator 072 * @param datatype Data type 073 * @param annotationMap Annotations 074 */ 075 RolapBaseCubeMeasure( 076 RolapCube cube, 077 RolapMember parentMember, 078 RolapLevel level, 079 String name, 080 String caption, 081 String description, 082 String formatString, 083 MondrianDef.Expression expression, 084 String aggregatorName, 085 String datatype, 086 Map<String, Annotation> annotationMap) 087 { 088 super(parentMember, level, name, null, MemberType.MEASURE); 089 assert annotationMap != null; 090 this.cube = cube; 091 this.annotationMap = annotationMap; 092 this.caption = caption; 093 this.expression = expression; 094 if (description != null) { 095 setProperty( 096 Property.DESCRIPTION.name, 097 description); 098 } 099 if (formatString == null) { 100 formatString = ""; 101 } else { 102 setProperty( 103 Property.FORMAT_STRING.name, 104 formatString); 105 } 106 setProperty( 107 Property.FORMAT_EXP_PARSED.name, 108 Literal.createString(formatString)); 109 setProperty( 110 Property.FORMAT_EXP.name, 111 formatString); 112 113 // Validate aggregator. 114 this.aggregator = 115 RolapAggregator.enumeration.getValue(aggregatorName, false); 116 if (this.aggregator == null) { 117 StringBuilder buf = new StringBuilder(); 118 for (String aggName : RolapAggregator.enumeration.getNames()) { 119 if (buf.length() > 0) { 120 buf.append(", "); 121 } 122 buf.append('\''); 123 buf.append(aggName); 124 buf.append('\''); 125 } 126 throw MondrianResource.instance().UnknownAggregator.ex( 127 aggregatorName, 128 buf.toString()); 129 } 130 131 setProperty(Property.AGGREGATION_TYPE.name, aggregator); 132 if (datatype == null) { 133 if (aggregator == RolapAggregator.Count 134 || aggregator == RolapAggregator.DistinctCount) 135 { 136 datatype = "Integer"; 137 } else { 138 datatype = "Numeric"; 139 } 140 } 141 if (RolapBaseCubeMeasure.DataType.valueOf(datatype) == null) { 142 throw MondrianResource.instance().CastInvalidType.ex(datatype); 143 } 144 setProperty(Property.DATATYPE.name, datatype); 145 } 146 147 public MondrianDef.Expression getMondrianDefExpression() { 148 return expression; 149 } 150 151 public RolapAggregator getAggregator() { 152 return aggregator; 153 } 154 155 public RolapCube getCube() { 156 return cube; 157 } 158 159 public RolapResult.ValueFormatter getFormatter() { 160 return formatter; 161 } 162 163 public void setFormatter(CellFormatter cellFormatter) { 164 this.formatter = 165 new RolapResult.CellFormatterValueFormatter(cellFormatter); 166 } 167 168 public Object getStarMeasure() { 169 return starMeasure; 170 } 171 172 void setStarMeasure(Object starMeasure) { 173 this.starMeasure = starMeasure; 174 } 175 176 @Override 177 public Map<String, Annotation> getAnnotationMap() { 178 return annotationMap; 179 } 180 181 public Dialect.Datatype getDatatype() { 182 Object datatype = getPropertyValue(Property.DATATYPE.name); 183 try { 184 return Dialect.Datatype.valueOf((String) datatype); 185 } catch (ClassCastException e) { 186 return Dialect.Datatype.String; 187 } catch (IllegalArgumentException e) { 188 return Dialect.Datatype.String; 189 } 190 } 191} 192 193// End RolapBaseCubeMeasure.java