Package mondrian.olap.fun

Source Code of mondrian.olap.fun.PropertiesFunDef

/*
// $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/fun/PropertiesFunDef.java#1 $
// This software is subject to the terms of the Eclipse Public License v1.0
// Agreement, available at the following URL:
// http://www.eclipse.org/legal/epl-v10.html.
// Copyright (C) 2005-2009 Julian Hyde and others
// All Rights Reserved.
// You must accept the terms of that agreement to use this software.
*/
package mondrian.olap.fun;

import mondrian.olap.*;
import mondrian.calc.*;
import mondrian.calc.impl.GenericCalc;
import mondrian.mdx.ResolvedFunCall;

import java.util.List;

/**
* Definition of the <code>Properties</code> MDX function.
*
* @author jhyde
* @version $Id: //open/mondrian-release/3.2/src/main/mondrian/olap/fun/PropertiesFunDef.java#1 $
* @since Mar 23, 2006
*/
class PropertiesFunDef extends FunDefBase {
    static final ResolverImpl Resolver = new ResolverImpl();

    public PropertiesFunDef(
        String name,
        String signature,
        String description,
        Syntax syntax,
        int returnType,
        int[] parameterTypes)
    {
        super(name, signature, description, syntax, returnType, parameterTypes);
    }

    public Calc compileCall(ResolvedFunCall call, ExpCompiler compiler) {
        final MemberCalc memberCalc = compiler.compileMember(call.getArg(0));
        final StringCalc stringCalc = compiler.compileString(call.getArg(1));
        return new GenericCalc(call) {
            public Object evaluate(Evaluator evaluator) {
                return properties(
                        memberCalc.evaluateMember(evaluator),
                        stringCalc.evaluateString(evaluator));
            }

            public Calc[] getCalcs() {
                return new Calc[] {memberCalc, stringCalc};
            }
        };
    }

    static Object properties(Member member, String s) {
        boolean matchCase = MondrianProperties.instance().CaseSensitive.get();
        Object o = member.getPropertyValue(s, matchCase);
        if (o == null) {
            if (!Util.isValidProperty(member, s)) {
                throw new MondrianEvaluationException(
                    "Property '" + s
                    + "' is not valid for member '" + member + "'");
            }
        }
        return o;
    }

    /**
     * Resolves calls to the <code>PROPERTIES</code> MDX function.
     */
    private static class ResolverImpl extends ResolverBase {
        private ResolverImpl() {
            super(
                "Properties",
                "<Member>.Properties(<String Expression>)",
                "Returns the value of a member property.",
                Syntax.Method);
        }

        public FunDef resolve(
            Exp[] args,
            Validator validator,
            List<Conversion> conversions)
        {
            final int[] argTypes = new int[]{Category.Member, Category.String};
            final Exp propertyNameExp = args[1];
            final Exp memberExp = args[0];
            if ((args.length != 2)
                || (memberExp.getCategory() != Category.Member)
                || (propertyNameExp.getCategory() != Category.String))
            {
                return null;
            }
            int returnType = deducePropertyCategory(memberExp, propertyNameExp);
            return new PropertiesFunDef(
                getName(), getSignature(), getDescription(), getSyntax(),
                returnType, argTypes);
        }

        /**
         * Deduces the category of a property. This is possible only if the
         * name is a string literal, and the member's hierarchy is unambigous.
         * If the type cannot be deduced, returns {@link Category#Value}.
         *
         * @param memberExp Expression for the member
         * @param propertyNameExp Expression for the name of the property
         * @return Category of the property
         */
        private int deducePropertyCategory(
            Exp memberExp,
            Exp propertyNameExp)
        {
            if (!(propertyNameExp instanceof Literal)) {
                return Category.Value;
            }
            String propertyName =
                (String) ((Literal) propertyNameExp).getValue();
            Hierarchy hierarchy = memberExp.getType().getHierarchy();
            if (hierarchy == null) {
                return Category.Value;
            }
            Level[] levels = hierarchy.getLevels();
            Property property = lookupProperty(
                levels[levels.length - 1], propertyName);
            if (property == null) {
                // we'll likely get a runtime error
                return Category.Value;
            } else {
                switch (property.getType()) {
                case TYPE_BOOLEAN:
                    return Category.Logical;
                case TYPE_NUMERIC:
                    return Category.Numeric;
                case TYPE_STRING:
                    return Category.String;
                default:
                    throw Util.badValue(property.getType());
                }
            }
        }

        public boolean requiresExpression(int k) {
            return true;
        }
    }
}

// End PropertiesFunDef.java
TOP

Related Classes of mondrian.olap.fun.PropertiesFunDef

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.