001 /*
002 // $Id: //open/mondrian-release/3.0/src/main/mondrian/udf/CurrentDateMemberUdf.java#2 $
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-2007 Julian Hyde and others
007 // All Rights Reserved.
008 // You must accept the terms of that agreement to use this software.
009 */
010 package mondrian.udf;
011
012 import mondrian.olap.*;
013 import mondrian.olap.type.*;
014 import mondrian.spi.UserDefinedFunction;
015 import mondrian.util.*;
016
017 import java.util.*;
018
019 /**
020 * User-defined function <code>CurrentDateMember</code>. Arguments to the
021 * function are as follows:
022 *
023 * <blockquote>
024 * <code>
025 * CurrentDateMember(<Hierarchy>, <FormatString>[, <Find>)
026 * returns <Member>
027 * </code>
028 * </blockquote>
029 *
030 * The function returns the member from the specified hierarchy that matches
031 * the current date, to the granularity specified by the <FormatString>.
032 *
033 * The format string conforms to the format string implemented by
034 * {@link Format}.
035 *
036 * @author Zelaine Fong
037 * @version $Id: //open/mondrian-release/3.0/src/main/mondrian/udf/CurrentDateMemberUdf.java#2 $
038 */
039 public class CurrentDateMemberUdf implements UserDefinedFunction {
040 private Object resultDateMember = null;
041
042 public Object execute(Evaluator evaluator, Argument[] arguments) {
043
044 if (resultDateMember != null) {
045 return resultDateMember;
046 }
047
048 // determine the current date
049 Object formatArg = arguments[1].evaluateScalar(evaluator);
050
051 final Locale locale = Locale.getDefault();
052 final Format format = new Format((String) formatArg, locale);
053 Date currDate = evaluator.getQueryStartTime();
054 String currDateStr = format.format(currDate);
055
056 // determine the match type
057 MatchType matchType;
058 if (arguments.length == 3) {
059 String matchStr = arguments[2].evaluateScalar(evaluator).toString();
060 matchType = Enum.valueOf(MatchType.class, matchStr);
061 } else {
062 matchType = MatchType.EXACT;
063 }
064
065 List<Id.Segment> uniqueNames = Util.parseIdentifier(currDateStr);
066 resultDateMember =
067 evaluator.getSchemaReader().getMemberByUniqueName(
068 uniqueNames, false, matchType);
069 if (resultDateMember != null) {
070 return resultDateMember;
071 }
072
073 // if there is no matching member, return the null member for
074 // the specified dimension/hierarchy
075 Object arg0 = arguments[0].evaluate(evaluator);
076 if (arg0 instanceof Hierarchy) {
077 resultDateMember = ((Hierarchy) arg0).getNullMember();
078 } else {
079 resultDateMember = ((Dimension) arg0).getHierarchy().getNullMember();
080 }
081 return resultDateMember;
082 }
083
084 public String getDescription() {
085 return "Returns the closest or exact member within the specified dimension corresponding to the current date, in the format specified by the format parameter. "
086 + "Format strings are the same as used by the MDX Format function, namely the Visual Basic format strings. See http://www.apostate.com/programming/vb-format.html.";
087 }
088
089 public String getName() {
090 return "CurrentDateMember";
091 }
092
093 public Type[] getParameterTypes() {
094 return new Type[] {
095 new HierarchyType(null, null),
096 new StringType(),
097 new SymbolType()
098 };
099 }
100
101 public String[] getReservedWords() {
102 return new String[] {
103 "EXACT",
104 "BEFORE",
105 "AFTER"
106 };
107 }
108
109 public Type getReturnType(Type[] parameterTypes) {
110 return MemberType.Unknown;
111 }
112
113 public Syntax getSyntax() {
114 return Syntax.Function;
115 }
116
117 private MatchType mapMatchStrToType(String matchStr)
118 {
119 if (matchStr.equals("EXACT")) {
120 return MatchType.EXACT;
121 } else if (matchStr.equals("BEFORE")) {
122 return MatchType.BEFORE;
123 } else {
124 return MatchType.AFTER;
125 }
126 }
127 }
128
129 // End CurrentDateMemberUdf.java