1 package org.apache.ojb.broker.metadata; 2 3 17 18 import java.util.Hashtable ; 19 import java.util.Iterator ; 20 import java.util.Vector ; 21 22 import org.apache.commons.lang.builder.ToStringBuilder; 23 import org.apache.ojb.broker.OJBRuntimeException; 24 import org.apache.ojb.broker.PersistenceBrokerException; 25 import org.apache.ojb.broker.core.proxy.ProxyHelper; 26 import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; 27 28 37 public class ObjectReferenceDescriptor extends AttributeDescriptorBase implements XmlCapable 38 { 39 private static final long serialVersionUID = 5561562217150972131L; 40 41 public static final int CASCADE_NONE = 17; 42 public static final int CASCADE_LINK = 19; 43 public static final int CASCADE_OBJECT = 23; 44 45 private Class m_ClassOfItems = null; 46 private Vector m_ForeignKeyFields = new Vector (); 47 private boolean m_CascadeRetrieve = true; 48 private int m_CascadeStore = CASCADE_NONE; 49 private int m_CascadeDelete = CASCADE_NONE; 50 private int m_ProxyPrefetchingLimit = 50; 51 52 private Class m_ProxyOfItems = null; 53 private boolean m_LookedUpProxy = false; 54 private boolean m_OtmDependent = false; 55 56 59 private Hashtable fkFieldMap = new Hashtable (); 60 63 private boolean lazy = false; 64 67 private boolean refresh = false; 68 69 72 public ObjectReferenceDescriptor(ClassDescriptor descriptor) 73 { 74 super(descriptor); 75 } 76 77 80 public Class getItemProxyClass() throws PersistenceBrokerException 81 { 82 if (!m_LookedUpProxy) 83 { 84 m_ProxyOfItems = getClassDescriptor().getRepository(). 85 getDescriptorFor(m_ClassOfItems).getProxyClass(); 86 m_LookedUpProxy = true; 87 } 88 return m_ProxyOfItems; 89 } 90 91 94 public FieldDescriptor[] getForeignKeyFieldDescriptors(ClassDescriptor cld) 95 { 96 FieldDescriptor[] foreignKeyFieldDescriptors; 97 if ((foreignKeyFieldDescriptors = (FieldDescriptor[]) fkFieldMap.get(cld)) == null) 98 { 99 Vector v = getForeignKeyFields(); 101 if (v != null) 104 { 105 Vector ret; 106 if (cld.isInterface()) 107 { 108 Vector extents = cld.getExtentClasses(); 111 Class firstConcreteClass = (Class ) extents.get(0); 112 cld = getClassDescriptor().getRepository().getDescriptorFor(firstConcreteClass); 113 } 114 ret = new Vector (); 115 116 Iterator iter = v.iterator(); 117 while (iter.hasNext()) 118 { 119 Object fk = iter.next(); 120 FieldDescriptor fkfd = null; 121 126 ClassDescriptor tmp = cld; 127 while(tmp != null) 128 { 129 if (fk instanceof Integer ) 130 { 131 Integer index = (Integer ) fk; 132 fkfd = cld.getFieldDescriptorByIndex(index.intValue()); 133 } 134 else 135 { 136 fkfd = tmp.getFieldDescriptorByName((String ) fk); 137 } 138 if(fkfd != null) 139 { 140 break; 141 } 142 else 143 { 144 tmp = tmp.getSuperClassDescriptor(); 145 } 146 } 147 148 if (fkfd == null) 149 { 150 throw new OJBRuntimeException("Incorrect or not found field reference name '" 151 + fk + "' in descriptor " + this + " for class-descriptor '" 152 + (cld != null ? cld.getClassNameOfObject() + "'" : "'null'")); 153 } 154 ret.add(fkfd); 155 } 156 foreignKeyFieldDescriptors = (FieldDescriptor[]) ret.toArray(new FieldDescriptor[ret.size()]); 157 fkFieldMap.put(cld, foreignKeyFieldDescriptors); 158 } 159 } 160 return foreignKeyFieldDescriptors; 161 } 162 163 170 public Object [] getForeignKeyValues(Object obj, ClassDescriptor mif) 171 throws PersistenceBrokerException 172 { 173 FieldDescriptor[] fks = getForeignKeyFieldDescriptors(mif); 174 if(fks.length > 0) obj = ProxyHelper.getRealObject(obj); 176 Object [] result = new Object [fks.length]; 177 for (int i = 0; i < result.length; i++) 178 { 179 FieldDescriptor fmd = fks[i]; 180 PersistentField f = fmd.getPersistentField(); 181 182 188 result[i] = f.get(obj); 189 } 190 return result; 191 } 192 193 196 public Class getItemClass() 197 { 198 return m_ClassOfItems; 199 } 200 201 204 public String getItemClassName() 205 { 206 return this.m_ClassOfItems != null ? this.m_ClassOfItems.getName() : null; 207 } 208 209 213 public void setItemClass(Class c) 214 { 215 m_ClassOfItems = c; 216 } 217 218 221 public Vector getForeignKeyFields() 222 { 223 return m_ForeignKeyFields; 224 } 225 226 229 public void setForeignKeyFields(Vector vec) 230 { 231 m_ForeignKeyFields = vec; 232 } 233 234 237 public void addForeignKeyField(int newId) 238 { 239 if (m_ForeignKeyFields == null) 240 { 241 m_ForeignKeyFields = new Vector (); 242 } 243 m_ForeignKeyFields.add(new Integer (newId)); 244 } 245 246 249 public void addForeignKeyField(String newField) 250 { 251 if (m_ForeignKeyFields == null) 252 { 253 m_ForeignKeyFields = new Vector (); 254 } 255 m_ForeignKeyFields.add(newField); 256 } 257 258 262 public boolean isRefresh() 263 { 264 return refresh; 265 } 266 267 271 public void setRefresh(boolean refresh) 272 { 273 this.refresh = refresh; 274 } 275 276 280 public boolean isLazy() 281 { 282 return lazy; 283 } 284 285 289 public void setLazy(boolean lazy) 290 { 291 this.lazy = lazy; 292 } 293 294 297 public boolean getCascadeRetrieve() 298 { 299 return m_CascadeRetrieve; 300 } 301 302 305 public void setCascadeRetrieve(boolean b) 306 { 307 m_CascadeRetrieve = b; 308 } 309 310 313 public int getCascadingStore() 314 { 315 return m_CascadeStore; 316 } 317 318 321 public void setCascadingStore(int cascade) 322 { 323 m_CascadeStore = cascade; 324 } 325 326 public void setCascadingStore(String value) 327 { 328 setCascadingStore(getCascadeStoreValue(value)); 329 } 330 331 334 public boolean getCascadeStore() 335 { 336 return getCascadingStore() == CASCADE_OBJECT; 337 } 338 339 342 public void setCascadeStore(boolean cascade) 343 { 344 if(cascade) 345 { 346 setCascadingStore(getCascadeStoreValue("true")); 347 } 348 else 349 { 350 setCascadingStore(getCascadeStoreValue("false")); 351 } 352 } 353 354 357 public int getCascadingDelete() 358 { 359 return m_CascadeDelete; 360 } 361 362 365 public void setCascadingDelete(int cascade) 366 { 367 m_CascadeDelete = cascade; 368 } 369 370 public void setCascadingDelete(String value) 371 { 372 setCascadingDelete(getCascadeDeleteValue(value)); 373 } 374 375 378 public boolean getCascadeDelete() 379 { 380 return getCascadingDelete() == CASCADE_OBJECT; 381 } 382 383 386 public void setCascadeDelete(boolean cascade) 387 { 388 if(cascade) 389 { 390 setCascadingDelete(getCascadeDeleteValue("true")); 391 } 392 else 393 { 394 setCascadingDelete(getCascadeDeleteValue("false")); 395 } 396 } 397 398 protected int getCascadeStoreValue(String cascade) 399 { 400 if(cascade.equalsIgnoreCase(RepositoryTags.CASCADE_NONE_STR)) 401 { 402 return CASCADE_NONE; 403 } 404 else if(cascade.equalsIgnoreCase(RepositoryTags.CASCADE_LINK_STR)) 405 { 406 return CASCADE_LINK; 407 } 408 else if(cascade.equalsIgnoreCase(RepositoryTags.CASCADE_OBJECT_STR)) 409 { 410 return CASCADE_OBJECT; 411 } 412 else if(cascade.equalsIgnoreCase("true")) 413 { 414 return CASCADE_OBJECT; 415 } 416 else if(cascade.equalsIgnoreCase("false")) 417 { 418 423 return CASCADE_LINK; 424 } 425 else 426 { 427 throw new OJBRuntimeException("Invalid value! Given value was '" + cascade 428 + "', expected values are: " + RepositoryTags.CASCADE_NONE_STR + ", " 429 + RepositoryTags.CASCADE_LINK_STR + ", " + RepositoryTags.CASCADE_OBJECT_STR 430 + " ('false' and 'true' are deprecated but still valid)"); 431 } 432 } 433 434 protected int getCascadeDeleteValue(String cascade) 435 { 436 if(cascade.equalsIgnoreCase(RepositoryTags.CASCADE_NONE_STR)) 437 { 438 return CASCADE_NONE; 439 } 440 else if(cascade.equalsIgnoreCase(RepositoryTags.CASCADE_LINK_STR)) 441 { 442 return CASCADE_LINK; 443 } 444 else if(cascade.equalsIgnoreCase(RepositoryTags.CASCADE_OBJECT_STR)) 445 { 446 return CASCADE_OBJECT; 447 } 448 else if(cascade.equalsIgnoreCase("true")) 449 { 450 return CASCADE_OBJECT; 451 } 452 else if(cascade.equalsIgnoreCase("false")) 453 { 454 return CASCADE_NONE; 455 } 456 else 457 { 458 throw new OJBRuntimeException("Invalid value! Given value was '" + cascade 459 + "', expected values are: " + RepositoryTags.CASCADE_NONE_STR + ", " 460 + RepositoryTags.CASCADE_LINK_STR + ", " + RepositoryTags.CASCADE_OBJECT_STR 461 + " ('false' and 'true' are deprecated but still valid)"); 462 } 463 } 464 465 public String getCascadeAsString(int cascade) 466 { 467 String result = null; 468 switch(cascade) 469 { 470 case CASCADE_NONE: 471 result = RepositoryTags.CASCADE_NONE_STR; 472 break; 473 case CASCADE_LINK: 474 result = RepositoryTags.CASCADE_LINK_STR; 475 break; 476 case CASCADE_OBJECT: 477 result = RepositoryTags.CASCADE_OBJECT_STR; 478 break; 479 } 480 return result; 481 } 482 483 public int getProxyPrefetchingLimit() 484 { 485 return m_ProxyPrefetchingLimit; 486 } 487 488 public void setProxyPrefetchingLimit(int proxyPrefetchingLimit) 489 { 490 m_ProxyPrefetchingLimit = proxyPrefetchingLimit; 491 } 492 493 496 public boolean getOtmDependent() 497 { 498 return m_OtmDependent; 499 } 500 501 504 public void setOtmDependent(boolean b) 505 { 506 m_OtmDependent = b; 507 } 508 509 515 public boolean isSuperReferenceDescriptor() 516 { 517 return false; 518 } 519 520 524 public boolean hasConstraint() 525 { 526 531 String result = getAttribute("constraint"); 532 return result != null && result.equalsIgnoreCase("true"); 533 } 534 535 539 public void setConstraint(boolean constraint) 540 { 541 addAttribute("constraint", constraint ? "true" : "false"); 542 } 543 544 public String toString() 545 { 546 return new ToStringBuilder(this) 547 .append("cascade_retrieve", getCascadeRetrieve()) 548 .append("cascade_store", getCascadeAsString(m_CascadeStore)) 549 .append("cascade_delete", getCascadeAsString(m_CascadeDelete)) 550 .append("is_lazy", lazy) 551 .append("class_of_Items", m_ClassOfItems) 552 .toString(); 553 } 554 555 558 public String toXML() 559 { 560 RepositoryTags tags = RepositoryTags.getInstance(); 561 String eol = System.getProperty( "line.separator" ); 562 563 StringBuffer result = new StringBuffer ( 1024 ); 565 result.append( " " ); 566 result.append( tags.getOpeningTagNonClosingById( REFERENCE_DESCRIPTOR ) ); 567 result.append( eol ); 568 569 String name = this.getAttributeName(); 572 if( name == null ) 573 { 574 name = RepositoryElements.TAG_SUPER; 575 } 576 result.append( " " ); 577 result.append( tags.getAttribute( FIELD_NAME, name ) ); 578 result.append( eol ); 579 580 result.append( " " ); 582 result.append( tags.getAttribute( REFERENCED_CLASS, this.getItemClassName() ) ); 583 result.append( eol ); 584 585 if( isLazy() ) 587 { 588 result.append( " " ); 589 result.append( tags.getAttribute( PROXY_REFERENCE, "true" ) ); 590 result.append( eol ); 591 result.append( " " ); 592 result.append( tags.getAttribute( PROXY_PREFETCHING_LIMIT, "" + this.getProxyPrefetchingLimit() ) ); 593 result.append( eol ); 594 } 595 596 if( isRefresh() ) 598 { 599 result.append( " " ); 600 result.append( tags.getAttribute( REFRESH, "true" ) ); 601 result.append( eol ); 602 } 603 604 result.append( " " ); 606 result.append( tags.getAttribute( AUTO_RETRIEVE, "" + getCascadeRetrieve() ) ); 607 result.append( eol ); 608 609 result.append( " " ); 611 result.append( tags.getAttribute( AUTO_UPDATE, getCascadeAsString( getCascadingStore() ) ) ); 612 result.append( eol ); 613 614 result.append( " " ); 616 result.append( tags.getAttribute( AUTO_DELETE, getCascadeAsString( getCascadingDelete() ) ) ); 617 result.append( eol ); 618 619 if( getOtmDependent() ) 621 { 622 result.append( " " ); 623 result.append( tags.getAttribute( OTM_DEPENDENT, "true" ) ); 624 result.append( eol ); 625 } 626 627 result.append( " >" ); 629 result.append( eol ); 630 631 for( int i = 0; i < getForeignKeyFields().size(); i++ ) 634 { 635 Object obj = getForeignKeyFields().get( i ); 636 if( obj instanceof Integer ) 637 { 638 String fkId = obj.toString(); 639 result.append( " " ); 640 result.append( tags.getOpeningTagNonClosingById( FOREIGN_KEY ) ); 641 result.append( " " ); 642 result.append( tags.getAttribute( FIELD_ID_REF, fkId ) ); 643 result.append( "/>" ); 644 result.append( eol ); 645 } 646 else 647 { 648 String fk = ( String ) obj; 649 result.append( " " ); 650 result.append( tags.getOpeningTagNonClosingById( FOREIGN_KEY ) ); 651 result.append( " " ); 652 result.append( tags.getAttribute( FIELD_REF, fk ) ); 653 result.append( "/>" ); 654 result.append( eol ); 655 } 656 } 657 658 result.append( " " ); 660 result.append( tags.getClosingTagById( REFERENCE_DESCRIPTOR ) ); 661 result.append( eol ); 662 return result.toString(); 663 } 664 } 665 | Popular Tags |