001 /* 002 // $Id: //open/mondrian/src/main/mondrian/olap/ParameterImpl.java#7 $ 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) 2000-2002 Kana Software, Inc. 007 // Copyright (C) 2001-2007 Julian Hyde and others 008 // All Rights Reserved. 009 // You must accept the terms of that agreement to use this software. 010 // 011 // leonardk, 10 January, 2000 012 */ 013 014 package mondrian.olap; 015 import mondrian.olap.type.Type; 016 import mondrian.olap.type.NumericType; 017 import mondrian.olap.type.StringType; 018 import mondrian.olap.type.MemberType; 019 import mondrian.mdx.MemberExpr; 020 import mondrian.calc.*; 021 import mondrian.calc.impl.GenericCalc; 022 023 /** 024 * Implementation of {@link Parameter}. 025 * 026 * @author jhyde 027 * @version $Id: //open/mondrian/src/main/mondrian/olap/ParameterImpl.java#7 $ 028 * @since Jul 22, 2006 029 */ 030 public class ParameterImpl 031 implements Parameter, ParameterCompilable { 032 033 private final String name; 034 private String description; 035 private Exp defaultExp; 036 private Type type; 037 private ParameterSlot slot = new ParameterSlot() { 038 Object value; 039 public Object getCachedDefaultValue() { 040 throw new UnsupportedOperationException(); 041 } 042 043 public Calc getDefaultValueCalc() { 044 throw new UnsupportedOperationException(); 045 } 046 047 public int getIndex() { 048 throw new UnsupportedOperationException(); 049 } 050 051 public Parameter getParameter() { 052 return ParameterImpl.this; 053 } 054 055 public Object getParameterValue() { 056 return value; 057 } 058 059 public void setCachedDefaultValue(Object value) { 060 throw new UnsupportedOperationException(); 061 } 062 063 public void setParameterValue(Object value) { 064 this.value = value; 065 } 066 067 }; 068 069 public ParameterImpl( 070 String name, 071 Exp defaultExp, 072 String description, 073 Type type) 074 { 075 this.name = name; 076 this.defaultExp = defaultExp; 077 this.description = description; 078 this.type = type; 079 assert defaultExp != null; 080 assert type instanceof StringType || 081 type instanceof NumericType || 082 type instanceof MemberType; 083 } 084 085 public Scope getScope() { 086 return Scope.Statement; 087 } 088 089 public Type getType() { 090 return type; 091 } 092 093 public Exp getDefaultExp() { 094 return defaultExp; 095 } 096 097 public String getName() { 098 return name; 099 } 100 101 public Object getValue() { 102 if (slot == null) { 103 // query has not been resolved yet, so it's not possible for the 104 // parameter to have a value 105 return null; 106 } else { 107 return slot.getParameterValue(); 108 } 109 } 110 111 public void setValue(Object value) { 112 if (value instanceof MemberExpr) { 113 slot.setParameterValue(((MemberExpr) value).getMember()); 114 } else if (value instanceof Literal) { 115 slot.setParameterValue(((Literal) value).getValue()); 116 } else { 117 slot.setParameterValue(value); 118 } 119 } 120 121 public String getDescription() { 122 return description; 123 } 124 125 // For the purposes of type inference and expression substitution, a 126 // parameter is atomic; therefore, we ignore the child member, if any. 127 public Object[] getChildren() { 128 return null; 129 } 130 131 /** 132 * Returns whether this parameter is equal to another, based upon name, 133 * type and value 134 */ 135 public boolean equals(Object other) { 136 if (!(other instanceof ParameterImpl)) { 137 return false; 138 } 139 ParameterImpl that = (ParameterImpl) other; 140 return that.getName().equals(this.getName()) && 141 that.defaultExp.equals(this.defaultExp); 142 } 143 144 public int hashCode() { 145 return Util.hash(getName().hashCode(), defaultExp.hashCode()); 146 } 147 148 /** 149 * Returns whether the parameter can be modified. 150 */ 151 public boolean isModifiable() { 152 return true; 153 } 154 155 public void setDescription(String description) { 156 this.description = description; 157 } 158 159 public void setType(Type type) { 160 assert type instanceof StringType || 161 type instanceof NumericType || 162 type instanceof MemberType; 163 this.type = type; 164 } 165 166 public void setDefaultExp(Exp defaultExp) { 167 assert defaultExp != null; 168 this.defaultExp = defaultExp; 169 } 170 171 public Calc compile(ExpCompiler compiler) { 172 final ParameterSlot slot = compiler.registerParameter(this); 173 if (this.slot != null) { 174 // save previous value 175 slot.setParameterValue(this.slot.getParameterValue()); 176 } 177 this.slot = slot; 178 return new ParameterCalc(slot); 179 } 180 181 /** 182 * Compiled expression which yields the value of a parameter. 183 * It uses a slot which has a unique id within the execution environment. 184 */ 185 private static class ParameterCalc 186 extends GenericCalc { 187 private final ParameterSlot slot; 188 189 public ParameterCalc(ParameterSlot slot) { 190 super(new DummyExp(slot.getParameter().getType())); 191 this.slot = slot; 192 } 193 194 public Calc[] getCalcs() { 195 return new Calc[0]; 196 } 197 198 public Object evaluate(Evaluator evaluator) { 199 Object value = evaluator.getParameterValue(slot); 200 if (slot.getParameterValue() == null) { 201 // save value if not set (setting the default value) 202 slot.setParameterValue(value); 203 } 204 return value; 205 } 206 } 207 } 208 209 // End ParameterImpl.java 210