001    /*
002    // $Id: //open/mondrian/src/main/mondrian/rolap/RolapBaseCubeMeasure.java#10 $
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) 2006-2008 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.rolap;
011    
012    import mondrian.olap.*;
013    import mondrian.rolap.sql.SqlQuery;
014    import mondrian.resource.MondrianResource;
015    
016    import java.util.List;
017    import java.util.Arrays;
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     * @version $Id: //open/mondrian/src/main/mondrian/rolap/RolapBaseCubeMeasure.java#10 $
028     */
029    public class RolapBaseCubeMeasure extends RolapMember implements RolapStoredMeasure {
030    
031        private static final List<String> datatypeList =
032            Arrays.asList("Integer", "Numeric", "String");
033    
034        /**
035         * For SQL generator. Column which holds the value of the measure.
036         */
037        private final MondrianDef.Expression expression;
038    
039        /**
040         * For SQL generator. Has values "SUM", "COUNT", etc.
041         */
042        private final RolapAggregator aggregator;
043    
044        private final RolapCube cube;
045    
046        /**
047         * Holds the {@link mondrian.rolap.RolapStar.Measure} from which this
048         * member is computed. Untyped, because another implementation might store
049         * it somewhere else.
050         */
051        private Object starMeasure;
052    
053        private CellFormatter formatter;
054    
055        RolapBaseCubeMeasure(
056                RolapCube cube,
057                RolapMember parentMember,
058                RolapLevel level,
059                String name,
060                String formatString,
061                MondrianDef.Expression expression,
062                String aggregatorName,
063                String datatype) {
064            super(parentMember, level, name, null, MemberType.MEASURE);
065            this.cube = cube;
066            this.expression = expression;
067            if (formatString == null) {
068                formatString = "";
069            }
070            setProperty(
071                    Property.FORMAT_EXP.name,
072                    Literal.createString(formatString));
073    
074            // Validate aggregator.
075            this.aggregator =
076                RolapAggregator.enumeration.getValue(aggregatorName, false);
077            if (this.aggregator == null) {
078                StringBuilder buf = new StringBuilder();
079                for (String aggName : RolapAggregator.enumeration.getNames()) {
080                    if (buf.length() > 0) {
081                        buf.append(", ");
082                    }
083                    buf.append('\'');
084                    buf.append(aggName);
085                    buf.append('\'');
086                }
087                throw MondrianResource.instance().UnknownAggregator.ex(
088                    aggregatorName,
089                    buf.toString());
090            }
091    
092            setProperty(Property.AGGREGATION_TYPE.name, aggregator);
093            if (datatype == null) {
094                if (aggregator == RolapAggregator.Count ||
095                        aggregator == RolapAggregator.DistinctCount) {
096                    datatype = "Integer";
097                } else {
098                    datatype = "Numeric";
099                }
100            }
101            // todo: End-user error.
102            Util.assertTrue(
103                RolapBaseCubeMeasure.datatypeList.contains(datatype),
104                "invalid datatype " + datatype);
105            setProperty(Property.DATATYPE.name, datatype);
106        }
107    
108        public MondrianDef.Expression getMondrianDefExpression() {
109            return expression;
110        }
111    
112        public RolapAggregator getAggregator() {
113            return aggregator;
114        }
115    
116        public RolapCube getCube() {
117            return cube;
118        }
119    
120        public CellFormatter getFormatter() {
121            return formatter;
122        }
123    
124        public void setFormatter(CellFormatter formatter) {
125            this.formatter = formatter;
126        }
127    
128        public Object getStarMeasure() {
129            return starMeasure;
130        }
131    
132        void setStarMeasure(Object starMeasure) {
133            this.starMeasure = starMeasure;
134        }
135    
136        public SqlQuery.Datatype getDatatype() {
137            Object datatype = getPropertyValue(Property.DATATYPE.name);
138            try {
139                return SqlQuery.Datatype.valueOf((String) datatype);
140            } catch (ClassCastException e) {
141                return SqlQuery.Datatype.String;
142            } catch (IllegalArgumentException e) {
143                return SqlQuery.Datatype.String;
144            }
145        }
146    }
147    
148    // End RolapBaseCubeMeasure.java