1 19 package org.openharmonise.rm.resources; 20 21 import java.sql.*; 22 import java.util.*; 23 import java.util.logging.*; 24 25 import org.openharmonise.commons.cache.*; 26 import org.openharmonise.commons.dsi.*; 27 import org.openharmonise.commons.dsi.dml.*; 28 import org.openharmonise.rm.*; 29 import org.openharmonise.rm.dsi.*; 30 import org.openharmonise.rm.factory.*; 31 import org.openharmonise.rm.publishing.*; 32 import org.openharmonise.rm.resources.lifecycle.*; 33 import org.openharmonise.rm.resources.publishing.*; 34 import org.openharmonise.rm.search.Search; 35 import org.w3c.dom.*; 36 37 38 46 public abstract class AbstractParentObject 47 extends AbstractChildObject 48 implements Editable, Publishable, DataStoreObject, Cloneable , EditEventListener { 49 50 54 private static final String CLMN_POSITION = "pos"; 55 56 60 public static final int BRANCH_NODES = 1; 61 62 65 public static final int LEAF_NODES = 2; 66 67 70 public static final int ALL_NODES = 3; 71 72 76 public static final String TAG_CHILDREN = "Children"; 77 78 81 public static final String TAG_CONTENTS = "Contents"; 82 83 86 public static final String TAG_SUBGROUPS = "SubGroups"; 87 88 91 public static final String TAG_ATTACH = "Attach"; 92 93 96 public final String TAG_DETACH = "Detach"; 97 98 103 protected List m_children = null; 104 105 108 protected int m_nMaxIndex = -1; 109 110 115 protected List m_add_children = null; 116 117 122 protected List m_remove_children = null; 123 124 127 protected List m_add_real_children = null; 128 129 132 protected List m_real_children = null; 133 134 138 protected boolean m_bIsChildrenPopulated = false; 139 140 143 protected List m_archivedChildren = null; 144 145 148 protected List m_allArchivedChildren = null; 149 150 155 protected boolean m_bIsContentsChanged = false; 156 157 161 protected boolean m_bIsArchivedChildrenPopulated = false; 162 163 167 protected boolean m_bIsAllArchivedChildrenPopulated = false; 168 169 172 private static Logger m_logger = Logger.getLogger(AbstractParentObject.class.getName()); 173 174 { 176 m_children = new Vector(); 177 m_add_children = new Vector(); 178 m_remove_children = new Vector(); 179 m_add_real_children = new Vector(); 180 m_real_children = new Vector(); 181 m_archivedChildren = new Vector(); 182 m_allArchivedChildren = new Vector(); 183 } 184 188 public AbstractParentObject() { 189 super(); 190 } 191 192 197 public AbstractParentObject(AbstractDataStoreInterface dbintrf) { 198 super(dbintrf); 199 } 200 201 209 public AbstractParentObject( 210 AbstractDataStoreInterface dbintrf, 211 int nId, 212 int nKey, 213 boolean bIsHist) { 214 super(dbintrf, nId, nKey, bIsHist); 215 } 216 217 225 public AbstractParentObject(AbstractDataStoreInterface dbintrf, int nId) { 226 super(dbintrf, nId); 227 } 228 229 232 public String getPath() throws DataAccessException { 233 String sPath = null; 234 235 AbstractParentObject parent = getRealParent(); 236 237 if (parent == null) { 239 sPath = separator; 240 } else { 241 sPath = super.getPath(); 242 } 243 244 return sPath; 245 } 246 247 250 public void markAsNew() throws PopulateException { 251 super.markAsNew(); 252 m_bIsContentsChanged = false; 253 254 clearChildren(); 255 clearArchivedChildren(); 256 } 257 258 261 public Object clone() { 262 AbstractParentObject other = null; 263 264 try { 265 if (m_bIsChildrenPopulated == false) { 266 populateChildrenFromDatabase(); 267 } 268 269 other = (AbstractParentObject) super.clone(); 270 271 if (m_children != null) { 273 other.setChildren(m_children); 274 } 275 276 } catch (InvalidChildException e) { 277 throw new IllegalStateException ( 278 "Problem occured adding child to clone:" 279 + e.getLocalizedMessage()); 280 } catch (PopulateException e) { 281 throw new IllegalStateException ( 282 "Problem occured populating:" + e.getLocalizedMessage()); 283 } 284 285 return other; 286 } 287 288 292 public void clearChildren() { 293 m_bIsChildrenPopulated = false; 294 m_children = null; 295 m_real_children = null; 296 } 297 298 301 public void clear() { 302 super.clear(); 303 m_bIsContentsChanged = false; 304 305 clearChildren(); 306 clearArchivedChildren(); 307 } 308 309 312 public org.w3c.dom.Element publish( 313 Element topEl, 314 HarmoniseOutput xmlDoc, 315 State state) 316 throws PublishException { 317 Element docEl = null; 318 NodeList nodes = null; 319 Text txt = null; 320 String sTagName = topEl.getTagName(); 321 322 if (sTagName.equals(TAG_CONTENTS)) { 323 docEl = xmlDoc.createElement(TAG_CONTENTS); 324 nodes = topEl.getChildNodes(); 325 } else if (sTagName.equals(TAG_SUBGROUPS)) { 326 docEl = xmlDoc.createElement(TAG_SUBGROUPS); 327 328 NodeList nlChildren = topEl.getChildNodes(); 329 Node nTemp = null; 330 331 for (int j = 0; j < nlChildren.getLength(); j++) { 332 nTemp = nlChildren.item(j); 333 334 if (nTemp.getNodeType() != Node.ELEMENT_NODE) { 335 continue; 336 } else if (nTemp.getNodeName().equals(Template.TAG_TEMPLATE)) { 337 List subGroups = null; 338 try { 339 subGroups = this.getChildrenByType(BRANCH_NODES); 340 } catch (DataAccessException e) { 341 throw new PublishException( 342 "Error occured getting branch children", e); 343 } 344 345 int nPageId = -1; 346 347 NodeList pageNodes = 348 ((Element) nTemp).getElementsByTagName( 349 WebPage.TAG_PAGE); 350 351 if (pageNodes.getLength() > 0) { 352 nPageId = 353 Integer.parseInt( 354 ((Element) pageNodes.item(0)).getAttribute( 355 AbstractObject.ATTRIB_ID)); 356 } 357 358 if (subGroups.size() > 0) { 359 Template grpTemplate = null; 360 try { 361 grpTemplate = (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, Template.class.getName(), Integer.parseInt( 362 ((Element) nTemp).getAttribute( 363 AbstractObject.ATTRIB_ID))); 364 } catch (NumberFormatException e) { 365 throw new PublishException(e); 366 } catch (HarmoniseFactoryException e) { 367 throw new PublishException(e); 368 } 369 370 371 if (grpTemplate == null) { 372 throw new PublishException("No template supplied."); 373 } 374 375 String sSubClassName = null; 376 377 NodeList tmpNL = nTemp.getChildNodes(); 378 379 if (tmpNL.getLength() > 0) { 380 boolean bFound = false; 381 int k = 0; 382 383 while ((bFound == false) 384 && (k < tmpNL.getLength())) { 385 if (tmpNL.item(k).getNodeType() 386 == Node.ELEMENT_NODE) { 387 Element tmpEl = (Element) tmpNL.item(k); 388 389 if (tmpEl 390 .getTagName() 391 .equals(WebPage.TAG_PAGE) 392 == false) { 393 bFound = true; 394 try { 395 sSubClassName = 396 HarmoniseObjectFactory.getClassName( 397 this.m_dsi, 398 tmpEl); 399 } catch (HarmoniseFactoryException e) { 400 throw new PublishException( 401 "Error occured getting data from factory",e); 402 } 403 } 404 } 405 406 k++; 407 } 408 } 409 410 if (sSubClassName == null) { 411 try { 412 sSubClassName = 413 HarmoniseObjectFactory.getClassName( 414 this.m_dsi, 415 grpTemplate.getTemplateRootElement()); 416 } catch (HarmoniseFactoryException e) { 417 throw new PublishException( 418 "Error occured getting data from factory",e); 419 } catch (DataAccessException e) { 420 throw new PublishException( 421 "Error occured getting data from Template",e); 422 } 423 } 424 425 try { 426 Class objClass = Class.forName(sSubClassName); 427 428 List matchedSubs = getChildrenByClass(objClass); 429 430 Iterator iter = matchedSubs.iterator(); 431 432 while (iter.hasNext()) { 433 Publishable pObj = (Publishable) iter.next(); 434 435 boolean bPublishable = true; 436 437 PublishFilter filter = state.getPublishFilter(); 438 if (filter != null) { 439 440 bPublishable = 441 filter.allowPublish(this, pObj); 442 } 443 444 if (bPublishable == true) { 445 446 Element grpEl = 447 pObj.publish( 448 grpTemplate, 449 xmlDoc, 450 state); 451 452 if (nPageId > 0) { 453 xmlDoc.addPageIdToLinkNode( 454 state.getLoggedInUser(), 455 grpEl, 456 nPageId); 457 } 458 459 docEl.appendChild(grpEl); 460 } 461 } 462 } catch (DataAccessException e) { 463 throw new PublishException( 464 "Error occured getting data from Template",e); 465 } catch (DOMException e) { 466 throw new PublishException( 467 "DOMException occured",e); 468 } catch (ClassNotFoundException e) { 469 throw new PublishException( 470 "Class not found",e); 471 } 472 } 473 } 474 } 475 } else if (sTagName.equals(TAG_CHILDREN)) { 476 docEl = xmlDoc.createElement(TAG_CHILDREN); 477 478 NodeList nlChildren = topEl.getChildNodes(); 479 Node nTemp = null; 480 boolean bHistorical = false; 481 String sHistorical = topEl.getAttribute(ATTRIB_HISTORICAL); 482 483 if (sHistorical != null) { 484 if (sHistorical.equals("1")) { 485 bHistorical = true; 486 } 487 } 488 489 for (int j = 0; j < nlChildren.getLength(); j++) { 490 nTemp = nlChildren.item(j); 491 492 if (nTemp.getNodeType() != Node.ELEMENT_NODE) { 493 continue; 494 } else if (nTemp.getNodeName().equals(Template.TAG_TEMPLATE)) { 495 List children = null; 496 497 try { 498 if (bHistorical) { 499 children = 500 this.getArchivedChildrenByType(LEAF_NODES); 501 } else { 502 children = this.getChildrenByType(LEAF_NODES); 503 } 504 } catch (DataAccessException e) { 505 throw new PublishException( 506 "Error occured accessing children", e); 507 } 508 509 if (children.size() > 0) { 510 Template template = null; 511 try { 512 template = (Template) HarmoniseObjectFactory.instantiateHarmoniseObject(m_dsi, Template.class.getName(), Integer.parseInt( 513 ((Element) nTemp).getAttribute( 514 AbstractObject.ATTRIB_ID))); 515 } catch (NumberFormatException e) { 516 throw new PublishException(e); 517 } catch (HarmoniseFactoryException e) { 518 throw new PublishException(e); 519 } 520 521 int nPageId = -1; 522 523 NodeList pageNodes = 524 ((Element) nTemp).getElementsByTagName( 525 WebPage.TAG_PAGE); 526 527 if (pageNodes.getLength() > 0) { 528 nPageId = 529 Integer.parseInt( 530 ((Element) pageNodes.item(0)).getAttribute( 531 AbstractObject.ATTRIB_ID)); 532 } 533 534 if (template == null) { 535 throw new PublishException("No template supplied."); 536 } 537 538 Iterator iter = children.iterator(); 539 while (iter.hasNext()) { 540 Publishable pObj = (Publishable) iter.next(); 541 Element chldEl = 542 pObj.publish(template, xmlDoc, state); 543 544 if (nPageId > 0) { 545 xmlDoc.addPageIdToLinkNode( 546 state.getLoggedInUser(), 547 chldEl, 548 nPageId); 549 } 550 551 docEl.appendChild(chldEl); 552 } 553 } 554 } 555 } 556 } else if (sTagName.equals(Search.TAG_LIST)) { 557 Search searchObj; 558 try { 559 searchObj = 560 (Search) HarmoniseObjectFactory.instantiatePublishableObject( 561 m_dsi, 562 topEl, 563 state); 564 searchObj.addConditionGroup(this); 565 566 docEl = searchObj.publish(topEl, xmlDoc, state); 567 } catch (HarmoniseFactoryException e) { 568 throw new PublishException( 569 "Error occured processing List element",e); 570 } 571 572 } else { 573 docEl = super.publish(topEl, xmlDoc, state); 575 } 576 577 Element formEl; 579 Element el; 580 581 if (nodes != null) { 582 for (int i = 0; i < nodes.getLength(); i++) { 583 if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) { 584 continue; 585 } 586 587 formEl = (Element) nodes.item(i); 588 el = publish(formEl, xmlDoc, state); 589 590 if (el != null) { 591 try { 592 docEl.appendChild(el); 593 } catch (org.w3c.dom.DOMException e) { 594 throw new PublishException( 595 el.getTagName() + ":" + e.getMessage()); 596 } 597 } 598 } 599 } 600 601 return docEl; 602 } 603 604 607 public void populate(Element xmlElement, State state) 608 throws PopulateException { 609 Element formEl = xmlElement; 610 String sTagName = formEl.getTagName(); 611 int nId = -1; 612 613 if (sTagName.equals(TAG_CHILDREN)) { 614 String sIdTemp = ""; 615 String sDefault = ""; 616 boolean bDefault = false; 617 618 NodeList nlAttach = formEl.getElementsByTagName(TAG_ATTACH); 619 620 if (nlAttach.getLength() > 0) { 621 NodeList nlAttachObjects = 622 ((Element) nlAttach.item(0)).getChildNodes(); 623 624 for (int j = 0; j < nlAttachObjects.getLength(); j++) { 625 if (nlAttachObjects.item(j).getNodeType() 626 != Node.ELEMENT_NODE) { 627 continue; 628 } 629 630 sIdTemp = 631 ((Element) nlAttachObjects.item(j)).getAttribute( 632 ATTRIB_ID); 633 sDefault = 634 ((Element) nlAttachObjects.item(j)).getAttribute( 635 ATTRIB_DEFAULT); 636 637 if (!sIdTemp.equals("XXXX")) { 638 639 if ((sDefault != null) && sDefault.equals("1")) { 640 bDefault = true; 641 } else { 642 bDefault = false; 643 } 644 645 try { 646 addChild( 647 ( 648 AbstractChildObject) this 649 .getObjectFromFactory( 650 (Element) nlAttachObjects.item(j)), 651 bDefault); 652 } catch (InvalidChildException e) { 653 throw new PopulateException( 654 "Invalid child:" + e.getLocalizedMessage()); 655 } catch (HarmoniseFactoryException e) { 656 throw new PopulateException( 657 "Invalid child:" + e.getLocalizedMessage()); 658 } 659 } 660 } 661 } 662 663 NodeList nlDetach = formEl.getElementsByTagName(TAG_DETACH); 664 665 if (nlDetach.getLength() > 0) { 666 NodeList nlDetachObjects = 667 ((Element) nlDetach.item(0)).getChildNodes(); 668 669 for (int j = 0; j < nlDetachObjects.getLength(); j++) { 670 if (nlDetachObjects.item(j).getNodeType() 671 != Node.ELEMENT_NODE) { 672 continue; 673 } 674 675 sIdTemp = 676 ((Element) nlDetachObjects.item(j)).getAttribute( 677 ATTRIB_ID); 678 679 if (!sIdTemp.equals("XXXX")) { 680 681 try { 682 removeChild( 683 ( 684 AbstractChildObject) this 685 .getObjectFromFactory( 686 (Element) nlDetachObjects.item(j))); 687 } catch (HarmoniseFactoryException e) { 688 throw new PopulateException( 689 "Error occured removing child from parent",e); 690 } 691 } 692 } 693 } 694 } else { 695 super.populate(formEl, state); 696 } 697 } 698 699 706 public void addChild(AbstractChildObject obj) 707 throws InvalidChildException, PopulateException { 708 addChild(-1, obj, false); 709 } 710 711 722 public void addChild(int nIndex, AbstractChildObject obj) 723 throws InvalidChildException, PopulateException { 724 addChild(nIndex, obj, false); 725 } 726 727 738 public void addChild(AbstractChildObject obj, boolean bIsSoftLink) 739 throws InvalidChildException, PopulateException { 740 addChild(-1, obj, bIsSoftLink); 741 } 742 743 759 public void addChild( 760 int nIndex, 761 AbstractChildObject obj, 762 boolean bIsSoftLink) 763 throws InvalidChildException, PopulateException { 764 765 try { 766 if(isLiveVersion() == false) { 767 throw new InvalidChildException("Can't add child to non-live parent"); 768 } 769 } catch (DataAccessException e) { 770 throw new PopulateException(e); 771 } 772 773 if(m_logger.isLoggable(Level.INFO)) { 774 try { 775 m_logger.logp(Level.INFO, this.getClass().getName(), "addChild", "Adding child (id - " + obj.getId() + ",key - " + obj.getKey() + ") to parent (id - " + m_nId + ",key - " + m_nObjectKey + ")"); 776 } catch (DataAccessException e) { 777 m_logger.log(Level.WARNING, "Trouble logging addChild", e); 778 } 779 } 780 781 if (m_add_children == null) { 783 m_add_children = new Vector(); 784 m_add_real_children = new Vector(); 785 } 786 787 if (obj == null) { 789 if(m_logger.isLoggable(Level.INFO)) { 790 m_logger.logp(Level.INFO, this.getClass().getName(), "addChild", "attempt to add null child"); 791 } 792 throw new InvalidChildException("Null object"); 793 } 794 795 if (isValidChild(obj) == false) { 796 797 throw new InvalidChildException( 798 this.getClass().getName() 799 + " can't have " 800 + obj.getClass().getName() 801 + " descendent"); 802 803 804 } 805 806 if (obj.getId() <= 0) { 807 if(m_logger.isLoggable(Level.INFO)) { 808 m_logger.logp(Level.INFO, this.getClass().getName(), "addChild", "Object has invalid id"); 809 } 810 throw new InvalidChildException("Object has invalid id"); 811 } 812 813 if (m_bIsChildrenPopulated == false) { 815 populateChildrenFromDatabase(); 816 } 817 818 try { 819 if (isChild(obj) == false) { 821 822 if(isNameAllowed(obj) == false) { 823 throw new InvalidChildException("Duplicate name - " + obj.getName()); 824 } 825 826 if (obj instanceof AbstractParentObject 827 && obj.getParents().size() > 0) { 828 try { 829 List objpaths = obj.getAllFullPaths(); 830 831 Iterator iter = objpaths.iterator(); 832 833 while (iter.hasNext()) { 834 String sPath = (String ) iter.next(); 835 if (getPath().startsWith(sPath) == true) { 836 throw new InvalidChildException("Child is not allowed, it's an ancestor of this parent"); 837 } 838 } 839 840 } catch (DataAccessException e) { 841 throw new PopulateException( 842 "Problem occured validating child's path",e); 843 } 844 } 845 846 OrderableCachePointer ptr = 847 new OrderableCachePointer( 848 CacheHandler.getInstance(m_dsi).getCachePointer(obj)); 849 850 obj.addEditEventListener(this); 851 852 if (nIndex < 0) { 853 nIndex = getMaxIndex() + 1; 854 setMaxIndex(nIndex); 855 } 856 857 ptr.setPosition(nIndex); 858 859 if (nIndex < getMaxIndex() && getChild(nIndex) != null) { 861 Set sortedSet = getOrderedChildPointers(); 862 Object [] array = sortedSet.toArray(); 863 864 for (int i = nIndex; i < array.length; i++) { 867 OrderableCachePointer tmpPtr = 868 (OrderableCachePointer) array[i]; 869 OrderableCachePointer newPtr = 870 new OrderableCachePointer(tmpPtr); 871 newPtr.setPosition(tmpPtr.getPosition() + 1); 872 if (m_remove_children.contains(tmpPtr) == false) { 873 m_remove_children.add(tmpPtr); 874 } 875 if (m_add_children.contains(newPtr) == false) { 876 m_add_children.add(newPtr); 877 878 Integer intId = 880 new Integer ( 881 ((AbstractChildObject) newPtr.getObject()) 882 .getId()); 883 if (m_real_children.contains(intId)) { 884 m_add_real_children.add(intId); 885 } 886 } 887 } 888 } 889 890 m_add_children.add(ptr); 891 892 if (bIsSoftLink == false) { 893 m_add_real_children.add(new Integer (obj.getId())); 894 } 895 896 m_bIsContentsChanged = true; 897 } 898 } catch (DataAccessException e) { 899 throw new PopulateException( 900 "Error occured accessing current children",e); 901 } catch (CacheException e) { 902 throw new PopulateException( 903 "Error occured getting cache pointer",e); 904 } 905 } 906 907 915 private boolean isNameAllowed(AbstractChildObject obj) throws DataAccessException { 916 boolean bIsAllowed = true; 917 String sName = obj.getName(); 918 919 if(sName != null) { 920 try { 921 if(m_bIsChildrenPopulated == false) { 922 populateChildrenFromDatabase(); 923 } 924 925 Iterator iter = m_children.iterator(); 926 927 while (iter.hasNext() && bIsAllowed == true) { 928 CachePointer ptr = (CachePointer) iter.next(); 929 930 AbstractChildObject child = (AbstractChildObject) ptr.getObject(); 931 932 if(sName.equals(child.getName()) == true) { 933 if(obj.getLiveVersion() != null && obj.getLiveVersion().equals(child) == true) { 934 bIsAllowed = true; 935 } else { 936 bIsAllowed = false; 937 } 938 939 } 940 } 941 } catch (CacheException e) { 942 throw new DataAccessException(e.getLocalizedMessage(),e); 943 } catch (PopulateException e) { 944 throw new DataAccessException(e.getLocalizedMessage(),e); 945 } 946 } else { 947 bIsAllowed = false; 948 } 949 950 951 return bIsAllowed; 952 } 953 954 962 public boolean isChild(AbstractChildObject child) 963 throws DataAccessException { 964 if (m_bIsChildrenPopulated == false) { 965 try { 966 populateChildrenFromDatabase(); 967 } catch (PopulateException e) { 968 throw new DataAccessException( 969 "Error occured populating children",e); 970 } 971 } 972 973 boolean bRtn = false; 974 975 CachePointer ptr = null; 977 try { 978 ptr = CacheHandler.getInstance(m_dsi).getCachePointer(child); 979 } catch (CacheException e) { 980 throw new DataAccessException( 981 "Error occured getting cache pointer:", e); 982 } 983 984 bRtn = m_children.contains(ptr); 985 986 return bRtn; 987 } 988 989 997 public int indexOf(AbstractChildObject child) throws DataAccessException { 998 if (m_bIsChildrenPopulated == false) { 999 try { 1000 populateChildrenFromDatabase(); 1001 } catch (PopulateException e) { 1002 throw new DataAccessException( 1003 "Error occured populating kids:" + e.getLocalizedMessage()); 1004 } 1005 } 1006 1007 OrderableCachePointer ptr = null; 1009 try { 1010 ptr = getCachePointer(child); 1011 } catch (CacheException e) { 1012 throw new DataAccessException( 1013 "Error occured getting cache pointer",e); 1014 } catch (PopulateException e) { 1015 throw new DataAccessException( 1016 "Error occured getting cache pointer",e); 1017 } 1018 1019 int nIndex = -1; 1020 1021 if(m_children.contains(ptr)) { 1022 nIndex = new ArrayList(getOrderedChildPointers()).indexOf(ptr); 1023 } 1024 1025 return nIndex; 1026 } 1027 1028 1036 public void setChildren(List children) 1037 throws InvalidChildException, PopulateException { 1038 1039 if (m_bIsChildrenPopulated == false) { 1040 populateChildrenFromDatabase(); 1041 } 1042 1043 if (children.equals(m_children) == false) { 1044 m_add_children = new Vector(); 1045 m_remove_children = new Vector(); 1046 1047 try { 1048 List curr_children = getChildren(); 1049 1050 Iterator iter = curr_children.iterator(); 1052 1053 while (iter.hasNext()) { 1054 AbstractChildObject tmpChild = (AbstractChildObject) iter.next(); 1055 if(children.contains(tmpChild) == false) { 1056 OrderableCachePointer ptr = getCachePointer(tmpChild); 1057 1058 m_remove_children.add(ptr); 1059 } 1060 } 1061 } catch (DataAccessException e) { 1062 throw new PopulateException( 1063 "Error occured getting cache pointer",e); 1064 } catch (CacheException e) { 1065 throw new PopulateException( 1066 "Error occured getting cache pointer",e); 1067 } 1068 1069 for (int i = 0; i < children.size(); i++) { 1070 1071 AbstractChildObject child; 1072 try { 1073 child = (AbstractChildObject) children.get(i); 1074 } catch (ClassCastException e) { 1075 throw new InvalidChildException(); 1076 } 1077 1078 if (isValidChild(child) == false) { 1079 throw new InvalidChildException(); 1080 } 1081 1082 try { 1083 if(isChild(child) == true) { 1086 int nIndex = indexOf(child); 1087 OrderableCachePointer ptr = getCachePointer(child); 1088 1089 if(nIndex != i && ptr.getPosition() != i) { 1090 m_remove_children.add(ptr); 1091 } else { 1092 continue; 1094 } 1095 } 1096 } catch (DataAccessException e) { 1097 throw new PopulateException( 1098 "Error occured getting cache pointer",e); 1099 } catch (CacheException e) { 1100 throw new PopulateException( 1101 "Error occured getting cache pointer",e); 1102 } 1103 1104 OrderableCachePointer ptr = null; 1106 try { 1107 ptr = 1108 new OrderableCachePointer( 1109 CacheHandler.getInstance(m_dsi).getCachePointer( 1110 child)); 1111 } catch (CacheException e) { 1112 throw new PopulateException( 1113 "Error occured getting cache pointer",e); 1114 } 1115 ptr.setPosition(i); 1116 m_add_children.add(ptr); 1117 1118 Integer intId = new Integer (child.getId()); 1119 1120 if (m_real_children.contains(intId) == true) { 1121 m_add_real_children.add(intId); 1122 } 1123 } 1124 } 1125 1126 m_bIsContentsChanged = true; 1127 } 1128 1129 1135 public void removeChild(AbstractChildObject obj) throws PopulateException { 1136 1137 if(m_logger.isLoggable(Level.INFO)) { 1138 try { 1139 m_logger.logp(Level.INFO,this.getClass().getName(), "removeChild", "Removing child " + obj.getClass().getName() + ", key - " + obj.getKey() + " from parent, key - " + this.getKey()); 1140 } catch (DataAccessException e) { 1141 m_logger.log(Level.WARNING, "Problem logging child removal", e); 1142 } 1143 } 1144 1145 if (m_remove_children == null) { 1146 m_remove_children = new Vector(); 1147 } 1148 1149 String sClassName = obj.getClass().getName(); 1150 1151 if (isValidChild(obj) == true) { 1153 if (m_bIsChildrenPopulated == false) { 1154 populateChildrenFromDatabase(); 1155 } 1156 1157 CachePointer ptr = null; 1159 try { 1160 ptr = CacheHandler.getInstance(m_dsi).getCachePointer(obj); 1161 } catch (CacheException e) { 1162 throw new PopulateException( 1163 "Error occured getting cache pointer",e); 1164 } 1165 1166 int nPtrIndex = m_children.indexOf(ptr); 1167 1168 if (nPtrIndex >= 0) { 1169 OrderableCachePointer ordPtr = 1170 (OrderableCachePointer) m_children.get(nPtrIndex); 1171 1172 if (m_remove_children.contains(ordPtr) == false) { 1173 m_remove_children.add(ordPtr); 1174 } 1175 1176 Set sortedSet = getOrderedChildPointers(); 1177 1178 Object [] array = sortedSet.toArray(); 1179 1180 1183 int nIndex = ordPtr.getPosition(); 1184 if (nIndex >= 0) { 1185 for (int i = nIndex; i < array.length; i++) { 1186 OrderableCachePointer tmpPtr = 1187 (OrderableCachePointer) array[i]; 1188 if (tmpPtr.equals(ordPtr) == false) { 1189 OrderableCachePointer newPtr = 1190 new OrderableCachePointer(tmpPtr); 1191 newPtr.setPosition(tmpPtr.getPosition() - 1); 1192 1193 if (m_remove_children.contains(tmpPtr) == false) { 1194 m_remove_children.add(tmpPtr); 1195 } 1196 1197 if (m_add_children.contains(newPtr) == false) { 1198 m_add_children.add(newPtr); 1199 try { 1201 Integer intId = 1202 new Integer ( 1203 ((AbstractChildObject) newPtr 1204 .getObject()) 1205 .getId()); 1206 if (m_real_children.contains(intId)) { 1207 m_add_real_children.add(intId); 1208 } 1209 } catch (CacheException e) { 1210 throw new PopulateException(e.getLocalizedMessage(),e); 1211 } 1212 } 1213 } 1214 } 1215 setMaxIndex(m_nMaxIndex - 1); 1216 } 1217 m_bIsContentsChanged = true; 1218 } 1219 } 1220 } 1221 1222 1230 public boolean isValidChild(AbstractChildObject childObj) { 1231 1232 if(m_logger.isLoggable(Level.FINER)) { 1233 try { 1234 m_logger.logp(Level.FINER, this.getClass().getName(), "isValidChild", "Validating child - " + childObj.getClass().getName() + " key - " + childObj.getKey()); 1235 } catch (DataAccessException e) { 1236 m_logger.log(Level.WARNING, "Error logging child validation", e); 1237 } 1238 } 1239 1240 List classes = new ArrayList(); 1241 List classNames = getChildClassNames(); 1242 1243 Iterator iter = classNames.iterator(); 1244 boolean bIsValid = false; 1245 while (iter.hasNext() && bIsValid == false) { 1246 String sClassname = (String ) iter.next(); 1247 Class clss; 1248 try { 1249 clss = Class.forName(sClassname); 1250 if(clss.isAssignableFrom(childObj.getClass())) { 1251 bIsValid = true; 1252 } 1253 } catch (ClassNotFoundException e) { 1254 bIsValid = false; 1255 } 1256 1257 } 1258 1259 return bIsValid; 1260 } 1261 1262 1270 public List getChildrenByClass(Class clss) throws DataAccessException { 1271 List rtn = new Vector(); 1272 1273 Iterator iter = getChildren().iterator(); 1274 1275 while (iter.hasNext()) { 1276 Object obj = iter.next(); 1277 if (clss.isInstance(obj) == true) { 1278 rtn.add(obj); 1279 } 1280 } 1281 1282 return rtn; 1283 } 1284 1285 1295 public List getChildrenByType(int nType) throws DataAccessException { 1296 List rtn = new Vector(); 1297 1298 if (isLiveVersion() == false) { 1300 AbstractParentObject parent = 1301 (AbstractParentObject) getLiveVersion(); 1302 1303 if (parent != null) { 1304 rtn = parent.getChildrenByType(nType); 1305 } 1306 } else { 1307 if (m_bIsChildrenPopulated == false) { 1309 try { 1310 populateChildrenFromDatabase(); 1311 } catch (PopulateException e) { 1312 throw new DataAccessException( 1313 "Error occured populating kids:",e); 1314 } 1315 } 1316 1317 rtn = new Vector(); 1318 1319 Iterator iter = m_children.iterator(); 1320 1321 while (iter.hasNext()) { 1324 CachePointer ptr = (CachePointer) iter.next(); 1325 1326 AbstractChildObject child = null; 1327 1328 try { 1329 child = (AbstractChildObject) ptr.getObject(); 1330 } catch (CacheException e) { 1331 throw new DataAccessException( 1332 "Error occured getting object from cache:" 1333 + e.getLocalizedMessage()); 1334 } 1335 1336 if (nType == ALL_NODES) { 1337 rtn.add(child); 1338 } else { 1339 1340 if (nType == BRANCH_NODES 1341 && child instanceof AbstractParentObject) { 1342 rtn.add(child); 1343 } else if ( 1344 nType == LEAF_NODES 1345 && (child instanceof AbstractParentObject) == false) { 1346 rtn.add(child); 1347 } 1348 } 1349 } 1350 } 1351 1352 return rtn; 1353 } 1354 1355 1361 public List getChildren() throws DataAccessException { 1362 1363 if(m_logger.isLoggable(Level.FINE)) { 1364 m_logger.logp(Level.FINE, this.getClass().getName(), "getChildren", "Getting children for object, id - " + m_nId + ", key - " + m_nObjectKey); 1365 } 1366 1367 List rtn = getChildrenByType(ALL_NODES); 1368 1369 return rtn; 1370 } 1371 1372 1378 public AbstractChildObject getChildByName(String sName) 1379 throws DataAccessException { 1380 AbstractChildObject child = null; 1381 1382 if (isLiveVersion() == false) { 1383 AbstractParentObject parent = 1384 (AbstractParentObject) getLiveVersion(); 1385 1386 if (parent != null) { 1387 child = parent.getChildByName(sName); 1388 } 1389 } else { 1390 if (m_bIsChildrenPopulated == false) { 1392 try { 1393 populateChildrenFromDatabase(); 1394 } catch (PopulateException e) { 1395 throw new DataAccessException( 1396 "Error occured populating kids:",e); 1397 } 1398 } 1399 1400 Iterator iter = m_children.iterator(); 1401 1402 try { 1403 while (iter.hasNext() == true && child == null) { 1404 CachePointer tmpPtr = (CachePointer) iter.next(); 1405 AbstractChildObject tmpChild = (AbstractChildObject) tmpPtr.getObject(); 1406 1407 if (tmpChild.getName().equals(sName)) { 1408 child = tmpChild; 1409 } 1410 } 1411 } catch (CacheException e) { 1412 throw new DataAccessException(e.getLocalizedMessage(),e); 1413 } 1414 1415 } 1416 1417 return child; 1418 } 1419 1420 1428 public AbstractChildObject getChild(int nIndex) 1429 throws DataAccessException { 1430 AbstractChildObject child = null; 1431 1432 if (nIndex >= 0) { 1433 try { 1434 if (m_bIsChildrenPopulated == false) { 1435 populateChildrenFromDatabase(); 1436 } 1437 1438 Iterator iter = m_children.iterator(); 1439 boolean bFound = false; 1440 while (iter.hasNext() && bFound == false) { 1441 OrderableCachePointer ptr = 1442 (OrderableCachePointer) iter.next(); 1443 if (ptr.getPosition() == nIndex) { 1444 child = (AbstractChildObject) ptr.getObject(); 1445 bFound = true; 1446 } 1447 } 1448 } catch (PopulateException e) { 1449 throw new DataAccessException("Error populating parent", e); 1450 } catch (CacheException e) { 1451 throw new DataAccessException( 1452 "Error getting object from cache", 1453 e); 1454 } 1455 } 1456 1457 return child; 1458 } 1459 1460 1469 public int getMaxIndex() throws DataAccessException { 1470 if (m_nMaxIndex < 0 && m_bIsChildrenPopulated == false) { 1471 try { 1472 populateChildrenFromDatabase(); 1473 } catch (PopulateException e) { 1474 throw new DataAccessException("Error populating children", e); 1475 } 1476 } 1477 1478 return m_nMaxIndex; 1479 } 1480 1481 1486 private void setMaxIndex(int nMax) { 1487 m_nMaxIndex = nMax; 1488 } 1489 1490 1498 public AbstractChildObject getArchivedChildByName(String sName) 1499 throws DataAccessException { 1500 AbstractChildObject child = null; 1501 List children = getArchivedChildren(); 1502 1503 Iterator iter = children.iterator(); 1504 1505 while (iter.hasNext() == true && child == null) { 1506 AbstractChildObject tmpChild = (AbstractChildObject) iter.next(); 1507 1508 if (tmpChild.getName().equals(sName)) { 1509 child = tmpChild; 1510 } 1511 } 1512 1513 return child; 1514 } 1515 1516 1525 public List getArchivedChildrenByClass(Class clss) 1526 throws DataAccessException { 1527 List rtn = new Vector(); 1528 1529 Iterator iter = getArchivedChildren().iterator(); 1530 1531 while (iter.hasNext()) { 1532 Object obj = iter.next(); 1533 1534 if (clss.isInstance(obj) == true) { 1535 rtn.add(obj); 1536 } 1537 } 1538 1539 return rtn; 1540 } 1541 1542 1551 public List getArchivedChildrenByType(int nType) 1552 throws DataAccessException { 1553 List rtn = null; 1554 1555 if (nType == ALL_NODES) { 1556 rtn = getArchivedChildren(); 1557 } else { 1558 rtn = new Vector(); 1559 1560 List archive = getArchivedChildren(); 1561 1562 Iterator iter = archive.iterator(); 1563 1564 while (iter.hasNext()) { 1566 AbstractChildObject child = (AbstractChildObject) iter.next(); 1567 1568 if (nType == BRANCH_NODES 1569 && child instanceof AbstractParentObject) { 1570 rtn.add(child); 1571 } else if ( 1572 nType == LEAF_NODES 1573 && (child instanceof AbstractParentObject) == false) { 1574 rtn.add(child); 1575 } 1576 } 1577 } 1578 1579 return rtn; 1580 } 1581 1582 1592 public List getAllArchivedChildrenByClass(Class clss) 1593 throws DataAccessException { 1594 List rtn = new Vector(); 1595 1596 Iterator iter = getAllArchivedChildren().iterator(); 1597 1598 while (iter.hasNext()) { 1599 Object obj = iter.next(); 1600 1601 if (clss.isInstance(obj) == true) { 1602 rtn.add(obj); 1603 } 1604 } 1605 1606 return rtn; 1607 } 1608 1609 1619 public List getAllArchivedChildrenByType(int nType) 1620 throws DataAccessException { 1621 List rtn = null; 1622 1623 if (nType == ALL_NODES) { 1624 rtn = this.getAllArchivedChildren(); 1625 } else { 1626 rtn = new Vector(); 1627 1628 List archive = this.getAllArchivedChildren(); 1629 1630 Iterator iter = archive.iterator(); 1631 1632 while (iter.hasNext()) { 1634 AbstractChildObject child = (AbstractChildObject) iter.next(); 1635 1636 if (nType == BRANCH_NODES 1637 && child instanceof AbstractParentObject) { 1638 rtn.add(child); 1639 } else if ( 1640 nType == LEAF_NODES 1641 && (child instanceof AbstractParentObject) == false) { 1642 rtn.add(child); 1643 } 1644 } 1645 } 1646 1647 return rtn; 1648 } 1649 1650 1657 public boolean isTopLevel() { 1658 boolean bIsTopLevel = false; 1659 1660 try { 1661 bIsTopLevel = (this.getParents().size() == 0); 1662 } catch (Exception e) { 1663 m_logger.log(Level.WARNING, e.getMessage(), e); 1664 } 1665 1666 return bIsTopLevel; 1667 } 1668 1669 1672 public Editable changeStatus(Status status) throws EditException { 1673 boolean bIsUnApproved = false; 1674 1675 try { 1676 if (getStatus() == Status.UNAPPROVED) { 1677 bIsUnApproved = true; 1678 } 1679 } catch (DataAccessException e) { 1680 throw new EditException( 1681 "Error occured getting status:" + e.getLocalizedMessage()); 1682 } 1683 1684 if ((bIsUnApproved == true) && (status == Status.APPROVED)) { 1685 AbstractParentObject live = null; 1687 try { 1688 live = (AbstractParentObject) getLiveVersion(); 1689 } catch (DataAccessException e) { 1690 throw new EditException("Error occured finding live version",e); 1691 } 1692 1693 if (live != null) { 1694 try { 1695 List childClassNames = getChildClassNames(); 1696 Iterator iter = childClassNames.iterator(); 1697 UpdateStatement update = new UpdateStatement(); 1698 int nParentKey = live.getKey(); 1699 1700 while (iter.hasNext()) { 1701 String sClassname = (String ) iter.next(); 1702 String sTable = 1703 DatabaseInfo.getInstance().getTableName(sClassname); 1704 1705 ColumnRef colGroup = 1706 getGroupChildJoinColumnRef(sTable, TAG_GROUP); 1707 1708 update.addColumnValue(colGroup, this.m_nObjectKey); 1709 update.addWhereCondition(colGroup, "=", nParentKey); 1710 1711 m_dsi.execute(update); 1712 1713 update.clear(); 1714 } 1715 1716 live.clearChildren(); 1717 1718 } catch (DataStoreException dse) { 1719 throw new EditException( 1720 "Error occured updating DB",dse); 1721 } catch (DataAccessException dae) { 1722 throw new EditException( 1723 "Error accessing data for update",dae); 1724 } 1725 } 1726 } 1727 1728 return super.changeStatus(status); 1729 } 1730 1731 1740 public static List getTopLevelGroups( 1741 AbstractDataStoreInterface dbinterf, 1742 AbstractParentObject grpObj) 1743 throws DataAccessException { 1744 Vector vTopLevelGroups = new Vector(16); 1745 ResultSet rs = null; 1746 1747 try { 1748 String sTable = null; 1749 try { 1750 sTable = 1751 DatabaseInfo.getInstance().getTableName( 1752 grpObj.getClass().getName()); 1753 } catch (DataStoreException e) { 1754 throw new DataAccessException("Error getting table name", e); 1755 } 1756 1757 SelectStatement nestedSelect = new SelectStatement(); 1758 1759 nestedSelect.addSelectColumn( 1760 grpObj.getGroupChildJoinColumnRef(sTable, TAG_CHILDREN)); 1761 1762 SelectStatement select = new SelectStatement(); 1763 1764 select.addSelectColumn( 1765 grpObj.getInstanceColumnRef(ATTRIB_ID, false)); 1766 1767 select.addWhereCondition( 1768 grpObj.getInstanceColumnRef(ATTRIB_KEY, false), 1769 "NOT IN", 1770 nestedSelect); 1771 1772 select.addWhereCondition( 1773 grpObj.getInstanceColumnRef(ATTRIB_TYPE, false), 1774 "=", 1775 grpObj.getClass().getName()); 1776 1777 rs = dbinterf.execute(select); 1778 1779 while (rs.next()) { 1780 Publishable topObj = 1781 HarmoniseObjectFactory.instantiatePublishableObject( 1782 dbinterf, 1783 grpObj.getClass().getName(), 1784 rs.getInt(1)); 1785 vTopLevelGroups.addElement(topObj); 1786 } 1787 } catch (DataStoreException e) { 1788 throw new DataAccessException( 1789 "Error occured building query",e); 1790 } catch (HarmoniseFactoryException e) { 1791 throw new DataAccessException( 1792 "Error occured instantiating object from factory",e); 1793 } catch (SQLException e) { 1794 throw new DataAccessException( 1795 "SQL error",e); 1796 } finally { 1797 if (rs != null) { 1798 try { 1799 rs.close(); 1800 } catch (SQLException e) { 1801 throw new DataAccessException( 1802 "Error occured closing result set",e); 1803 } 1804 } 1805 } 1806 1807 return vTopLevelGroups; 1808 } 1809 1810 1814 abstract public List getChildClassNames(); 1815 1816 1823 public List getArchivedChildren() throws DataAccessException { 1824 try { 1825 1826 if (isLiveVersion() == false) { 1827 AbstractParentObject liveVersion = 1828 (AbstractParentObject) getLiveVersion(); 1829 1830 if (liveVersion != null) { 1831 m_archivedChildren = liveVersion.getArchivedChildren(); 1832 } else if (isHistorical() == true) { 1833 if (m_bIsArchivedChildrenPopulated == false) { 1834 populateArchivedChildrenFromDatabase(false); 1835 } 1836 } else { 1837 m_archivedChildren = new Vector(); 1838 } 1839 } else { 1840 if (m_bIsArchivedChildrenPopulated == false) { 1841 populateArchivedChildrenFromDatabase(false); 1842 } 1843 } 1844 } catch (PopulateException e) { 1845 throw new DataAccessException( 1846 "Error occured populating archived children", 1847 e); 1848 } 1849 1850 return new ArrayList(m_archivedChildren); 1852 } 1853 1854 1857 1858 1867 protected ColumnRef getGroupChildJoinColumnRef( 1868 String sChildTableName, 1869 String sCol) 1870 throws DataStoreException { 1871 ColumnRef colref = null; 1872 1873 StringBuffer sbuf = 1874 new StringBuffer (getDBTableName()).append(JOIN_TO).append( 1875 sChildTableName); 1876 1877 String sTable = sbuf.toString(); 1878 1879 if (sCol.equals(CLMN_CHILD_KEY) == true 1880 || sCol.equals(AbstractParentObject.TAG_CHILDREN)) { 1881 colref = new ColumnRef(sTable, CLMN_CHILD_KEY, ColumnRef.NUMBER); 1882 } else if ( 1883 sCol.equals(CLMN_PARENT_KEY) == true 1884 || sCol.equals(TAG_GROUP) == true) { 1885 colref = new ColumnRef(sTable, CLMN_PARENT_KEY, ColumnRef.NUMBER); 1886 } else if (sCol.equals(CLMN_DATE) == true) { 1887 colref = new ColumnRef(sTable, CLMN_DATE, ColumnRef.DATE); 1888 } else if ( 1889 sCol.equals(CLMN_DEFAULT_LINK) == true 1890 || sCol.equals(ATTRIB_DEFAULT) == true) { 1891 colref = new ColumnRef(sTable, CLMN_DEFAULT_LINK, ColumnRef.NUMBER); 1892 } else if (sCol.equals(CLMN_POSITION) == true) { 1893 colref = new ColumnRef(sTable, CLMN_POSITION, ColumnRef.NUMBER); 1894 } 1895 1896 if (colref == null) { 1897 throw new InvalidColumnReferenceException(); 1898 } 1899 1900 return colref; 1901 } 1902 1903 1906 protected void delete(boolean bDeleteHist) 1907 throws 1908 DataStoreException, 1909 DataAccessException, 1910 EditException, 1911 PopulateException { 1912 1913 try { 1914 List children = getChildren(); 1915 1916 if (children.isEmpty() == false) { 1917 while (children.size() > 0) { 1918 AbstractChildObject child = 1919 (AbstractChildObject) children.get(0); 1920 1921 if (child.getRealParent().equals(this)) { 1922 child.delete(bDeleteHist); 1923 } else { 1924 removeChild(child); 1925 saveNonCoreData(); 1926 } 1927 } 1928 1929 m_children.clear(); 1930 } 1931 } catch (DataAccessException e) { 1932 throw new EditException( 1933 "Error occured accesing data",e); 1934 } catch (PopulateException e) { 1935 throw new EditException( 1936 "Error occured populating object",e); 1937 } catch (DataStoreException e) { 1938 throw new EditException( 1939 "Error occured deleting branch child",e); 1940 } 1941 1942 super.delete(bDeleteHist); 1943 } 1944 1945 1948 protected void saveNonCoreData() throws EditException { 1949 boolean bIsApproved = false; 1950 1951 if(isLockThread() == false) { 1952 throw new EditException("This object has been locked by another thread"); 1953 } 1954 1955 try { 1956 if (getStatus() == Status.APPROVED) { 1957 bIsApproved = true; 1958 } 1959 } catch (DataAccessException e) { 1960 throw new EditException( 1961 "Error occured getting status",e); 1962 } 1963 1964 if (bIsApproved == true && isHistorical() == false) { 1965 try { 1967 populateChildrenFromDatabase(); 1968 } catch (PopulateException e) { 1969 throw new EditException( 1970 "Error occured populating object",e); 1971 } 1972 1973 if (m_bIsContentsChanged == true) { 1975 DeleteStatement delete = new DeleteStatement(); 1977 1978 Iterator remove_iter = 1979 new Vector(m_remove_children).listIterator(); 1980 1981 while (remove_iter.hasNext()) { 1982 try { 1983 OrderableCachePointer ptr = 1984 (OrderableCachePointer) remove_iter.next(); 1985 AbstractChildObject child = 1986 (AbstractChildObject) ptr.getObject(); 1987 1988 if(m_logger.isLoggable(Level.FINER)) { 1989 m_logger.logp(Level.FINER, 1990 this.getClass().getName(), 1991 "saveNonCoreData", 1992 "Deleteing DB child entry for " 1993 + child.getClass().getName() 1994 + ", id - " 1995 + child.getId() 1996 + "posn -" 1997 + ptr.getPosition() 1998 + "for parent ,id - " 1999 + getId()); 2000 } 2001 2002 if (m_add_children.contains(ptr) == true) { 2006 m_add_children.remove(ptr); 2007 } 2008 2009 child.removeParent(this); 2010 child.removeEditEventListener(this); 2011 2012 Integer intId = new Integer (child.getId()); 2013 boolean bIsReal = m_real_children.contains(intId); 2014 2015 delete.addWhereCondition( 2016 getGroupChildJoinColumnRef( 2017 child.getDBTableName(), 2018 TAG_CHILDREN), 2019 "=", 2020 child.getKey()); 2021 delete.addWhereCondition( 2022 getGroupChildJoinColumnRef( 2023 child.getDBTableName(), 2024 TAG_GROUP), 2025 "=", 2026 m_nObjectKey); 2027 delete.addWhereCondition( 2028 getGroupChildJoinColumnRef( 2029 child.getDBTableName(), 2030 CLMN_POSITION), 2031 "=", 2032 ptr.getPosition()); 2033 2034 m_dsi.execute(delete); 2035 2036 delete.clear(); 2037 2038 m_children.remove(ptr); 2039 2040 if (bIsReal == true) { 2041 m_real_children.remove(intId); 2042 } 2043 } catch (DataAccessException e) { 2044 throw new EditException( 2045 "Error accessing child data",e); 2046 } catch (CacheException e) { 2047 throw new EditException( 2048 "Error getting object from cache",e); 2049 } catch (DataStoreException e) { 2050 throw new EditException( 2051 "Error deleting data from DB",e); 2052 } catch (PopulateException e) { 2053 throw new EditException( 2054 "Error removing groups as parent from child",e); 2055 } 2056 } 2057 2058 m_remove_children.clear(); 2060 2061 InsertStatement insert = new InsertStatement(); 2062 2063 Iterator iter = this.m_add_children.listIterator(); 2065 2066 int nDefault = 0; 2067 2068 while (iter.hasNext()) { 2069 try { 2070 OrderableCachePointer ptr = 2071 (OrderableCachePointer) iter.next(); 2072 AbstractChildObject child = 2073 (AbstractChildObject) ptr.getObject(); 2074 2075 if(m_logger.isLoggable(Level.FINER)) { 2076 m_logger.logp(Level.FINER, 2077 this.getClass().getName(), 2078 "saveNonCoreData", 2079 "Adding DB child entry for " 2080 + child.getClass().getName() 2081 + ", id - " 2082 + child.getId() 2083 + " for parent ,id - " 2084 + getId()); 2085 } 2086 2087 Integer intId = new Integer (child.getId()); 2088 boolean bIsReal = m_add_real_children.contains(intId); 2089 2090 if (bIsReal == true) { 2091 child.setRealParent(this); 2092 } else { 2093 child.addParent(this); 2094 } 2095 child.addEditEventListener(this); 2096 2097 insert.addColumnValue( 2098 getGroupChildJoinColumnRef( 2099 child.getDBTableName(), 2100 TAG_CHILDREN), 2101 child.getKey()); 2102 insert.addColumnValue( 2103 getGroupChildJoinColumnRef( 2104 child.getDBTableName(), 2105 TAG_GROUP), 2106 m_nObjectKey); 2107 2108 nDefault = 0; 2109 2110 if (bIsReal == true) { 2111 nDefault = 1; 2112 } 2113 2114 insert.addColumnValue( 2115 getGroupChildJoinColumnRef( 2116 child.getDBTableName(), 2117 AbstractChildObject.CLMN_DEFAULT_LINK), 2118 nDefault); 2119 2120 insert.addColumnValue( 2121 getGroupChildJoinColumnRef( 2122 child.getDBTableName(), 2123 CLMN_POSITION), 2124 ptr.getPosition()); 2125 2126 m_dsi.execute(insert); 2127 2128 insert.clear(); 2129 m_children.add(ptr); 2130 if (bIsReal == true) { 2131 m_real_children.add(intId); 2132 } 2133 2134 iter.remove(); 2135 2136 } catch (DataAccessException e) { 2137 throw new EditException( 2138 "Error occured accessing data",e); 2139 } catch (DataStoreException e) { 2140 throw new EditException( 2141 "Error occured inserting child data to DB",e); 2142 } catch (CacheException e) { 2143 throw new EditException( 2144 "Error occured getting object from cache",e); 2145 } catch (PopulateException e) { 2146 throw new EditException( 2147 "Error occured adding group to child",e); 2148 } 2149 2150 } 2151 2152 m_add_children.clear(); 2154 m_add_real_children.clear(); 2155 2156 m_children = new ArrayList(getOrderedChildPointers()); 2158 2159 m_bIsContentsChanged = false; 2160 } 2161 } 2162 } 2163 2164 2167 protected void fullPopulate() throws PopulateException { 2168 if (m_bIsChildrenPopulated == false) { 2169 populateChildrenFromDatabase(); 2170 } 2171 2172 super.fullPopulate(); 2173 } 2174 2175 2185 protected void addChild(Element el) 2186 throws InvalidChildException, PopulateException { 2187 2188 AbstractChildObject obj; 2189 try { 2190 obj = 2191 ( 2192 AbstractChildObject) HarmoniseObjectFactory 2193 .instantiatePublishableObject( 2194 this.m_dsi, 2195 el, 2196 null); 2197 2198 this.addChild(obj); 2199 } catch (HarmoniseFactoryException e) { 2200 throw new PopulateException( 2201 "Problem occured creating object from XML element",e); 2202 } 2203 2204 } 2205 2206 2213 protected void removeChild(Element el) throws PopulateException { 2214 2215 try { 2216 AbstractChildObject obj = 2217 ( 2218 AbstractChildObject) HarmoniseObjectFactory 2219 .instantiatePublishableObject( 2220 this.m_dsi, 2221 el, 2222 null); 2223 2224 removeChild(obj); 2225 } catch (HarmoniseFactoryException e) { 2226 throw new PopulateException( 2227 "Error occured creating object from XML",e); 2228 } 2229 2230 } 2231 2232 2235 2236 2240 private void clearArchivedChildren() { 2241 m_archivedChildren = null; 2242 m_allArchivedChildren = null; 2243 m_bIsArchivedChildrenPopulated = false; 2244 m_bIsAllArchivedChildrenPopulated = false; 2245 } 2246 2247 2254 private List getAllArchivedChildren() throws DataAccessException { 2255 try { 2256 if (isPopulated() == false) { 2257 populateFromDatabase(); 2258 } 2259 2260 if (isLiveVersion() == false) { 2261 AbstractParentObject liveVersion = 2262 (AbstractParentObject) getLiveVersion(); 2263 2264 if (liveVersion != null) { 2265 m_allArchivedChildren = 2266 liveVersion.getAllArchivedChildren(); 2267 } else { 2268 m_allArchivedChildren = new Vector(); 2269 } 2270 } else { 2271 if (m_bIsAllArchivedChildrenPopulated == false) { 2272 populateArchivedChildrenFromDatabase(true); 2273 } 2274 } 2275 } catch (PopulateException e) { 2276 throw new DataAccessException( 2277 "Error occured populating archived children",e); 2278 } 2279 2280 return new ArrayList(m_allArchivedChildren); 2281 } 2282 2283 2292 private Object getObjectFromFactory(Element el) 2293 throws HarmoniseFactoryException { 2294 return (Object ) HarmoniseObjectFactory.instantiatePublishableObject( 2295 this.m_dsi, 2296 el, 2297 null); 2298 } 2299 2300 2308 private boolean isLeafChild(AbstractChildObject child) 2309 throws DataAccessException { 2310 if (m_bIsChildrenPopulated == false) { 2312 try { 2313 populateChildrenFromDatabase(); 2314 } catch (PopulateException e) { 2315 throw new DataAccessException( 2316 "Error occured populating kids:" + e.getLocalizedMessage()); 2317 } 2318 } 2319 2320 return ( 2321 m_children.contains(child) 2322 && (child instanceof AbstractParentObject) == false); 2323 } 2324 2325 2330 private synchronized void populateChildrenFromDatabase() throws PopulateException { 2331 if (m_bIsChildrenPopulated == false) { 2332 2333 if(m_logger.isLoggable(Level.FINER)) { 2334 m_logger.logp(Level.FINER, this.getClass().getName(), "populateChildrenFromDatabase", "populating children for parent, id - " + m_nId + ", key - " + m_nObjectKey); 2335 } 2336 2337 if (isPopulated() == false) { 2338 populateFromDatabase(); 2339 } 2340 2341 if (m_children == null) { 2342 m_children = new Vector(); 2343 } 2344 2345 if (m_real_children == null) { 2346 m_real_children = new Vector(); 2347 } 2348 2349 List childClassNames = getChildClassNames(); 2350 2351 if ((this.m_nId != AbstractObject.NOTDBSAVED_ID) 2352 && childClassNames != null 2353 && childClassNames.size() > 0) { 2354 SelectStatement select = new SelectStatement(); 2355 2356 Iterator iter = childClassNames.iterator(); 2357 while (iter.hasNext()) { 2358 2359 ColumnRef idColref; 2360 ColumnRef typeColref; 2361 ColumnRef linkColref; 2362 try { 2363 String sChildClassName = (String ) iter.next(); 2364 2365 String sChildTableName = null; 2366 2367 try { 2368 sChildTableName = 2369 DatabaseInfo.getInstance().getTableName( 2370 sChildClassName); 2371 } catch (DataStoreException e) { 2372 throw new PopulateException( 2373 "Error getting table name", 2374 e); 2375 } 2376 2377 idColref = getColumnRef(sChildClassName, ATTRIB_ID); 2378 2379 linkColref = 2380 getGroupChildJoinColumnRef( 2381 sChildTableName, 2382 AbstractChildObject.CLMN_DEFAULT_LINK); 2383 typeColref = getColumnRef(sChildClassName, ATTRIB_TYPE); 2384 2385 select.addSelectColumn(idColref); select.addSelectColumn(linkColref); select.addSelectColumn(typeColref); ColumnRef posCol = 2389 getGroupChildJoinColumnRef( 2390 sChildTableName, 2391 CLMN_POSITION); 2392 select.addSelectColumn(posCol); 2394 Collection coreRefs = 2395 AbstractParentObject.getCoreColumnRefs( 2396 sChildClassName); 2397 Iterator resIter = coreRefs.iterator(); 2398 2399 while (resIter.hasNext() == true) { 2400 select.addSelectColumn((ColumnRef) resIter.next()); 2401 } 2402 2403 select.setOrderBy(posCol); 2404 2405 ColumnRef joinColumn1 = 2407 getColumnRef( 2408 sChildClassName, 2409 AbstractObject.ATTRIB_KEY); 2410 ColumnRef joinColumn2 = 2411 getGroupChildJoinColumnRef( 2412 sChildTableName, 2413 TAG_CHILDREN); 2414 2415 select.addJoinCondition(joinColumn1, joinColumn2); 2416 2417 ColumnRef whereColumn = 2418 getGroupChildJoinColumnRef( 2419 sChildTableName, 2420 TAG_GROUP); 2421 2422 select.addWhereCondition( 2423 whereColumn, 2424 "=", 2425 m_nObjectKey); 2426 select.setOrderBy(joinColumn2); 2427 } catch (DataStoreException e) { 2428 throw new PopulateException( 2429 "Error occured building query",e); 2430 } 2431 2432 ResultSet rs = null; 2433 2434 try { 2435 rs = m_dsi.execute(select); 2436 2437 int nId = 0; 2438 2439 while (rs.next()) { 2440 nId = rs.getInt(idColref.getColumn()); 2441 2442 AbstractProfiledObject tmpChild = 2443 ( 2444 AbstractProfiledObject) HarmoniseObjectFactory 2445 .instantiatePublishableObject( 2446 this.m_dsi, 2447 rs.getString(typeColref.getColumn()), 2448 nId); 2449 2450 tmpChild.addEditEventListener(this); 2451 2452 if (tmpChild.isPopulated() == false) { 2453 tmpChild.populateFromResultSetRow(rs, select); 2454 } 2455 2456 OrderableCachePointer ptr = null; 2457 2458 ptr = 2459 new OrderableCachePointer( 2460 CacheHandler.getInstance( 2461 m_dsi).getCachePointer( 2462 tmpChild)); 2463 2464 int nIndex = rs.getInt(4); 2465 2466 if (nIndex > m_nMaxIndex) { 2467 m_nMaxIndex = nIndex; 2468 } 2469 2470 ptr.setPosition(nIndex); 2471 2472 m_children.add(ptr); 2473 2474 if (rs.getBoolean(linkColref.getColumn())) { 2475 m_real_children.add(new Integer (nId)); 2476 } 2477 } 2478 2479 m_children = new ArrayList(getOrderedChildPointers()); 2481 } catch (HarmoniseFactoryException e) { 2482 throw new PopulateException( 2483 "Error occured instantiating object from factory",e); 2484 } catch (DataStoreException e) { 2485 throw new PopulateException( 2486 "Error occured processing query",e); 2487 } catch (SQLException e) { 2488 throw new PopulateException( 2489 "SQL error",e); 2490 } catch (CacheException e) { 2491 throw new PopulateException( 2492 "Error occured getting cache pointer",e); 2493 } finally { 2494 if (rs != null) { 2495 try { 2496 rs.close(); 2497 } catch (SQLException e) { 2498 throw new PopulateException( 2499 "Error occured closing result set",e); 2500 } 2501 } 2502 2503 m_bIsChildrenPopulated = true; 2504 } 2505 select.clear(); 2506 } 2507 2508 } else { 2509 m_bIsChildrenPopulated = true; 2510 } 2511 } 2512 } 2513 2514 2521 private void populateArchivedChildrenFromDatabase(boolean bAllChildren) 2522 throws PopulateException { 2523 2524 List archive = null; 2525 2526 if (bAllChildren == true) { 2527 if (m_allArchivedChildren == null) { 2528 m_allArchivedChildren = new Vector(); 2529 } 2530 2531 archive = m_allArchivedChildren; 2532 } else { 2533 if (m_archivedChildren == null) { 2534 m_archivedChildren = new Vector(); 2535 } 2536 2537 archive = m_archivedChildren; 2538 } 2539 2540 List children = null; 2541 try { 2542 children = getChildren(); 2543 } catch (DataAccessException e) { 2544 throw new PopulateException( 2545 "Error occured getting children",e); 2546 } 2547 2548 List classNames = this.getChildClassNames(); 2550 2551 Iterator iter = classNames.iterator(); 2552 2553 while (iter.hasNext()) { 2554 2555 String sClassname = (String ) iter.next(); 2556 Class childClass = null; 2557 try { 2558 childClass = Class.forName(sClassname); 2559 } catch (ClassNotFoundException e) { 2560 throw new PopulateException( 2561 "Error occured getting class for child",e); 2562 } 2563 2564 SelectStatement select = new SelectStatement(); 2565 2566 try { 2567 ColumnRef histIdColumn = 2568 AbstractObject.getColumnRef( 2569 sClassname, 2570 AbstractObject.ATTRIB_ID, 2571 true); 2572 2573 select.addSelectColumn(histIdColumn); 2574 select.addSelectColumn( 2575 AbstractObject.getColumnRef( 2576 sClassname, 2577 AbstractObject.TAG_NAME, 2578 true)); 2579 select.addSelectColumn( 2580 AbstractEditableObject.getColumnRef( 2581 sClassname, 2582 AbstractEditableObject.TAG_VERSION, 2583 true)); 2584 select.addSelectColumn( 2585 AbstractEditableObject.getColumnRef( 2586 sClassname, 2587 AbstractEditableObject.TAG_VERSION_COMMENT, 2588 true)); 2589 select.addSelectColumn( 2590 AbstractEditableObject.getColumnRef( 2591 sClassname, 2592 AbstractEditableObject.TAG_VERSION_DATE, 2593 true)); 2594 select.addSelectColumn( 2595 AbstractEditableObject.getColumnRef( 2596 sClassname, 2597 AbstractObject.ATTRIB_KEY, 2598 true)); 2599 2600 ColumnRef whereColumn = 2601 AbstractChildObject.getColumnRef( 2602 sClassname, 2603 AbstractChildObject.TAG_PATH, 2604 true); 2605 2606 if (bAllChildren) { 2607 select.addWhereCondition( 2608 whereColumn, 2609 "LIKE", 2610 getFullPath() + "%"); 2611 } else { 2612 select.addWhereCondition(whereColumn, "=", getFullPath()); 2613 } 2614 2615 ColumnRef liveIdColumn = 2616 AbstractObject.getColumnRef(sClassname, ATTRIB_ID); 2617 2618 SelectStatement nestedSelect = new SelectStatement(); 2620 2621 nestedSelect.addSelectColumn(liveIdColumn); 2622 2623 select.addWhereCondition(histIdColumn, "not in", nestedSelect); 2624 2625 ColumnRef parentIdColumn = 2626 AbstractEditableObject.getColumnRef( 2627 sClassname, 2628 TAG_LIVE_VERSION, 2629 false); 2630 2631 SelectStatement nestedSelect2 = new SelectStatement(); 2633 2634 nestedSelect2.addSelectColumn(parentIdColumn); 2635 2636 select.addWhereCondition(histIdColumn, "not in", nestedSelect2); 2637 2638 select.addOrderBy( 2639 AbstractObject.getColumnRef( 2640 sClassname, 2641 AbstractObject.ATTRIB_KEY, 2642 true),SelectStatement.ORDER_DESCENDING); 2643 2644 } catch (DataAccessException e) { 2645 throw new PopulateException("Error occured accessing data", e); 2646 } catch (DataStoreException e) { 2647 throw new PopulateException("Error occured building query", e); 2648 } 2649 2650 ResultSet rs = null; 2651 2652 try { 2653 rs = m_dsi.execute(select); 2654 2655 Vector ids = new Vector(); 2656 2657 while (rs.next()) { 2658 int nId = rs.getInt(1); 2659 Integer intId = new Integer (nId); 2660 2661 if (ids.contains(intId) == false) { 2662 AbstractChildObject obj = 2663 (AbstractChildObject) childClass.newInstance(); 2664 2665 obj.setDataStoreInterface(m_dsi); 2666 obj.setId(nId); 2667 obj.setHistorical(true); 2668 2669 obj.populateFromResultSetRow(rs, select); 2670 2671 obj.setRealParent(this); 2672 obj.addEditEventListener(this); 2673 2674 archive.add(obj); 2675 ids.add(intId); 2676 } 2677 } 2678 } catch (SQLException e) { 2679 throw new PopulateException( 2680 "SQL error",e); 2681 } catch (IllegalArgumentException e) { 2682 throw new PopulateException( 2683 "Illegal argument error",e); 2684 } catch (InstantiationException e) { 2685 throw new PopulateException( 2686 "Instantiation error",e); 2687 } catch (IllegalAccessException e) { 2688 throw new PopulateException( 2689 "Illegal access error",e); 2690 } catch (DataStoreException e) { 2691 throw new PopulateException( 2692 "Error occured processing query",e); 2693 } finally { 2694 if (rs != null) { 2695 try { 2696 rs.close(); 2697 } catch (SQLException e) { 2698 throw new PopulateException( 2699 "Error occured closing result set",e); 2700 } 2701 } 2702 2703 if (bAllChildren) { 2704 m_bIsAllArchivedChildrenPopulated = true; 2705 } else { 2706 m_bIsArchivedChildrenPopulated = true; 2707 } 2708 } 2709 2710 } 2711 } 2712 2713 2716 public void workflowObjectArchived(EditEvent event) { 2717 Editable source = (Editable) event.getSource(); 2718 2719 if (source instanceof AbstractChildObject) { 2721 AbstractChildObject childSource = (AbstractChildObject) source; 2722 2723 if (isValidChild(childSource) == true) { 2729 2730 if (m_bIsArchivedChildrenPopulated == true) { 2731 m_bIsArchivedChildrenPopulated = false; 2732 m_archivedChildren.clear(); 2733 } 2734 2735 if (m_bIsAllArchivedChildrenPopulated == true) { 2736 m_bIsAllArchivedChildrenPopulated = false; 2737 m_allArchivedChildren.clear(); 2738 } 2739 } 2740 2741 } 2742 2743 super.workflowObjectArchived(event); 2744 2745 } 2746 2747 2750 public void workflowObjectLocked(EditEvent event) { 2751 super.workflowObjectLocked(event); 2752 } 2753 2754 2757 public void workflowObjectReactivated(EditEvent event) { 2758 Object src = event.getSource(); 2759 2760 if (src instanceof AbstractChildObject) { 2763 2764 if (m_bIsAllArchivedChildrenPopulated == true) { 2765 m_allArchivedChildren.remove(src); 2766 } 2767 2768 if (m_bIsArchivedChildrenPopulated == true) { 2769 m_archivedChildren.remove(src); 2770 } 2771 } 2772 2773 super.workflowObjectReactivated(event); 2774 } 2775 2776 2779 public void workflowObjectSaved(EditEvent event) { 2780 super.workflowObjectSaved(event); 2781 } 2782 2783 2786 public void workflowObjectStatusChanged(EditEvent event) { 2787 if (event.getSource() instanceof AbstractChildObject) { 2791 clearChildren(); 2792 } 2793 2794 super.workflowObjectStatusChanged(event); 2795 } 2796 2797 2800 public void workflowObjectUnlocked(EditEvent event) { 2801 super.workflowObjectUnlocked(event); 2802 2803 } 2804 2805 2813 private class OrderableCachePointer extends CachePointer { 2814 2815 2818 private int m_nPosition = -1; 2819 2820 2823 public OrderableCachePointer() { 2824 super(); 2825 } 2826 2827 2833 public OrderableCachePointer(CachePointer ptr) { 2834 this.setCache(ptr.getCache()); 2835 this.setKey(ptr.getKey()); 2836 } 2837 2838 2845 public OrderableCachePointer(Object key, AbstractCache cache) { 2846 super(key, cache); 2847 } 2848 2849 2854 public int getPosition() { 2855 return m_nPosition; 2856 } 2857 2858 2863 public void setPosition(int i) { 2864 m_nPosition = i; 2865 } 2866 2867 2870 public String toString() { 2871 String result = null; 2872 2873 StringBuffer strbuf = new StringBuffer (); 2874 2875 try { 2876 strbuf.append( 2877 ((AbstractChildObject) getObject()).getName()).append( 2878 " ").append( 2879 m_nPosition); 2880 result = strbuf.toString(); 2881 } catch (DataAccessException e) { 2882 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 2883 } catch (CacheException e) { 2884 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 2885 } 2886 2887 return result; 2888 } 2889 2890 2901 public CachePointer getCachePointer() { 2902 return new CachePointer(this.getKey(), this.getCache()); 2903 } 2904 2905 2908 public boolean equals(Object obj) { 2909 boolean bEq = false; 2910 2911 if (obj instanceof CachePointer) { 2912 CachePointer ptr = (CachePointer) obj; 2913 2914 if (this == ptr) { 2915 bEq = true; 2916 } else if ( 2917 ptr.getCache().equals(m_cache) == true 2918 && ptr.getKey().equals(m_cache_key) == true) { 2919 bEq = true; 2920 2921 if (ptr instanceof OrderableCachePointer 2922 && bEq == true 2923 && ((OrderableCachePointer) ptr).m_nPosition 2924 != this.m_nPosition) { 2925 bEq = false; 2926 } 2927 } 2928 } 2929 2930 return bEq; 2931 } 2932 2933 } 2934 2935 2943 private class OrderableCachePointerComparator implements Comparator { 2944 2945 2948 public int compare(Object arg1, Object arg2) { 2949 OrderableCachePointer ptr1 = (OrderableCachePointer) arg1; 2950 OrderableCachePointer ptr2 = (OrderableCachePointer) arg2; 2951 2952 int nCompare = 0; 2953 int nPos1 = ptr1.getPosition(); 2954 int nPos2 = ptr2.getPosition(); 2955 2956 if (nPos1 != nPos2) { 2957 2958 if (nPos2 == -1) { 2961 nCompare = 1; 2962 } else { 2963 nCompare = nPos1 - nPos2; 2964 } 2965 2966 } else { 2967 2968 try { 2969 AbstractChildObject child1 = 2970 (AbstractChildObject) ptr1.getObject(); 2971 AbstractChildObject child2 = 2972 (AbstractChildObject) ptr2.getObject(); 2973 2974 nCompare = child1.compareTo(child2); 2975 } catch (CacheException e) { 2976 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 2977 nCompare = 0; 2978 } 2979 } 2980 2981 return nCompare; 2982 } 2983 2984 } 2985 2986 2991 private Set getOrderedChildPointers() { 2992 TreeSet sortedSet = new TreeSet(new OrderableCachePointerComparator()); 2993 sortedSet.addAll(m_children); 2994 2995 return sortedSet; 2996 } 2997 2998 3009 private OrderableCachePointer getCachePointer(AbstractChildObject child) throws PopulateException, CacheException { 3010 if(m_bIsChildrenPopulated == false) { 3011 populateChildrenFromDatabase(); 3012 } 3013 OrderableCachePointer result = null; 3014 Iterator iter = m_children.iterator(); 3015 boolean bFound = false; 3016 while (iter.hasNext() && bFound == false) { 3017 OrderableCachePointer ptr = (OrderableCachePointer) iter.next(); 3018 3019 if(((AbstractChildObject)ptr.getObject()).getId() == child.getId() && 3020 ((AbstractChildObject)ptr.getObject()).getClass().equals(child.getClass())) { 3021 bFound = true; 3022 result = ptr; 3023 } 3024 } 3025 3026 return result; 3027 } 3028 3029 3032 public ColumnRef getInstanceColumnRef(String sColumn, boolean bIsHist) 3033 throws DataStoreException { 3034 ColumnRef returnColRef = null; 3035 3036 if (sColumn.equals(TAG_SUBGROUPS) == true) { 3037 returnColRef = this.getParentChildJoinColumnRef(TAG_CHILDREN); 3038 } else if ( 3039 sColumn.equals(TAG_GROUP) == true) { 3040 returnColRef = this.getParentChildJoinColumnRef(sColumn); 3041 } 3042 3043 if (returnColRef != null) { 3044 return returnColRef; 3045 } else { 3046 return super.getInstanceColumnRef(sColumn,bIsHist); 3047 } 3048 } 3049 3050} 3051 | Popular Tags |