1 56 package org.objectstyle.cayenne.access.util; 57 58 import java.sql.ResultSet ; 59 import java.sql.ResultSetMetaData ; 60 import java.sql.SQLException ; 61 import java.util.ArrayList ; 62 import java.util.Collection ; 63 import java.util.Iterator ; 64 import java.util.List ; 65 66 import org.objectstyle.cayenne.CayenneRuntimeException; 67 import org.objectstyle.cayenne.access.jdbc.ColumnDescriptor; 68 import org.objectstyle.cayenne.access.types.ExtendedType; 69 import org.objectstyle.cayenne.access.types.ExtendedTypeMap; 70 import org.objectstyle.cayenne.dba.TypesMapping; 71 import org.objectstyle.cayenne.map.DbAttribute; 72 import org.objectstyle.cayenne.map.DbEntity; 73 import org.objectstyle.cayenne.map.ObjAttribute; 74 import org.objectstyle.cayenne.map.ObjEntity; 75 import org.objectstyle.cayenne.map.Procedure; 76 import org.objectstyle.cayenne.map.ProcedureParameter; 77 78 88 public class ResultDescriptor { 89 90 protected String [] names; 92 protected int[] jdbcTypes; 93 protected ExtendedType[] converters; 94 protected int[] idIndexes; 95 protected int[] outParamIndexes; 96 97 protected List dbAttributes = new ArrayList (); 99 protected List javaTypes = new ArrayList (); 100 protected ExtendedTypeMap typesMapping; 101 protected ObjEntity rootEntity; 102 protected boolean indexedIds; 103 104 107 public static ResultDescriptor createDescriptor( 108 ResultSet resultSet, 109 ExtendedTypeMap typeConverters) { 110 ResultDescriptor descriptor = new ResultDescriptor(typeConverters); 111 try { 112 ResultSetMetaData md = resultSet.getMetaData(); 113 int len = md.getColumnCount(); 114 if (len == 0) { 115 throw new CayenneRuntimeException("No columns in ResultSet."); 116 } 117 118 for (int i = 0; i < len; i++) { 119 120 int pos = i + 1; 122 String name = md.getColumnLabel(pos); 123 int sqlType = md.getColumnType(pos); 124 int precision = md.getScale(pos); 125 int length = md.getColumnDisplaySize(pos); 126 if (name == null || name.length() == 0) { 127 name = md.getColumnName(i + 1); 128 129 if (name == null || name.length() == 0) { 130 name = "column_" + (i + 1); 131 } 132 } 133 134 DbAttribute desc = new DbAttribute(); 135 desc.setName(name); 136 desc.setType(md.getColumnType(i + 1)); 137 138 descriptor.addDbAttribute(desc); 139 descriptor.addJavaType(TypesMapping.getJavaBySqlType( 140 sqlType, 141 length, 142 precision)); 143 } 144 } 145 catch (SQLException sqex) { 146 throw new CayenneRuntimeException("Error reading metadata.", sqex); 147 } 148 149 descriptor.index(); 150 return descriptor; 151 } 152 153 158 public static ResultDescriptor createDescriptor( 159 ColumnDescriptor[] columns, 160 ExtendedTypeMap typeConverters) { 161 162 ResultDescriptor descriptor = new ResultDescriptor(typeConverters); 163 164 int len = columns.length; 165 descriptor.names = new String [len]; 166 descriptor.jdbcTypes = new int[len]; 167 descriptor.converters = new ExtendedType[len]; 168 int idWidth = 0; 169 170 for (int i = 0; i < len; i++) { 171 descriptor.names[i] = columns[i].getName(); 172 descriptor.jdbcTypes[i] = columns[i].getJdbcType(); 173 descriptor.converters[i] = typeConverters.getRegisteredType(columns[i] 174 .getJavaClass()); 175 if (columns[i].isPrimaryKey()) { 176 idWidth++; 177 } 178 } 179 180 return descriptor; 181 } 182 183 186 public static ResultDescriptor createDescriptor( 187 Procedure procedure, 188 ExtendedTypeMap typeConverters) { 189 ResultDescriptor descriptor = new ResultDescriptor(typeConverters); 190 Iterator it = procedure.getCallParameters().iterator(); 191 while (it.hasNext()) { 192 descriptor.addDbAttribute(new ProcedureParameterWrapper( 193 (ProcedureParameter) it.next())); 194 } 195 196 descriptor.index(); 197 return descriptor; 198 } 199 200 public ResultDescriptor(ExtendedTypeMap typesMapping) { 201 this(typesMapping, null); 202 } 203 204 public ResultDescriptor(ExtendedTypeMap typesMapping, ObjEntity rootEntity) { 205 this.typesMapping = typesMapping; 206 this.rootEntity = rootEntity; 207 } 208 209 public void addColumns(Collection dbAttributes) { 210 this.dbAttributes.addAll(dbAttributes); 211 } 212 213 public void addDbAttribute(DbAttribute attr) { 214 this.dbAttributes.add(attr); 215 } 216 217 public void addJavaTypes(Collection javaTypes) { 218 this.javaTypes.addAll(javaTypes); 219 } 220 221 public void addJavaType(String javaType) { 222 this.javaTypes.add(javaType); 223 } 224 225 230 protected void indexIds(DbEntity entity) { 231 235 if (!indexedIds) { 236 synchronized (this) { 237 if (!indexedIds) { 238 idIndexes = new int[0]; 239 240 if (entity == null) { 241 return; 242 } 243 244 indexedIds = true; 245 246 int resultWidth = names.length; 247 int[] tmp = new int[resultWidth]; 248 int j = 0; 249 for (int i = 0; i < resultWidth; i++) { 250 DbAttribute attribute = (DbAttribute) entity 251 .getAttribute(names[i]); 252 if (attribute != null && attribute.isPrimaryKey()) { 253 tmp[j++] = i; 254 } 255 } 256 257 if (j > 0) { 258 this.idIndexes = new int[j]; 259 System.arraycopy(tmp, 0, idIndexes, 0, j); 260 } 261 262 } 263 } 264 } 265 } 266 267 public void index() { 268 269 if (javaTypes.size() > 0 && javaTypes.size() != dbAttributes.size()) { 271 throw new IllegalArgumentException ( 272 "DbAttributes and Java type arrays must have the same size."); 273 } 274 275 int resultWidth = dbAttributes.size(); 277 int outWidth = 0; 278 this.names = new String [resultWidth]; 279 this.jdbcTypes = new int[resultWidth]; 280 for (int i = 0; i < resultWidth; i++) { 281 DbAttribute attr = (DbAttribute) dbAttributes.get(i); 282 283 jdbcTypes[i] = attr.getType(); 285 286 if (attr instanceof ProcedureParameterWrapper) { 288 if (((ProcedureParameterWrapper) attr).getParameter().isOutParam()) { 289 outWidth++; 290 } 291 } 292 293 String name = null; 295 if (rootEntity != null) { 296 ObjAttribute objAttr = rootEntity.getAttributeForDbAttribute(attr); 297 if (objAttr != null) { 298 name = objAttr.getDbAttributePath(); 299 } 300 } 301 302 if (name == null) { 303 name = attr.getName(); 304 } 305 306 names[i] = name; 307 } 308 309 if (outWidth == 0) { 310 this.outParamIndexes = new int[0]; 311 } 312 else { 313 this.outParamIndexes = new int[outWidth]; 314 for (int i = 0, j = 0; i < resultWidth; i++) { 315 DbAttribute attr = (DbAttribute) dbAttributes.get(i); 316 jdbcTypes[i] = attr.getType(); 317 318 if (attr instanceof ProcedureParameterWrapper) { 319 if (((ProcedureParameterWrapper) attr).getParameter().isOutParam()) { 320 outParamIndexes[j++] = i; 321 } 322 } 323 } 324 } 325 326 if (javaTypes.size() > 0) { 329 initConvertersFromJavaTypes(); 330 } 331 else if (rootEntity != null) { 332 initConvertersFromMapping(); 333 } 334 else { 335 initDefaultConverters(); 336 } 337 } 338 339 protected void initConvertersFromJavaTypes() { 340 int resultWidth = dbAttributes.size(); 341 this.converters = new ExtendedType[resultWidth]; 342 343 for (int i = 0; i < resultWidth; i++) { 344 converters[i] = typesMapping.getRegisteredType((String ) javaTypes.get(i)); 345 } 346 } 347 348 protected void initDefaultConverters() { 349 int resultWidth = dbAttributes.size(); 350 this.converters = new ExtendedType[resultWidth]; 351 352 for (int i = 0; i < resultWidth; i++) { 353 String javaType = TypesMapping.getJavaBySqlType(jdbcTypes[i]); 354 converters[i] = typesMapping.getRegisteredType(javaType); 355 } 356 } 357 358 protected void initConvertersFromMapping() { 359 360 if (dbAttributes.size() == 0) { 362 throw new IllegalArgumentException ("DbAttributes list is empty."); 363 } 364 365 if (rootEntity == null) { 366 throw new IllegalArgumentException ("Root ObjEntity is null."); 367 } 368 369 int resultWidth = dbAttributes.size(); 370 this.converters = new ExtendedType[resultWidth]; 371 372 for (int i = 0; i < resultWidth; i++) { 373 String javaType = null; 374 DbAttribute attr = (DbAttribute) dbAttributes.get(i); 375 ObjAttribute objAttr = rootEntity.getAttributeForDbAttribute(attr); 376 377 if (objAttr != null) { 382 javaType = objAttr.getType(); 383 } 384 else { 385 javaType = TypesMapping.getJavaBySqlType(attr.getType()); 386 } 387 388 converters[i] = typesMapping.getRegisteredType(javaType); 389 } 390 } 391 392 public ExtendedType[] getConverters() { 393 return converters; 394 } 395 396 399 public int[] getIdIndexes(DbEntity entity) { 400 indexIds(entity); 401 return idIndexes; 402 } 403 404 public int[] getJdbcTypes() { 405 return jdbcTypes; 406 } 407 408 public String [] getNames() { 409 return names; 410 } 411 412 415 public int getResultWidth() { 416 return dbAttributes.size(); 417 } 418 419 public int[] getOutParamIndexes() { 420 return outParamIndexes; 421 } 422 423 static class ProcedureParameterWrapper extends DbAttribute { 427 428 ProcedureParameter parameter; 429 430 ProcedureParameterWrapper(ProcedureParameter parameter) { 431 this.parameter = parameter; 432 } 433 434 public int getMaxLength() { 435 return parameter.getMaxLength(); 436 } 437 438 public int getPrecision() { 439 return parameter.getPrecision(); 440 } 441 442 public int getType() { 443 return parameter.getType(); 444 } 445 446 public String getName() { 447 return parameter.getName(); 448 } 449 450 public Object getParent() { 451 return parameter.getParent(); 452 } 453 454 public ProcedureParameter getParameter() { 455 return parameter; 456 } 457 458 } 459 } | Popular Tags |