001 /* 002 // $Id: //open/mondrian/src/main/mondrian/udf/CurrentDateMemberUdf.java#12 $ 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-2008 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/src/main/mondrian/udf/CurrentDateMemberUdf.java#12 $ 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