001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/ExpCacheDescriptor.java#5 $
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-2006 Julian Hyde
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    */
010    package mondrian.olap;
011    
012    import mondrian.calc.*;
013    import mondrian.calc.impl.BetterExpCompiler;
014    
015    import java.util.ArrayList;
016    import java.util.List;
017    
018    /**
019     * Holds information necessary to add an expression to the expression result
020     * cache (see {@link Evaluator#getCachedResult(ExpCacheDescriptor)}).
021     *
022     * @author jhyde
023     * @since Aug 16, 2005
024     * @version $Id: //open/mondrian/src/main/mondrian/olap/ExpCacheDescriptor.java#5 $
025     */
026    public class ExpCacheDescriptor {
027        private final Exp exp;
028        private int[] dependentDimensionOrdinals;
029        private final Calc calc;
030    
031        public ExpCacheDescriptor(Exp exp, Calc calc, Evaluator evaluator) {
032            this.calc = calc;
033            this.exp = exp;
034            computeDepends(calc, evaluator);
035        }
036    
037        /**
038         * Creates a descriptor.
039         */
040        public ExpCacheDescriptor(Exp exp, Evaluator evaluator) {
041            this(exp, new BetterExpCompiler(evaluator, null));
042        }
043    
044        /**
045         * Creates a descriptor.
046         */
047        public ExpCacheDescriptor(Exp exp, ExpCompiler compiler) {
048            this.exp = exp;
049    
050            // Compile expression.
051            this.calc = compiler.compile(exp);
052    
053            // Compute list of dependent dimensions.
054            computeDepends(calc, compiler.getEvaluator());
055        }
056    
057        private void computeDepends(Calc calc, Evaluator evaluator) {
058            final List<Integer> ordinalList = new ArrayList<Integer>();
059            final Member[] members = evaluator.getMembers();
060            for (int i = 0; i < members.length; i++) {
061                Dimension dimension = members[i].getDimension();
062                if (calc.dependsOn(dimension)) {
063                    ordinalList.add(i);
064                }
065            }
066            dependentDimensionOrdinals = new int[ordinalList.size()];
067            for (int i = 0; i < dependentDimensionOrdinals.length; i++) {
068                dependentDimensionOrdinals[i] = ordinalList.get(i);
069            }
070        }
071    
072        public Exp getExp() {
073            return exp;
074        }
075    
076        public Calc getCalc() {
077            return calc;
078        }
079    
080        public Object evaluate(Evaluator evaluator) {
081            return calc.evaluate(evaluator);
082        }
083    
084        /**
085         * Returns the ordinals of the dimensions which this expression is
086         * dependent upon. When the cache descriptor is used to generate a cache
087         * key, the key will consist of a member from each of these dimensions.
088         */
089        public int[] getDependentDimensionOrdinals() {
090            return dependentDimensionOrdinals;
091        }
092    
093    }
094    
095    // End ExpCacheDescriptor.java