1 23 24 29 30 package com.sun.jdo.spi.persistence.support.sqlstore.query.jqlc; 31 32 import java.util.ArrayList ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 import java.util.Map ; 36 import java.util.ResourceBundle ; 37 38 import com.sun.jdo.api.persistence.support.JDOQueryException; 39 import com.sun.jdo.api.persistence.support.JDOFatalInternalException; 40 import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.Type; 41 import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.StringType; 42 import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.PrimitiveType; 43 import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.WrapperClassType; 44 import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.MathType; 45 import com.sun.jdo.spi.persistence.support.sqlstore.query.util.type.DateType; 46 47 import com.sun.jdo.spi.persistence.support.sqlstore.ValueFetcher; 48 import com.sun.jdo.spi.persistence.utility.I18NHelper; 49 import com.sun.jdo.spi.persistence.utility.JavaTypeHelper; 50 import com.sun.jdo.spi.persistence.utility.ParameterInfo; 51 52 58 public class ParameterTable 59 { 60 61 List names = null; 62 63 64 List types = null; 65 66 67 transient List values = null; 68 69 70 private static final String NULL_ = "null"; 72 73 private static final String TRUE_ = "true"; 75 76 private static final String FALSE_ = "false"; 78 79 private static final String OTHER_ = "other"; 81 82 private static final String NOPARAMS_ = "noparams"; 84 85 private static final char PARAMKEY_SEPARATOR = '/'; 86 87 90 static class Unbound { } 91 92 95 static final Unbound unbound = new Unbound(); 96 97 98 protected final static ResourceBundle messages = 99 I18NHelper.loadBundle(ParameterTable.class); 100 101 104 public ParameterTable() 105 {} 106 107 111 public ParameterTable(ParameterTable other) 112 { 113 this.names = other.names; 114 this.types = other.types; 115 this.values = other.values; 116 } 117 118 122 public void add(String name, Type type) 123 { 124 names.add(name); 125 types.add(type); 126 } 127 128 132 public void init() 133 { 134 this.names = new ArrayList (); 135 this.types = new ArrayList (); 136 } 137 138 142 public void initValueHandling() 143 { 144 values = new ArrayList (names.size()); 145 final int size = names.size(); 146 for (int i = 0; i < size; i++) { 147 values.add(unbound); 148 } 149 } 150 151 157 public void setValues(Object [] actualParams) 158 { 159 if (actualParams != null) 160 { 161 for (int i = 0; i < actualParams.length; i++) 162 { 163 Object value = actualParams[i]; 164 defineValueByIndex(i, value); 165 } 166 } 167 } 168 169 172 public void checkUnboundParams() 173 { 174 final int size = values.size(); 175 for (int i = 0; i < size; i++) 176 { 177 if (values.get(i) == unbound) 178 { 179 throw new JDOQueryException( 180 I18NHelper.getMessage(messages, "jqlc.parametertable.checkunboundparams.unboundparam", names.get(i))); 182 } 183 } 184 } 185 186 192 public void setValues(Map actualParams) 193 { 194 if (actualParams != null) 195 { 196 for (Iterator i = actualParams.entrySet().iterator(); i.hasNext();) 197 { 198 Map.Entry actualParam = (Map.Entry )i.next(); 199 String name = (String )actualParam.getKey(); 200 Object value = actualParam.getValue(); 201 defineValueByName(name, value); 202 } 203 } 204 } 205 206 209 public Object getValueByName(String name) 210 { 211 int index = names.indexOf(name); 212 if (index == -1) 213 throw new JDOFatalInternalException(I18NHelper.getMessage( 214 messages, 215 "jqlc.parametertable.getvaluebyname.undefined", name)); 217 218 return getValueByIndex(index); 219 } 220 221 224 public Object getValueByIndex(int index) 225 { 226 if ((index < 0) || (index >= values.size())) 227 throw new JDOFatalInternalException(I18NHelper.getMessage( 228 messages, 229 "jqlc.parametertable.getvaluebyindex.wrongindex", String.valueOf(index))); 231 232 return values.get(index); 233 } 234 235 236 public List getValues() 237 { 238 return values; 239 } 240 241 245 public ValueFetcher getValueFetcher() 246 { 247 return new QueryValueFetcher(values.toArray(new Object [values.size()])); 248 } 249 250 257 public String getKeyForRetrieveDescCache() 258 { 259 StringBuffer key = new StringBuffer (); 260 final int size = values.size(); 261 for (int i = 0; i < size; i++) { 262 if (isInlineType(types.get(i))) 265 return null; 266 267 Object item = values.get(i); 268 if (item == null) { 269 key.append(ParameterTable.NULL_); 270 } 271 else if (item instanceof Boolean ) { 272 if (((Boolean )item).booleanValue()) { 273 key.append(ParameterTable.TRUE_); 274 } else { 275 key.append(ParameterTable.FALSE_); 276 } 277 } else { 278 key.append(ParameterTable.OTHER_); 279 } 280 key.append(ParameterTable.PARAMKEY_SEPARATOR); 281 } 282 283 if (key.length() == 0) { 287 key.append(ParameterTable.NOPARAMS_); 288 } 289 290 return key.toString(); 291 } 292 293 301 public boolean inline(String paramName) 302 { 303 int index = names.indexOf(paramName); 304 Object value = values.get(index); 305 306 if (isInlineType(types.get(index))) return true; 307 308 if (value == null) return true; 309 310 if (value instanceof Boolean ) return true; 311 312 return false; 313 } 314 315 320 private boolean isInlineType(Object type) 321 { 322 if ((type instanceof StringType) || 332 (type instanceof PrimitiveType) || 333 (type instanceof WrapperClassType) || 334 (type instanceof MathType) || 335 (type instanceof DateType)) 336 return false; 337 return true; 338 } 339 340 344 public Integer getIndexForParamName(String paramName) 345 { 346 return new Integer (names.indexOf(paramName)); 347 } 348 349 354 public ParameterInfo getParameterInfoForParamName(String paramName) 355 { 356 return getParameterInfoForParamName(paramName, null); 357 } 358 359 368 public ParameterInfo getParameterInfoForParamName(String paramName, 369 String associatedField) 370 { 371 int index = names.indexOf(paramName); 372 Type type = (Type)types.get(index); 373 return new ParameterInfo(index, type.getEnumType(), associatedField); 374 } 375 376 379 private void defineValueByName(String name, Object value) 380 { 381 int index = names.indexOf(name); 382 if (index == -1) 383 throw new JDOQueryException( 384 I18NHelper.getMessage(messages, "jqlc.parametertable.definevaluebyname.undefinedparam", name)); defineValueByIndex(index, value); 386 } 387 388 391 private void defineValueByIndex(int index, Object value) 392 { 393 if (index < 0) 395 throw new JDOFatalInternalException(I18NHelper.getMessage( 396 messages, 397 "jqlc.parametertable.definevaluebyindex.wrongindex", String.valueOf(index))); 399 400 if (index >= types.size()) 402 throw new JDOQueryException( 403 I18NHelper.getMessage(messages, "jqlc.parametertable.definevaluebyindex.wrongnumberofargs")); 405 Class formalType = ((Type)types.get(index)).getJavaClass(); 407 if (!isCompatibleValue(formalType, value)) 408 { 409 String actualTypeName = ((value==null) ? "<type of null>" : value.getClass().getName()); 410 throw new JDOQueryException( 411 I18NHelper.getMessage(messages, "jqlc.parametertable.definevaluebyindex.typemismatch", actualTypeName, formalType.getName())); 413 } 414 415 values.set(index, value); 417 } 418 419 427 private boolean isCompatibleValue(Class formalType, Object value) 428 { 429 boolean isCompatible = true; 430 431 if (value == null) { 433 isCompatible = !formalType.isPrimitive(); 434 } 435 else { 436 Class actualType = value.getClass(); 437 if (formalType.isPrimitive()) 438 formalType = JavaTypeHelper.getWrapperClass(formalType); 439 440 isCompatible = formalType.isAssignableFrom(actualType); 441 } 442 return isCompatible; 443 } 444 445 } 446 447 | Popular Tags |