1 19 package org.openharmonise.rm.metadata; 20 21 import java.util.*; 22 import java.util.logging.*; 23 24 import org.openharmonise.commons.cache.*; 25 import org.openharmonise.commons.dsi.*; 26 import org.openharmonise.commons.dsi.ddl.*; 27 import org.openharmonise.commons.dsi.dml.*; 28 import org.openharmonise.commons.xml.XMLPrettyPrint; 29 import org.openharmonise.commons.xml.namespace.NamespaceClashException; 30 import org.openharmonise.rm.*; 31 import org.openharmonise.rm.dsi.DatabaseInfo; 32 import org.openharmonise.rm.factory.*; 33 import org.openharmonise.rm.publishing.*; 34 import org.openharmonise.rm.resources.*; 35 import org.openharmonise.rm.resources.metadata.properties.Property; 36 import org.openharmonise.rm.resources.metadata.properties.ranges.ChildObjectRange; 37 import org.openharmonise.rm.resources.publishing.*; 38 import org.w3c.dom.*; 39 40 41 49 public class ChildObjectPropertyInstance 50 extends AbstractPropertyInstance 51 implements Publishable { 52 53 57 private static Map m_childObj_table_mappings = new Hashtable(); 58 protected final static String CLMN_OBJECT_ID = "object_id"; 59 60 63 private static final Logger m_logger = Logger.getLogger(ChildObjectPropertyInstance.class.getName()); 64 65 68 public ChildObjectPropertyInstance() { 69 super(); 70 71 } 72 73 78 public ChildObjectPropertyInstance(AbstractDataStoreInterface dbint) { 79 super(dbint); 80 81 } 82 83 90 public ChildObjectPropertyInstance( 91 AbstractDataStoreInterface dbintrf, 92 Profile profile) { 93 super(dbintrf, profile); 94 95 } 96 97 107 public ChildObjectPropertyInstance( 108 AbstractDataStoreInterface dbintrf, 109 int nPropertyId, 110 Profile profile) { 111 super(dbintrf, nPropertyId, profile); 112 } 113 114 121 public ChildObjectPropertyInstance( 122 AbstractDataStoreInterface dbintrf, 123 Property prop) { 124 super(dbintrf, prop); 125 } 126 127 137 public ChildObjectPropertyInstance( 138 AbstractDataStoreInterface dbintrf, 139 Property property, 140 Profile profile) { 141 super(dbintrf, property, profile); 142 143 } 144 145 153 public void addValue(AbstractChildObject child) 154 throws PopulateException { 155 if (child != null && isValidValue(child)) { 156 try { 157 CachePointer ptr = 158 CacheHandler.getInstance(m_dsi).getCachePointer(child); 159 160 super.addValue(ptr); 161 162 } catch (CacheException e) { 163 throw new InvalidPropertyValueException( 164 "Unable to get cache pointer", 165 e); 166 } 167 } 168 } 169 170 179 public void addValue(AbstractChildObject child, int nId) 180 throws PopulateException { 181 if (child != null && isValidValue(child)) { 182 try { 183 CachePointer ptr = 184 CacheHandler.getInstance(m_dsi).getCachePointer(child); 185 186 super.addValue(ptr, nId); 187 } catch (CacheException e) { 188 throw new InvalidPropertyValueException( 189 "Unable to get cache pointer", 190 e); 191 } 192 } 193 194 } 195 196 205 public void removeValue(AbstractChildObject child) 206 throws InvalidPropertyValueException { 207 208 try { 209 CachePointer ptr = 210 CacheHandler.getInstance(m_dsi).getCachePointer(child); 211 212 super.removeValue(ptr); 213 } catch (CacheException e) { 214 throw new InvalidPropertyValueException(e.getLocalizedMessage(), e); 215 } 216 } 217 218 221 public void populate(Element xmlElement, State state) 222 throws PopulateException { 223 String sTagName = xmlElement.getTagName(); 224 Text txt = null; 225 226 if (sTagName.equals(TAG_PROP_INSTANCE_VALUES) == true) { 227 NodeList nodes = xmlElement.getChildNodes(); 228 boolean bChildFound = false; 229 230 for (int i = 0; i < nodes.getLength(); i++) { 231 if (nodes.item(i).getNodeType() != Node.ELEMENT_NODE) { 232 continue; 233 } 234 Element tmpEl = (Element) nodes.item(i); 235 sTagName = tmpEl.getTagName(); 236 237 if (sTagName.equals(TAG_ATTACH) == true){ 238 NodeList attachNodes = tmpEl.getChildNodes(); 239 for (int j = 0; j < attachNodes.getLength(); j++) { 240 if (attachNodes.item(j).getNodeType() != Node.ELEMENT_NODE) { 241 continue; 242 } 243 Element attEl = (Element) attachNodes.item(j); 244 populateChild(attEl, state); 245 } 246 } else if (sTagName.equals(TAG_DETACH) == true) { 247 NodeList detachNodes = tmpEl.getChildNodes(); 248 for (int j = 0; j < detachNodes.getLength(); j++) { 249 if (detachNodes.item(j).getNodeType() != Node.ELEMENT_NODE) { 250 continue; 251 } 252 Element attEl = (Element) detachNodes.item(j); 253 populateChild(attEl, state, true); 254 } 255 } else { 256 if(bChildFound == false){ 257 this.clearValues(); 258 } 259 populateChild(tmpEl, state); 260 bChildFound = true; 261 } 262 } 263 } else { 264 super.populate(xmlElement, state); 265 } 266 } 267 private void populateChild(Element childEl, State state) 268 throws PopulateException { 269 270 populateChild(childEl, state, false); 271 } 272 private void populateChild(Element childEl, State state, boolean bRemove) 273 throws PopulateException { 274 try { 275 Publishable pubObj = 276 HarmoniseObjectFactory.instantiatePublishableObject( 277 this.m_dsi, 278 childEl, 279 state); 280 281 if(pubObj != null) { 282 pubObj.populate(childEl, state); 283 if(bRemove){ 284 removeValue((AbstractChildObject) pubObj); 285 } else { 286 addValue((AbstractChildObject) pubObj); 287 } 288 } else { 289 XMLPrettyPrint xpp = new XMLPrettyPrint(); 290 291 try { 292 throw new PopulateException(xpp.printNode(childEl)); 293 } catch (PopulateException e) { 294 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 295 } catch (NamespaceClashException e) { 296 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 297 } 298 } 299 } catch (InvalidPropertyValueException iv_e) { 300 throw new PopulateException( 301 "Invalid value for PropertyInstance" ,iv_e); 302 } catch (HarmoniseFactoryException e) { 303 throw new PopulateException( 304 "Problem occured instantiating value",e); 305 } catch (ClassCastException cce) { 306 throw new PopulateException( 307 "Invalid value for PropertyInstance",cce); 308 } 309 } 310 311 314 public Element publish(Element formEl, HarmoniseOutput xmlDoc, State state) 315 throws PublishException { 316 317 Element resultEl = null; 318 String sTagname = formEl.getTagName(); 319 320 if (sTagname.equals(TAG_PROP_INSTANCE_VALUES) == true) { 321 resultEl = xmlDoc.createElement(TAG_PROP_INSTANCE_VALUES); 322 323 if (m_values != null) { 324 NodeList templateNodes = 325 formEl.getElementsByTagName(Template.TAG_TEMPLATE); 326 Element templateEl = (Element) templateNodes.item(0); 327 Template template = null; 328 Element publishTemplateEl = null; 329 330 int nPageId = -2; 331 332 if (templateEl != null) { 333 try { 334 template = 335 (Template) HarmoniseObjectFactory.instantiateHarmoniseObject( 336 m_dsi, 337 templateEl, 338 state); 339 NodeList pageNodes = 340 templateEl.getElementsByTagName(WebPage.TAG_PAGE); 341 342 if (pageNodes.getLength() > 0) { 343 nPageId = 344 Integer.parseInt( 345 ((Element) pageNodes.item(0)).getAttribute( 346 AbstractObject.ATTRIB_ID)); 347 } 348 } catch (HarmoniseFactoryException e) { 349 throw new PublishException(e.getLocalizedMessage(), e); 350 } 351 } 352 353 if (template != null) { 354 try { 355 publishTemplateEl = template.getTemplateRootElement(); 356 } catch (DataAccessException e) { 357 throw new PublishException(e.getLocalizedMessage(), e); 358 } 359 } else { 360 publishTemplateEl = 363 xmlDoc.createElement( 364 AbstractObject.TAG_HARMONISE_OBJECT); 365 Element nameEl = 366 xmlDoc.createElement(AbstractObject.TAG_NAME); 367 publishTemplateEl.appendChild(nameEl); 368 Element displayNameEl = 369 xmlDoc.createElement( 370 AbstractChildObject.TAG_DISPLAY_NAME); 371 publishTemplateEl.appendChild(displayNameEl); 372 } 373 374 Text txt = null; 375 for (int j = 0; j < m_values.size(); j++) { 376 try { 377 AbstractChildObject tmpChild = 378 (AbstractChildObject) ((CachePointer) m_values 379 .get(j)) 380 .getObject(); 381 382 Element childEl = null; 383 384 childEl = 385 tmpChild.publish(publishTemplateEl, xmlDoc, state); 386 387 if (childEl != null) { 388 resultEl.appendChild(childEl); 389 } 390 391 } catch (CacheException e) { 392 throw new PublishException(e); 393 } 394 395 } 396 if (nPageId > 0) { 397 xmlDoc.addPageIdToLinkNode( 398 state.getLoggedInUser(), 399 resultEl, 400 nPageId); 401 } 402 } 403 } else { 404 resultEl = super.publish(formEl, xmlDoc, state); 405 } 406 407 if (resultEl == null) { 408 resultEl = xmlDoc.createElement(TAG_ERROR); 409 resultEl.appendChild( 410 xmlDoc.createTextNode("Problem publishing " + sTagname)); 411 } 412 413 return resultEl; 414 } 415 416 419 public Element publish(Template template, HarmoniseOutput xmlDoc, State state) 420 throws PublishException { 421 return super.publish(template, xmlDoc, state); 422 } 423 424 427 protected void setDBTable(Profile profile) { 428 430 try { 431 Property prop = getProperty(); 432 433 if (prop != null) { 434 435 try { 436 437 ChildObjectRange range = 438 (ChildObjectRange) getProperty().getRange(); 439 440 AbstractChildObject child = null; 441 442 if (m_profile != null) { 443 child = 444 (AbstractChildObject) m_profile.getProfiledObject(); 445 } 446 447 String sClassname = 448 range.getChildObjectValueClassName(child); 449 450 m_sDataTable = getDBTableName(profile, sClassname); 451 } catch (DataStoreException e) { 452 throw new IllegalStateException ("Property had inappropriate range object for this property instance"); 453 } catch (DataAccessException e) { 454 throw new IllegalStateException ("Property had inappropriate range object for this property instance"); 455 } 456 } 457 } catch (DataAccessException e) { 458 throw new IllegalStateException (e.getLocalizedMessage()); 459 } 460 } 461 462 465 public boolean match(AbstractPropertyInstance propInst) 466 throws ProfileException { 467 boolean bMatch = false; 468 469 if (propInst instanceof ChildObjectPropertyInstance) { 470 List vals = getValues(); 471 List otherVals = propInst.getValues(); 472 473 Iterator thisIter = vals.iterator(); 474 475 if ((m_sOperator.equals("=") && vals.size() == otherVals.size()) 476 || m_sOperator.equalsIgnoreCase("contains")){ 477 478 while (thisIter.hasNext()) { 479 AbstractChildObject child = (AbstractChildObject) thisIter.next(); 480 481 if(otherVals.contains(child) == false) { 482 bMatch = false; 483 break; 484 } else if(bMatch == false) { 485 bMatch = true; 486 } 487 488 } 489 } 490 491 } 492 return bMatch; 493 } 494 495 498 499 502 protected ColumnRef getColumnForData() throws DataStoreException { 503 return getInstanceColumnRef(TAG_VALUE, isHistorical()); 504 } 505 506 509 protected Object getValueToStoreForValue(Object val) 510 throws ProfileException { 511 Integer intVal = null; 512 513 CachePointer ptr = (CachePointer) val; 514 int nChildId = Integer.parseInt((String ) ptr.getKey()); 515 516 if (nChildId > 0) { 517 intVal = new Integer (nChildId); 518 } else { 519 throw new InvalidPropertyInstanceException("Child object value with invalid id - 0"); 520 } 521 522 return intVal; 523 } 524 525 528 public JoinConditions getInstanceJoinConditions( 529 String sObjectTag, 530 boolean bIsOuter) 531 throws DataStoreException { 532 return null; 533 } 534 535 538 public ColumnRef getInstanceColumnRef(String sColumn, boolean bIsHist) 539 throws DataStoreException { 540 ColumnRef returnColRef = null; 541 String sDBTable = getDBTableName(); 542 543 if (sColumn.equals(TAG_VALUE) == true 544 || sColumn.equals(CLMN_OBJECT_ID) == true) { 545 returnColRef = 546 new ColumnRef(sDBTable, CLMN_OBJECT_ID, ColumnRef.NUMBER); 547 } 548 549 if (returnColRef != null) { 550 return returnColRef; 551 } else { 552 return super.getInstanceColumnRef(sColumn, bIsHist); 553 } 554 } 555 556 559 public List processResultSet( 560 CachedResultSet resultSet, 561 SelectStatement select) { 562 return null; 564 } 565 566 569 public List processResultSet( 570 CachedResultSet resultSet, 571 SelectStatement select, 572 int limit) { 573 return null; 575 } 576 577 593 public static String getDBTableName(Profile profile, String sClassname) 594 throws DataStoreException { 595 StringBuffer sDataTable = new StringBuffer (); 596 597 String sExt = (String ) m_childObj_table_mappings.get(sClassname); 598 599 if (sExt == null) { 600 String sTable = DatabaseInfo.getInstance().getTableName(sClassname); 601 sExt = "_" + sTable; 602 m_childObj_table_mappings.put(sClassname, sExt); 603 } 604 605 if (profile.isHistorical() == true) { 606 AbstractProfiledObject profObj = profile.getProfiledObject(); 607 sDataTable 608 .append(profObj.getDBTableName()) 609 .append(Profile.EXT_PROFILE) 610 .append(sExt) 611 .append(EXT_HIST); 612 } else { 613 sDataTable.append(profile.getDBTableName()).append(sExt); 614 } 615 616 return sDataTable.toString(); 617 } 618 619 636 public static String constructDBTableName(Profile profile, String sTable) { 637 StringBuffer sDataTable = new StringBuffer (); 638 639 String sExt = "_" + sTable; 640 641 if (profile.isHistorical() == true) { 642 AbstractProfiledObject profObj = profile.getProfiledObject(); 643 sDataTable 644 .append(profObj.getDBTableName()) 645 .append(Profile.EXT_PROFILE) 646 .append(sExt) 647 .append(EXT_HIST); 648 } else { 649 sDataTable.append(profile.getDBTableName()).append(sExt); 650 } 651 652 return sDataTable.toString(); 653 } 654 655 658 public String getDBTableName() { 659 if (m_sDataTable == null) { 660 try { 661 662 ChildObjectRange range = 663 (ChildObjectRange) getProperty().getRange(); 664 665 AbstractChildObject child = null; 666 667 if (m_profile != null) { 668 child = (AbstractChildObject) m_profile.getProfiledObject(); 669 } 670 671 String sClassname = range.getChildObjectValueClassName(child); 672 m_sDataTable = getDBTableName(m_profile, sClassname); 673 674 } catch (DataStoreException e) { 675 throw new IllegalStateException ("Property had inappropriate range object for this property instance"); 676 } catch (DataAccessException e) { 677 throw new IllegalStateException ("Property had inappropriate range object for this property instance"); 678 } 679 } 680 681 return m_sDataTable; 682 } 683 684 696 private boolean isValidValue(AbstractChildObject child) 697 throws InvalidPropertyValueException { 698 boolean bIsValid = true; 699 700 if (child.getId() > 0) { 701 try { 702 if (childExists(child) == true) { 703 bIsValid = child.isLiveVersion(); 704 } else { 705 bIsValid = false; 706 } 707 708 } catch (DataAccessException e) { 709 throw new InvalidPropertyValueException( 710 "Couldn't determine status of child object", 711 e); 712 } catch (DataStoreException e) { 713 throw new InvalidPropertyValueException( 714 "Child doesn't exit and had trouble removing it", 715 e); 716 } 717 718 if (bIsValid == false) { 719 throw new InvalidPropertyValueException("Child object must be live to add as value"); 720 } 721 } else { 722 bIsValid = false; 723 } 724 725 return bIsValid; 726 } 727 728 731 public Object getValue() { 732 AbstractChildObject child = null; 733 try { 734 child = 735 (AbstractChildObject) ((CachePointer) super.getValue()) 736 .getObject(); 737 } catch (CacheException e) { 738 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 739 } 740 741 return child; 742 } 743 744 747 public Object getValue(int nIndex) { 748 AbstractChildObject child = null; 749 try { 750 CachePointer ptr = (CachePointer) super.getValue(nIndex); 751 child = (AbstractChildObject) ptr.getObject(); 752 if (childExists(child) == false) { 753 child = null; 754 } 755 } catch (CacheException e) { 756 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 757 } catch (DataStoreException e) { 758 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 759 } 760 761 return child; 762 } 763 764 767 public List getValues() { 768 List result = new ArrayList(); 769 List ptrs = super.getValues(); 770 771 Iterator iter = ptrs.iterator(); 772 773 while (iter.hasNext()) { 774 Object obj = iter.next(); 775 776 CachePointer ptr = (CachePointer) obj; 777 try { 778 AbstractChildObject child = 779 (AbstractChildObject) ptr.getObject(); 780 if (childExists(child) == true) { 782 result.add(child); 783 } 784 785 } catch (CacheException e) { 786 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 787 } catch (DataStoreException e) { 788 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 789 } 790 } 791 792 return result; 793 } 794 795 798 public void setValues(List values) throws InvalidPropertyValueException { 799 List ptrs = new ArrayList(); 800 801 Iterator iter = values.iterator(); 802 803 try { 804 while (iter.hasNext()) { 805 Object tmpObj = iter.next(); 806 if (tmpObj instanceof AbstractChildObject) { 807 AbstractChildObject child = (AbstractChildObject) tmpObj; 808 ptrs.add( 809 CacheHandler.getInstance(m_dsi).getCachePointer(child)); 810 } else if (tmpObj instanceof CachePointer) { 811 ptrs.add(tmpObj); 812 } 813 814 } 815 } catch (CacheException e) { 816 m_logger.log(Level.WARNING, e.getLocalizedMessage(), e); 817 throw new InvalidPropertyValueException(e); 818 } 819 820 super.setValues(ptrs); 821 } 822 823 833 private boolean childExists(AbstractChildObject child) 834 throws DataStoreException { 835 boolean bExists = child.exists(); 836 837 if (bExists == false && isPopulated() == false) { 838 removeChildReferences(child); 839 } 840 841 return bExists; 842 } 843 844 852 protected void removeChildReferences(AbstractChildObject child) 853 throws DataStoreException { 854 int nIndex = -1; 855 int i = 0; 856 857 Iterator iter = m_values.iterator(); 858 boolean bFound = false; 859 while (iter.hasNext() && bFound == false) { 860 CachePointer ptr = (CachePointer) iter.next(); 861 862 if (ptr.getKey().equals(String.valueOf(child.getId()))) { 863 nIndex = i; 864 bFound = true; 865 } 866 867 i++; 868 } 869 870 if (bFound == true && m_valueIds.size() > nIndex) { 871 DeleteStatement delete = new DeleteStatement(); 872 873 delete.addWhereCondition(getColumnForData(), "=", child.getId()); 874 875 delete.addWhereCondition( 876 getInstanceColumnRef(CLMN_ID, isHistorical()), 877 "=", 878 ((Integer ) m_valueIds.get(nIndex)).intValue()); 879 880 m_dsi.execute(delete); 881 882 if (m_values.size() > nIndex) { 883 m_values.remove(nIndex); 884 } 885 if (m_valueIds.size() > nIndex) { 886 m_valueIds.remove(nIndex); 887 } 888 } 889 890 } 891 892 901 public static void generateTable(AbstractDataStoreInterface dsi,String sProfileTable, String sTableName) throws DataStoreException { 902 903 TableDefinition tblDef = new TableDefinition(sTableName); 904 905 tblDef.addColumn(CLMN_ID,true,ColumnDefinition.NUMBER); 906 ColumnDefinition profRef = new ColumnDefinition(CLMN_PROFILE_ID,ColumnDefinition.NUMBER); 907 profRef.addForeignKey(sProfileTable); 908 tblDef.addColumn(profRef); 909 tblDef.addColumn(CLMN_PROPERTY_ID,ColumnDefinition.NUMBER); 910 tblDef.addColumn(CLMN_OBJECT_ID,ColumnDefinition.NUMBER); 911 tblDef.addColumn(CLMN_VERSION_COMMENT,ColumnDefinition.TEXT,true); 912 913 dsi.createTable(tblDef); 914 } 915 916 928 public static String getDBTableName(String domainClass, String valueClass, boolean bIsHist) throws DataAccessException { 929 StringBuffer str = new StringBuffer (); 930 try { 931 DatabaseInfo dbinf = DatabaseInfo.getInstance(); 932 str.append(dbinf.getTableName(domainClass)); 933 str.append(Profile.EXT_PROFILE); 934 str.append("_"); 935 str.append(dbinf.getTableName(valueClass)); 936 937 if(bIsHist == true) { 938 str.append(Profile.EXT_HIST); 939 } 940 } catch (DataStoreException e) { 941 throw new DataAccessException(e); 942 } 943 944 return str.toString(); 945 } 946 947 961 public static void createTable(AbstractDataStoreInterface dsi, String domainClass, String valueClass, boolean bIsHist) throws DataAccessException, DataStoreException { 962 generateTable(dsi,Profile.getTableName(domainClass, bIsHist), getDBTableName(domainClass, valueClass, bIsHist)); 963 } 964 965 } 966 | Popular Tags |