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