001    /*
002    // $Id: //open/mondrian/src/main/mondrian/olap/fun/MultiResolver.java#19 $
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) 2002-2005 Kana Software, Inc. and others
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    //
010    // jhyde, Feb 12, 2003
011    */
012    package mondrian.olap.fun;
013    
014    import mondrian.olap.*;
015    
016    /**
017     * A <code>MultiResolver</code> considers several overloadings of the same
018     * function. If one of these overloadings matches the actual arguments, it
019     * calls the factory method {@link #createFunDef}.
020     *
021     * @author jhyde
022     * @since Feb 12, 2003
023     * @version $Id: //open/mondrian/src/main/mondrian/olap/fun/MultiResolver.java#19 $
024     */
025    public abstract class MultiResolver extends FunUtil implements Resolver {
026        private final String name;
027        private final String signature;
028        private final String description;
029        private final String[] signatures;
030        private final Syntax syntax;
031    
032        /**
033         * Creates a <code>MultiResolver</code>.
034         *
035         * @param name Name of function or operator
036         * @param signature Signature of function or operator
037         * @param description Description of function or operator
038         * @param signatures Array of possible signatures, each of which is an
039         *     encoding of the syntactic type, return type, and parameter
040         *     types of this operator. The "Members" operator has a syntactic
041         *     type "pxd" which means "an operator with
042         *     {@link Syntax#Property property} syntax (p) which returns a set
043         *     (x) and takes a dimension (d) as its argument".
044         *     See {@link FunUtil#decodeSyntacticType(String)},
045         *     {@link FunUtil#decodeReturnCategory(String)},
046         *     {@link FunUtil#decodeParameterCategories(String)}.
047         */
048        protected MultiResolver(
049                String name,
050                String signature,
051                String description,
052                String[] signatures) {
053            this.name = name;
054            this.signature = signature;
055            this.description = description;
056            this.signatures = signatures;
057            Util.assertTrue(signatures.length > 0);
058            this.syntax = decodeSyntacticType(signatures[0]);
059            for (int i = 1; i < signatures.length; i++) {
060                Util.assertTrue(decodeSyntacticType(signatures[i]) == syntax);
061            }
062        }
063    
064        public String getName() {
065            return name;
066        }
067    
068        public String getDescription() {
069            return description;
070        }
071    
072        public String getSignature() {
073            return signature;
074        }
075    
076        public Syntax getSyntax() {
077            return syntax;
078        }
079    
080        public String[] getReservedWords() {
081            return emptyStringArray;
082        }
083    
084        public String[] getSignatures() {
085            return signatures;
086        }
087    
088        public FunDef getFunDef() {
089            return null;
090        }
091    
092        public FunDef resolve(
093            Exp[] args, Validator validator, int[] conversionCount)
094        {
095    outer:
096            for (String signature : signatures) {
097                int[] parameterTypes = decodeParameterCategories(signature);
098                if (parameterTypes.length != args.length) {
099                    continue;
100                }
101                for (int i = 0; i < args.length; i++) {
102                    if (!validator.canConvert(
103                        args[i], parameterTypes[i], conversionCount)) {
104                        continue outer;
105                    }
106                }
107                int returnType = decodeReturnCategory(signature);
108                FunDef dummy = createDummyFunDef(this, returnType, args);
109                return createFunDef(args, dummy);
110            }
111            return null;
112        }
113    
114        public boolean requiresExpression(int k) {
115            for (String signature : signatures) {
116                int[] parameterTypes = decodeParameterCategories(signature);
117                if ((k < parameterTypes.length) &&
118                    parameterTypes[k] == Category.Set) {
119                    return false;
120                }
121            }
122            return true;
123        }
124    
125        protected abstract FunDef createFunDef(Exp[] args, FunDef dummyFunDef);
126    }
127    
128    // End MultiResolver.java