1 2 12 package com.versant.core.metadata; 13 14 import com.versant.core.common.Debug; 15 import com.versant.core.common.OID; 16 import com.versant.core.common.State; 17 import com.versant.core.metadata.parser.JdoExtension; 18 19 import java.io.PrintStream ; 20 import java.io.Serializable ; 21 import java.util.HashSet ; 22 import java.util.Set ; 23 24 import com.versant.core.common.BindingSupportImpl; 25 26 30 public final class FetchGroup implements Serializable , Comparable { 31 32 public static final FetchGroupField[] EMPTY_FETCHGROUP_FIELDS = new FetchGroupField[0]; 33 public static final int[] EMPTY_INT_ARRAY = new int[0]; 34 35 38 public static final String DFG_NAME = "default"; 39 42 public static final String DFG_NAME_NO_FAKES = "defaultNoFakes"; 43 46 public static final String RETRIEVE_NAME = "jdoGenieRetrieveFG"; 47 50 public static final String ALL_COLS_NAME = "_jdoall"; 51 55 public static final String REF_NAME = "_jdoref"; 56 60 public static final String DETAIL_NAME = "_jdodetail"; 61 69 public static final String DEL_NAME = "_jdodel"; 70 75 public static final String DEP_NAME = "_jdodep"; 76 81 public static final String REQ_NAME = "_jdoreq"; 82 88 public static final String MANY_TO_MANY_NAME = "_manytomany"; 89 90 93 public String name; 94 97 public ClassMetaData classMetaData; 98 104 public int index = -1; 105 109 public JdoExtension extension; 110 113 public FetchGroupField[] fields; 114 117 public int[] stateFieldNos; 118 121 public FetchGroup superFetchGroup; 122 125 public FetchGroup[] subFetchGroups; 126 132 public boolean sendFieldsOnFetch; 133 137 public boolean hasPrimaryFields; 138 141 public transient StoreFetchGroup storeFetchGroup; 142 143 private boolean canUseParallelFetch; 144 private boolean canUseParallelFetchDone; 145 146 149 public int jdbcTotalCols; 150 151 155 public FetchGroupField crossJoinedCollectionField; 156 157 public FetchGroup(ClassMetaData classMetaData, String name, 158 StoreFetchGroup sfg) { 159 this.classMetaData = classMetaData; 160 this.name = name; 161 this.storeFetchGroup = sfg; 162 if (sfg != null) { 163 sfg.setFetchGroup(this); 164 } 165 } 166 167 171 public int compareTo(Object o) { 172 if (name == DFG_NAME) return -1; 173 return name.compareTo(((FetchGroup)o).name); 174 } 175 176 181 public void add(FieldMetaData fmd) { 182 int n = fields.length; 183 FetchGroupField[] a = new FetchGroupField[n + 1]; 184 System.arraycopy(fields, 0, a, 0, n); 185 a[n] = new FetchGroupField(fmd); 186 fields = a; 187 if (storeFetchGroup != null) { 188 storeFetchGroup.fieldAdded(fmd); 189 } 190 } 191 192 195 public boolean contains(FieldMetaData fmd) { 196 for (int i = fields.length - 1; i >= 0; i--) { 197 FetchGroupField f = fields[i]; 198 if (f.fmd == fmd) return true; 199 } 200 return false; 201 } 202 203 public String toString() { 204 return "FetchGroup@" + System.identityHashCode(this) + ": " + name; 205 } 206 207 210 public void finish() { 211 if (fields != null) { 212 int nf = fields.length; 214 stateFieldNos = new int[nf]; 215 for (int i = nf - 1; i >= 0; i--) { 216 stateFieldNos[i] = fields[i].fmd.stateFieldNo; 217 } 218 } else { 219 fields = EMPTY_FETCHGROUP_FIELDS; 220 stateFieldNos = EMPTY_INT_ARRAY; 221 } 222 223 if (name != null) { 225 ClassMetaData pcmd = classMetaData.pcSuperMetaData; 226 if (pcmd != null) { 227 superFetchGroup = pcmd.getFetchGroup(name); 228 } 229 } 230 231 if (storeFetchGroup != null) { 232 storeFetchGroup.finish(); 233 } 234 } 235 236 241 public int getStateIndex() { 242 return classMetaData.superFetchGroupCount + index; 243 } 244 245 public boolean isRefFG() { 246 return name.equals("_jdoref"); 247 } 248 249 256 public FetchGroup resolve(OID oid, ModelMetaData jmd) { 257 ClassMetaData acmd = oid.getAvailableClassMetaData(); 259 ClassMetaData gcmd = classMetaData; 260 if (gcmd == acmd) return this; 261 for (ClassMetaData cmd = acmd; cmd != gcmd;) { 262 cmd = cmd.pcSuperMetaData; 263 if (cmd == null) { 264 throw BindingSupportImpl.getInstance().internal("Fetch group " + this + " (" + classMetaData + 265 ") does not match OID " + oid + " (" + 266 acmd + ")"); 267 } 268 } 269 return acmd.getFetchGroup(name); 270 } 271 272 277 public FetchGroup resolve(ClassMetaData availableCmd) { 278 if (availableCmd == classMetaData) return this; 279 return availableCmd.getFetchGroup(name); 280 } 281 282 public void dump() { 283 dump(Debug.OUT, ""); 284 } 285 286 public void dump(PrintStream out, String indent) { 287 out.println(indent + "FetchGroup " + this); 288 String is = indent + " "; 289 out.println(is + "classMetaData = " + classMetaData); 290 out.println(is + "index = " + index); 291 out.println(is + "getStateIndex() = " + getStateIndex()); 292 out.println(is + "superFetchGroup = " + superFetchGroup); 293 if (subFetchGroups != null) { 294 for (int i = 0; i < subFetchGroups.length; i++) { 295 FetchGroup sg = subFetchGroups[i]; 296 out.println(is + "subFetchGroups[" + i + "] = " + 297 sg.classMetaData.qname + " " + sg); 298 } 299 } else { 300 out.println(is + "subFetchGroups is null"); 301 } 302 if (fields != null) { 303 for (int i = 0; i < fields.length; i++) { 304 out.println(is + "fields[" + i + "] " + fields[i]); 305 } 306 } 307 if (stateFieldNos != null) { 308 for (int i = 0; i < stateFieldNos.length; i++) { 309 out.println( 310 is + "stateField[" + i + "] no = " + stateFieldNos[i]); 311 } 312 } 313 } 314 315 320 public boolean canUseParallelFetch() { 321 if (canUseParallelFetchDone) return canUseParallelFetch; 322 return canUseParallelFetchImp(new HashSet ()); 323 } 324 325 private boolean canUseParallelFetchImp(Set fgs) { 326 if (fgs.contains(this)) return canUseParallelFetch; 327 328 fgs.add(this); 329 for (int i = fields.length - 1; i >= 0; i--) { 330 FetchGroupField fgf = fields[i]; 331 int cat = fgf.fmd.category; 332 if (cat == MDStatics.CATEGORY_COLLECTION 333 || cat == MDStatics.CATEGORY_MAP) { 334 canUseParallelFetch = true; 335 break; 336 } else if (cat == MDStatics.CATEGORY_REF 337 && fgf.nextFetchGroup.canUseParallelFetchImp(fgs)) { 338 canUseParallelFetch = true; 339 break; 340 } 341 } 342 if (superFetchGroup != null) { 344 superFetchGroup.canUseParallelFetchImp(fgs); 345 if (!canUseParallelFetch) canUseParallelFetch = superFetchGroup.canUseParallelFetch; 347 } 348 349 canUseParallelFetchDone = true; 350 return canUseParallelFetch; 351 } 352 353 357 public boolean hasSecondaryFields() { 358 if (fields != null) { 359 for (int i = fields.length - 1; i >= 0; i--) { 360 if (fields[i].fmd.secondaryField) return true; 361 } 362 } 363 if (subFetchGroups != null) { 364 for (int i = subFetchGroups.length - 1; i >= 0; i--) { 365 if (subFetchGroups[i].hasSecondaryFields()) return true; 366 } 367 } 368 return false; 369 } 370 371 377 public boolean hasPrimaryFields(boolean nonFake) { 378 if (fields == null) return false; 379 for (int i = fields.length - 1; i >= 0; i--) { 380 final FieldMetaData fmd = fields[i].fmd; 381 if (fmd.primaryField && (!nonFake || !fmd.fake)) { 382 return true; 383 } 384 } 385 if (subFetchGroups != null) { 386 for (int i = subFetchGroups.length - 1; i >= 0; i--) { 387 if (subFetchGroups[i].hasPrimaryFields(false)) { 388 return true; 389 } 390 } 391 } 392 return false; 393 } 394 395 399 public void setSendFieldsOnFetch(boolean on) { 400 this.sendFieldsOnFetch = on; 401 if (subFetchGroups != null) { 402 for (int i = subFetchGroups.length - 1; i >= 0; i--) { 403 subFetchGroups[i].setSendFieldsOnFetch(on); 404 } 405 } 406 } 407 408 412 public void setHasPrimaryFields(boolean on) { 413 this.hasPrimaryFields = on; 414 if (subFetchGroups != null) { 415 for (int i = subFetchGroups.length - 1; i >= 0; i--) { 416 subFetchGroups[i].setHasPrimaryFields(on); 417 } 418 } 419 } 420 } 421 422 | Popular Tags |