1 40 41 package org.jahia.services.fields; 42 43 import org.jahia.content.*; 44 import org.jahia.bin.Jahia; 45 import org.jahia.data.fields.JahiaField; 46 import org.jahia.data.fields.JahiaFieldDefinition; 47 import org.jahia.engines.EngineMessage; 48 import org.jahia.exceptions.JahiaException; 49 import org.jahia.params.ParamBean; 50 import org.jahia.registries.JahiaListenersRegistry; 51 import org.jahia.registries.JahiaFieldDefinitionsRegistry; 52 import org.jahia.registries.ServicesRegistry; 53 import org.jahia.services.acl.ACLResourceInterface; 54 import org.jahia.services.acl.JahiaBaseACL; 55 import org.jahia.services.containers.ContentContainer; 56 import org.jahia.services.containers.FieldsChangeEventListener; 57 import org.jahia.services.pages.ContentPage; 58 import org.jahia.services.sites.JahiaSite; 59 import org.jahia.services.sites.SiteLanguageSettings; 60 import org.jahia.services.usermanager.JahiaUser; 61 import org.jahia.services.version.*; 62 import org.jahia.utils.xml.XMLSerializationOptions; 63 import org.jahia.utils.xml.XmlWriter; 64 65 import java.io.IOException ; 66 import java.io.Serializable ; 67 import java.util.*; 68 69 73 public abstract class ContentField extends ContentObject 74 implements ACLResourceInterface, PageReferenceableInterface, Serializable { 75 76 private static org.apache.log4j.Logger logger = 77 org.apache.log4j.Logger.getLogger (ContentField.class); 78 79 private static final String NO_VALUE = "<no_value>"; 80 81 private int aclID; 82 private JahiaBaseACL acl; 83 private int fieldType; 84 private int jahiaID; 85 private int pageID; 86 private int containerID; 87 private int fieldDefID; 88 private int connectType; 89 private Vector activeAndStagingEntryStates; 92 private Vector versioningEntryStates; 97 private Hashtable loadedDBValues; 102 private Hashtable theProperties; 104 static { 105 JahiaObject.registerType (ContentFieldKey.FIELD_TYPE, 106 ContentField.class.getName ()); 107 } 108 109 public static ContentObject getChildInstance (String IDInType) { 110 try { 111 return getField (Integer.parseInt (IDInType)); 112 } catch (JahiaException je) { 113 logger.debug ("Error retrieving field instance for id : " + IDInType, je); 114 } 115 return null; 116 } 117 118 119 public int getAclID () { 120 return aclID; 121 } 122 123 public int getType () { 124 return fieldType; 125 } 126 127 public int getSiteID () { 128 return jahiaID; 129 } 130 131 public int getPageID () { 132 return pageID; 133 } 134 135 public int getContainerID () { 136 return containerID; 137 } 138 139 public int getFieldDefID () { 140 return fieldDefID; 141 } 142 143 public int getConnectType () { 144 return connectType; 145 } 146 147 153 public ContentPage getPage () throws JahiaException { 154 return ContentPage.getPage (this.getPageID ()); 155 } 156 157 164 public int getDefinitionID (EntryLoadRequest loadRequest) { 165 return this.getFieldDefID (); 166 } 167 168 176 public ObjectKey getDefinitionKey (EntryLoadRequest loadRequest) { 177 int defID = getDefinitionID (loadRequest); 178 FieldDefinitionKey fieldDefKey = (FieldDefinitionKey) 179 FieldDefinitionKey.getChildInstance (String.valueOf (defID)); 180 return fieldDefKey; 181 } 182 183 public final JahiaBaseACL getACL () { 184 if (acl == null) { 185 try { 186 acl = new JahiaBaseACL (getAclID ()); 187 } catch (Throwable t) { 188 t.printStackTrace (); 189 } 190 } 191 return acl; 192 } 193 194 200 protected ContentField (int fieldID, int aJahiaID, int aPageID, int ctnid, int aFieldDefID, 201 int typeField, int aConnectType, int rights, Vector anActiveAndStagingEntryStates, 202 Hashtable activeAndStagedDBValues) { 203 super (new ContentFieldKey (fieldID)); 204 this.jahiaID = aJahiaID; 205 this.pageID = aPageID; 206 this.containerID = ctnid; 207 this.fieldDefID = aFieldDefID; 208 this.fieldType = typeField; 209 this.connectType = aConnectType; 210 this.aclID = rights; 211 this.activeAndStagingEntryStates = anActiveAndStagingEntryStates; 212 this.versioningEntryStates = null; 213 this.theProperties = null; 215 this.loadedDBValues = new Hashtable (activeAndStagedDBValues); 216 217 this.acl = null; 218 } 219 220 223 protected ContentField() { 224 225 } 226 227 240 public ContentObjectEntryState getEntryState (EntryLoadRequest loadRequest) 241 throws JahiaException { 242 Vector entryStateables = new Vector (activeAndStagingEntryStates); 243 if (loadRequest.getWorkflowState () < 1) { 245 loadVersioningEntryStates (); 246 entryStateables.addAll (versioningEntryStates); 248 } 249 return (ContentObjectEntryState) ServicesRegistry.getInstance ().getJahiaVersionService ().resolveEntry ( 251 entryStateables, loadRequest); 252 } 253 254 259 public String getValue (ParamBean jParams) throws JahiaException { 260 ContentObjectEntryState entryState = getEntryState (jParams.getEntryLoadRequest ()); 261 if (entryState == null) { 262 return null; 263 } 264 return this.getValue (jParams, entryState); 265 } 266 267 public String getValue (ContentObjectEntryState entryState) 268 throws JahiaException { 269 return this.getValue (null, entryState); 270 } 271 272 282 public void markLanguageForDeletion (JahiaUser user, 283 String languageCode, 284 StateModificationContext stateModificationContext) 285 throws JahiaException { 286 287 295 boolean stateModified = false; 296 if (ContentObject.SHARED_LANGUAGE.equals (languageCode) 297 || (!this.isShared () && this.willBeCompletelyDeleted (languageCode, null))) { 298 stateModified = true; 299 stateModificationContext.pushAllLanguages (true); 300 } 301 302 Set languageCodes = new HashSet (); 303 if (ContentObject.SHARED_LANGUAGE.equals (languageCode) 304 && !this.isShared ()) { 305 languageCodes.addAll (getStagingLanguages (true, false)); 306 Iterator languageCodeIter = languageCodes.iterator (); 307 while (languageCodeIter.hasNext ()) { 308 String curLanguageCode = (String ) languageCodeIter.next (); 309 markContentLanguageForDeletion (user, curLanguageCode, 310 stateModificationContext); 311 } 312 } else { 313 markContentLanguageForDeletion (user, languageCode, stateModificationContext); 314 } 315 316 languageCodes = new HashSet (); 317 languageCodes.add (languageCode); 318 if (stateModified && stateModificationContext.isAllLanguages ()) { 319 languageCodes.addAll (getStagingLanguages (false)); 320 } 321 if ((this.isShared () && 322 !this.willAllChildsBeCompletelyDeleted (user, languageCode, null)) 323 || (this.isShared () && !ContentObject.SHARED_LANGUAGE.equals (languageCode))) { 324 328 if (this.getStagingLanguages (false, true).isEmpty ()) { 331 Iterator iterator = this.getActiveAndStagingEntryStates ().iterator (); 333 if (iterator.hasNext ()) { 334 ContentObjectEntryState fromEntryState = 335 (ContentObjectEntryState) iterator.next (); 336 ContentObjectEntryState toEntryState = 337 new ContentObjectEntryState (ContentObjectEntryState 338 .WORKFLOW_STATE_START_STAGING, 0, 339 ContentObject.SHARED_LANGUAGE); 340 this.copyEntry (fromEntryState, toEntryState); 341 } 342 } 343 344 if (stateModified) { 345 stateModificationContext.popAllLanguages (); 346 } 347 } 348 349 Iterator languageCodeIter = languageCodes.iterator (); 350 while (languageCodeIter.hasNext ()) { 351 String curLanguageCode = (String ) languageCodeIter.next (); 352 353 boolean foundInActive = false; 354 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 355 ContentObjectEntryState thisEntryState = ( 356 ContentObjectEntryState) activeAndStagingEntryStates.get (i); 357 if (thisEntryState.isActive ()) { 358 if (this.isShared () || thisEntryState.getLanguageCode ().equals ( 359 curLanguageCode)) { 360 foundInActive = true; 361 break; 362 } 363 } 364 } 365 if (this.isShared ()) { 366 curLanguageCode = ContentObject.SHARED_LANGUAGE; 368 } 369 EntrySaveRequest saveRequest = new EntrySaveRequest (user, 370 curLanguageCode); 371 if (foundInActive) { 372 if ( (this.isShared() && ContentField.SHARED_LANGUAGE.equals(languageCode)) 377 || !this.isShared() ){ 378 preSet(NO_VALUE, saveRequest); 379 } 380 } else { 381 Set tempLanguageCodes = new HashSet (); 382 tempLanguageCodes.add (saveRequest.getLanguageCode ()); 383 deleteStagingEntries (tempLanguageCodes); 384 } 385 } 386 387 if (stateModified) { 388 stateModificationContext.popAllLanguages (); 389 } 390 391 notifyFieldUpdate(); 392 393 ServicesRegistry.getInstance ().getJahiaSearchService () 395 .removeFieldFromSearchEngine (this.getSiteID (), this.getID (), 396 ContentObjectEntryState.WORKFLOW_STATE_START_STAGING, languageCode); 397 } 398 399 406 public synchronized ActivationTestResults activate ( 407 Set languageCodes, 408 int newVersionID, 409 ParamBean jParams, 410 StateModificationContext stateModifContext) throws JahiaException { 411 ActivationTestResults activationResults = new ActivationTestResults (); 412 413 int activeVersionId = this.getActiveVersionID(); 415 int deletedVersionId = this.getDeleteVersionID(); 416 if ( activeVersionId == newVersionID 417 || deletedVersionId == newVersionID ){ 418 421 activationResults.appendWarning("Field " + getID() + 428 " is already activated with newVersionID=" + newVersionID); 429 return activationResults; 430 } 431 432 433 boolean versioningEnabled = ServicesRegistry.getInstance ().getJahiaVersionService ().isVersioningEnabled (jahiaID); 434 Vector stagedEntries = new Vector (); 435 436 boolean stateModified = false; 437 if (willBeCompletelyDeleted (null, languageCodes)) { 438 stateModified = true; 439 stateModifContext.pushAllLanguages (true); 440 } 441 442 Set activateLanguageCodes = new HashSet (languageCodes); 443 if (stateModifContext.isAllLanguages ()) { 444 activateLanguageCodes.addAll (getStagingLanguages (true)); 445 } 446 447 activationResults.merge ( 448 isValidForActivation (activateLanguageCodes, jParams, stateModifContext)); 449 450 454 459 if (activationResults.getStatus () == ActivationTestResults.FAILED_OPERATION_STATUS) { 460 return activationResults; 461 } 462 463 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 466 ContentObjectEntryState entryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 467 i); 468 if (entryState.isStaging ()) { 469 470 if (entryState.getLanguageCode ().equals (ContentField.SHARED_LANGUAGE) 471 || activateLanguageCodes.contains (entryState.getLanguageCode ())) { 472 stagedEntries.add (entryState); 473 } 474 475 } 476 } 477 478 479 480 486 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 488 ContentObjectEntryState actEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 489 i); 490 if (actEntryState.isActive ()) { 491 for (int j = 0; j < stagedEntries.size (); j++) { 492 ContentObjectEntryState staEntryState = (ContentObjectEntryState) stagedEntries.get ( 493 j); 494 if (actEntryState.getLanguageCode ().equals ( 495 staEntryState.getLanguageCode ())) { 496 if (versioningEnabled) { 498 499 ContentObjectEntryState backupEntryState = ContentFieldDB.getInstance ().backupDBValue ( 500 this, actEntryState); if (backupEntryState != null) { 503 if (versioningEntryStates != null) { 505 versioningEntryStates.add (backupEntryState); 506 } 507 this.changeEntryState (actEntryState, backupEntryState, 509 jParams, stateModifContext); 510 } 511 } else { 512 this.deleteEntry (actEntryState); 514 } 515 ContentFieldDB.getInstance ().deleteDBValue (this, actEntryState); 517 activeAndStagingEntryStates.remove (i); 518 i -= 1; 519 } 520 } 521 } 522 } 523 for (int i = 0; i < stagedEntries.size (); i++) { 529 ContentObjectEntryState staEntryState = (ContentObjectEntryState) stagedEntries.get ( 530 i); 531 532 ContentObjectEntryState newEntryState = null; 533 if (staEntryState.getVersionID () == -1) { 535 newEntryState = new ContentObjectEntryState ( 537 ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED, 538 newVersionID, 539 staEntryState.getLanguageCode ()); 540 } else { 541 newEntryState = new ContentObjectEntryState ( 543 ContentObjectEntryState.WORKFLOW_STATE_ACTIVE, 544 newVersionID, 545 staEntryState.getLanguageCode ()); 546 } 547 548 if ((!versioningEnabled) && (newEntryState.getWorkflowState () <= 1)) { 550 this.deleteEntry (staEntryState); 552 } else { 553 activationResults.merge ( 556 this.changeEntryState (staEntryState, newEntryState, jParams, 557 stateModifContext)); 558 559 563 566 if (activationResults.getStatus () != ActivationTestResults.FAILED_OPERATION_STATUS) { 567 ContentFieldDB.getInstance ().changeDBEntryState (this, staEntryState, newEntryState); 569 } else { 570 if (stateModified) { 571 stateModifContext.popAllLanguages (); 572 } 573 return activationResults; 574 } 575 } 576 577 activeAndStagingEntryStates.remove (staEntryState); loadedDBValues.remove (staEntryState); 582 if (newEntryState.getWorkflowState () >= 1) { 585 activeAndStagingEntryStates.add (newEntryState); } else { 587 if ((versioningEnabled) && (versioningEntryStates != null)) { 589 versioningEntryStates.add (newEntryState); 590 } 591 } 592 } 594 595 if ((activeAndStagingEntryStates.size () == 0) && 599 (!versioningEnabled)) { 600 ContentFieldTools.getInstance ().purgeFieldData (this); 602 } 603 604 605 ServicesRegistry.getInstance () 606 .getJahiaSearchService ().removeFieldFromSearchEngine (this); 607 608 if (!this.willBeCompletelyDeleted (null, null)) { 609 610 ServicesRegistry.getInstance () 611 .getJahiaSearchService ().indexField (this.getID (), false, 612 jParams, true); 613 } 614 615 if (stateModified) { 616 stateModifContext.popAllLanguages (); 617 } 618 619 ContentFieldTools.getInstance ().updateCache(this); 622 623 return activationResults; 624 } 625 626 641 public ActivationTestResults isValidForActivation ( 642 Set languageCodes, 643 ParamBean jParams, 644 StateModificationContext stateModifContext) 645 throws JahiaException { 646 ActivationTestResults activationTestResults = new ActivationTestResults (); 647 648 int containerId = this.getContainerID(); 649 ContentContainer contentContainer = null; 650 if ( containerId > 0 ){ 651 contentContainer = ContentContainer.getContainer(containerId); 652 } 653 654 boolean deleted = this.isDeleted(activeAndStagingEntryStates); 655 boolean markedForDelete = this.isMarkedForDelete(); 656 657 if ( ((contentContainer == null) && !(deleted || markedForDelete)) || 658 ((contentContainer != null) && !((contentContainer.isMarkedForDelete() || contentContainer.isDeleted(contentContainer.getActiveAndStagingEntryStates()))) 659 && !(deleted || markedForDelete) ) ){ 660 661 JahiaSite theSite = jParams.getSite(); 664 665 boolean allEntriesUninitialized = true; 668 Iterator activeAndStagingEntryEnum = activeAndStagingEntryStates.iterator(); 669 Map languagesInitialized = new HashMap(32); 670 while (activeAndStagingEntryEnum.hasNext()) { 671 ContentObjectEntryState curEntryState = (ContentObjectEntryState) 672 activeAndStagingEntryEnum.next(); 673 if (isEntryInitialized(curEntryState)) { 674 allEntriesUninitialized = false; 675 languagesInitialized.put(curEntryState.getLanguageCode(),Boolean.TRUE); 676 } 677 } 678 679 if (!markedForDelete && (!allEntriesUninitialized)) { 680 Vector languageSettings = theSite.getLanguageSettings(); 681 Enumeration languageSettingsEnum = languageSettings.elements(); 682 while (languageSettingsEnum.hasMoreElements()) { 683 SiteLanguageSettings curSettings = (SiteLanguageSettings) 684 languageSettingsEnum.nextElement(); 685 if (curSettings.isMandatory()) { 686 boolean foundLanguage = false; 689 if(languagesInitialized.containsKey(curSettings.getCode()) || 690 languagesInitialized.containsKey(ContentField.SHARED_LANGUAGE)) 691 foundLanguage = true; 692 693 if (!foundLanguage) { 694 activationTestResults.setStatus( 695 ActivationTestResults.FAILED_OPERATION_STATUS); 696 try { 697 JahiaFieldDefinition fieldDefinition = JahiaFieldDefinitionsRegistry.getInstance().getDefinition(getFieldDefID()); 698 String fieldTitle = null; 699 if (fieldDefinition != null) { 700 try { 701 fieldTitle = fieldDefinition.getTitle( 702 getPage().getPageTemplate(jParams. 703 getEntryLoadRequest()).getID(), 704 jParams.getLocale()); 705 } catch (NullPointerException npe) { 706 } 709 } 710 final EngineMessage msg = new EngineMessage( 711 "org.jahia.services.fields.ContentField.mandatoryLangMissingError", 712 fieldTitle); 713 IsValidForActivationResults activationResults = new IsValidForActivationResults( 714 ContentFieldKey.FIELD_TYPE, getID(), 715 curSettings.getCode(), msg); 716 activationTestResults.appendError( 717 activationResults); 718 } catch (ClassNotFoundException cnfe) { 719 logger.debug( 720 "Error while creating activation test node result", 721 cnfe); 722 } 723 } 724 725 } 726 } 727 } 728 } 729 730 activationTestResults.merge ( 731 isContentValidForActivation (languageCodes, jParams, stateModifContext)); 732 733 return activationTestResults; 734 } 735 736 751 protected boolean isEntryInitialized (ContentObjectEntryState curEntryState) 752 throws JahiaException { 753 String entryValue = getValue(curEntryState); 754 if (entryValue == null) { 755 return false; 756 } 757 if (!entryValue.equals("") && 758 !entryValue.equals("<empty>")) { 759 return true; 760 } 761 return false; 762 } 763 764 772 public synchronized void undoStaging (ParamBean jParams) 773 throws JahiaException { 774 775 Vector stagedEntryStates = new Vector (); 777 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 778 ContentObjectEntryState entryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 779 i); 780 if (entryState.isStaging ()) { 782 stagedEntryStates.add (entryState); 783 } 784 } 785 786 for (int i = 0; i < stagedEntryStates.size (); i++) { 788 ContentObjectEntryState curEntryState = (ContentObjectEntryState) stagedEntryStates.get ( 789 i); 790 791 this.deleteEntry (curEntryState); 793 794 ContentFieldDB.getInstance ().deleteDBValue (this, curEntryState); 796 797 activeAndStagingEntryStates.remove (curEntryState); loadedDBValues.remove (curEntryState); } 801 802 notifyFieldUpdate(); 803 804 if ( this.hasStagingEntries() || this.hasActiveEntries() ){ 805 ContentFieldTools.getInstance ().updateCache(this); 808 809 810 ServicesRegistry.getInstance () 811 .getJahiaSearchService ().removeFieldFromSearchEngine (this); 812 ServicesRegistry.getInstance().getJahiaSearchService() 814 .indexField(this.getID(),false,Jahia.getThreadParamBean(), true); 815 } else { 816 ServicesRegistry.getInstance () 817 .getJahiaSearchService ().removeFieldFromSearchEngine (this); 818 ContentFieldTools.getInstance ().removeFromCache(getID()); 819 } 820 } 821 822 829 public synchronized void purge () 830 throws JahiaException { 831 purgeContent (); 832 833 JahiaBaseACL localAcl = getACL (); 834 localAcl.delete (); 835 836 this.activeAndStagingEntryStates.clear (); 837 this.loadedDBValues.clear (); 838 if (this.versioningEntryStates != null) { 839 this.versioningEntryStates.clear (); 840 } 841 842 ContentFieldDB.getInstance ().purgeField (getID ()); 843 } 844 845 851 public abstract String getValue (ParamBean jParams, 852 ContentObjectEntryState entryState) 853 throws JahiaException; 854 855 863 public abstract String getValueForSearch (ParamBean jParams, 864 ContentObjectEntryState entryState) 865 throws JahiaException; 866 867 883 protected abstract ActivationTestResults changeEntryState ( 884 ContentObjectEntryState fromEntryState, 885 ContentObjectEntryState toEntryState, 886 ParamBean jParams, 887 StateModificationContext stateModifContext) throws JahiaException; 888 889 902 protected abstract ActivationTestResults isContentValidForActivation ( 903 Set languageCodes, 904 ParamBean jParams, StateModificationContext stateModifContext) 905 throws JahiaException; 906 907 908 929 protected abstract void serializeContentToXML (XmlWriter xmlWriter, 930 XMLSerializationOptions xmlSerializationOptions, 931 ContentObjectEntryState entryState, 932 ParamBean paramBean) 933 throws IOException ; 934 935 941 protected void purgeContent () throws JahiaException { 942 } 944 945 962 protected Map getContentLanguageStates (ContentObjectEntryState entryState) { 963 return null; 964 } 965 966 979 protected void markContentLanguageForDeletion (JahiaUser user, 980 String languageCode, 981 StateModificationContext stateModifContext) 982 throws JahiaException { 983 return; 984 } 985 986 989 public abstract boolean isShared (); 990 991 1012 protected static synchronized ContentField createField (int siteID, 1013 int pageID, int containerID, 1014 int fieldDefID, 1015 int typeField, int connectType, 1016 int parentAclID, int aclID) 1017 throws JahiaException { 1018 return ContentFieldTools.getInstance ().createField (siteID, pageID, 1019 containerID, fieldDefID, typeField, connectType, parentAclID, 1020 aclID); 1021 } 1022 1023 1028 public static ContentField getField (int fieldID) 1029 throws JahiaException { 1030 return ContentFieldTools.getInstance ().getField (fieldID); 1031 } 1032 1033 1043 public static ContentField getField (int fieldID, boolean forceLoadFromDB) 1044 throws JahiaException { 1045 return ContentFieldTools.getInstance ().getField (fieldID, forceLoadFromDB); 1046 } 1047 1048 1053 public static ContentField getFieldFromCacheOnly (int fieldID) 1054 throws JahiaException { 1055 return ContentFieldTools.getInstance ().getContentFieldFromCacheOnly(fieldID); 1056 } 1057 1058 1067 public static synchronized void preloadActiveOrStagedFieldsByPageID (int pageID) 1068 throws JahiaException { 1069 ContentFieldTools.getInstance ().preloadActiveOrStagedFieldsByPageID (pageID); 1070 } 1071 1072 1079 public static synchronized void removeFromCache (int fieldID) { 1080 ContentFieldTools.getInstance ().removeFromCache (fieldID); 1081 } 1082 1083 1084 1093 public static synchronized void preloadActiveOrStagedFieldsByContainerID (int containerID) 1094 throws JahiaException { 1095 ContentFieldTools.getInstance ().preloadActiveOrStagedFieldsByContainerID (containerID); 1096 } 1097 1098 1109 public static synchronized void markFieldForDeletion (int fieldID, 1110 JahiaUser user, 1111 StateModificationContext stateModifContext) 1112 throws JahiaException { 1113 ContentField theField = ContentField.getField (fieldID); synchronized (theField) { 1115 1116 ContentFieldTools.getInstance ().markFieldForDeletion (theField, 1117 user, 1118 theField.activeAndStagingEntryStates, 1119 stateModifContext); 1120 1121 ContentFieldTools.getInstance().updateCache(theField); 1124 } 1125 } 1126 1127 1136 protected ContentObjectEntryState preSet (String newDBValue, EntrySaveRequest saveRequest) 1137 throws JahiaException { 1138 int currentStatus = ContentObjectEntryState.WORKFLOW_STATE_START_STAGING; 1139 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1141 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1142 i); 1143 if (thisEntryState.isStaging ()) { 1144 currentStatus = thisEntryState.getWorkflowState (); 1145 break; 1146 } 1147 } 1148 1149 int currentVersionID = 0; if (newDBValue.equals (NO_VALUE)) { 1151 currentVersionID = -1; 1152 ContentObjectEntryState oldEntryState = null; 1154 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1156 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1157 i); 1158 if ((!thisEntryState.isStaging ()) && 1159 (thisEntryState.getLanguageCode ().equals ( 1160 saveRequest.getLanguageCode ()))) { 1161 oldEntryState = thisEntryState; 1162 break; 1163 } 1164 } 1165 if (oldEntryState == null) { 1166 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1167 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1168 i); 1169 if ((thisEntryState.isStaging ()) && 1170 (thisEntryState.getLanguageCode ().equals ( 1171 saveRequest.getLanguageCode ()))) { 1172 oldEntryState = thisEntryState; 1173 break; 1174 } 1175 } 1176 } 1177 if (oldEntryState != null) { 1179 newDBValue = getDBValue (oldEntryState); 1180 } 1181 } 1182 String currentLanguage = saveRequest.getLanguageCode (); 1183 ContentObjectEntryState newEntryState = new ContentObjectEntryState (currentStatus, 1184 currentVersionID, currentLanguage); 1185 1187 ContentObjectEntryState currentEntryState = null; for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1190 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1191 i); 1192 if ((thisEntryState.isStaging ()) && 1193 (thisEntryState.getLanguageCode ().equals (saveRequest.getLanguageCode ()))) { 1194 currentEntryState = thisEntryState; 1195 break; 1196 } 1197 } 1198 1199 if (currentEntryState != null) { 1201 activeAndStagingEntryStates.remove (currentEntryState); 1203 loadedDBValues.remove (currentEntryState); 1205 } 1206 1207 loadedDBValues.put (newEntryState, newDBValue); 1209 activeAndStagingEntryStates.add (newEntryState); 1211 1212 if (currentEntryState == null) { 1214 ContentFieldDB.getInstance ().createDBValue (this, newEntryState); 1215 } 1216 1217 ContentFieldDB.getInstance ().updateDBValue (this, newEntryState, getDBValue (newEntryState)); 1219 1220 ContentFieldTools.getInstance ().updateCache(this); 1223 1224 return newEntryState; 1225 } 1226 1227 1230 protected String getSetLanguageCode (ParamBean jParams) 1231 throws JahiaException { 1232 if (isShared ()) { 1233 return (SHARED_LANGUAGE); 1234 } else { 1235 return jParams.getLocale ().toString (); } 1237 } 1238 1239 1246 protected String getDBValue (EntryStateable entryState) throws JahiaException { 1247 String languageCode = entryState.getLanguageCode (); 1250 if (this.isShared ()) { 1251 languageCode = ContentObject.SHARED_LANGUAGE; 1252 } 1253 ContentObjectEntryState objectEntryState = new ContentObjectEntryState ( 1254 entryState.getWorkflowState (), entryState.getVersionID (), 1255 languageCode); 1256 String theResult = (String ) loadedDBValues.get (objectEntryState); 1257 if (theResult == null) { 1259 theResult = ContentFieldDB.getInstance ().loadDBValue (this, objectEntryState); 1260 loadedDBValues.put (objectEntryState, theResult); 1261 } 1262 return theResult; 1263 } 1264 1265 1277 protected Map getAllDBValues () throws JahiaException { 1278 Map theResult = ContentFieldDB.getInstance ().loadAllDBValues (this); 1279 return theResult; 1280 } 1281 1282 1283 1288 public boolean hasActiveEntries () { 1289 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1290 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1291 i); 1292 if (thisEntryState.isActive ()) { 1293 return true; 1294 } 1295 } 1296 return false; 1297 } 1298 1299 1302 public boolean hasStagingEntries () { 1303 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1304 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1305 i); 1306 if (thisEntryState.isStaging ()) { 1307 return true; 1308 } 1309 } 1310 return false; 1311 } 1312 1313 1318 public boolean hasStagingEntry (String languageCode) { 1319 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1320 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1321 i); 1322 if (thisEntryState.isStaging () && thisEntryState.getLanguageCode ().equals ( 1323 languageCode)) { 1324 return true; 1325 } 1326 } 1327 return false; 1328 } 1329 1330 1335 public boolean hasStagingEntryIgnoreLanguageCase (String languageCode) { 1336 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1337 ContentObjectEntryState thisEntryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1338 i); 1339 if (thisEntryState.isStaging () 1340 && (ContentObject.SHARED_LANGUAGE.equalsIgnoreCase(thisEntryState.getLanguageCode ()) 1341 || thisEntryState.getLanguageCode ().equalsIgnoreCase(languageCode))) { 1342 return true; 1343 } 1344 } 1345 return false; 1346 } 1347 1348 1356 public Map getLanguagesStates () { 1357 1358 int size = activeAndStagingEntryStates.size (); 1359 Map languageStates = new HashMap (); 1360 1361 for (int i = 0; i < size; i++) { 1363 ContentObjectEntryState entryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1364 i); 1365 1366 Integer curWorkflowState = (Integer ) languageStates.get(entryState.getLanguageCode ()); 1368 if (curWorkflowState == null || curWorkflowState.intValue() < entryState.getWorkflowState ()) { 1369 languageStates.put(entryState.getLanguageCode(), 1370 new Integer (entryState.getWorkflowState())); 1371 } 1372 1373 Map contentLanguageStates = getContentLanguageStates (entryState); 1376 if (contentLanguageStates != null) { 1377 Iterator contentLanguageKeysIter = contentLanguageStates.keySet(). 1378 iterator(); 1379 while (contentLanguageKeysIter.hasNext()) { 1380 String curLanguageKey = (String ) contentLanguageKeysIter. 1381 next(); 1382 languageStates.put(curLanguageKey, 1383 contentLanguageStates.get(curLanguageKey)); 1384 } 1385 } 1386 } 1387 1388 return languageStates; 1389 } 1390 1391 1392 1395 public SortedSet getActiveAndStagingEntryStates () { 1396 SortedSet entries = new TreeSet (); 1397 entries.addAll (activeAndStagingEntryStates); 1398 return entries; 1399 } 1400 1401 1407 public SortedSet getEntryStates () 1408 throws JahiaException { 1409 if (versioningEntryStates == null) { 1410 versioningEntryStates = ContentFieldDB.getInstance ().loadOldEntryStates (this); 1411 } 1412 SortedSet entryStates = new TreeSet (); 1413 entryStates.addAll (activeAndStagingEntryStates); 1414 entryStates.addAll (versioningEntryStates); 1415 return entryStates; 1416 } 1417 1418 1433 public void setWorkflowState (Set languageCodes, 1434 int newWorkflowState, 1435 ParamBean jParams, 1436 StateModificationContext stateModifContext) 1437 throws JahiaException { 1438 1439 Vector newActiveAndStagingEntryStates = new Vector (); 1440 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1441 ContentObjectEntryState entryState = (ContentObjectEntryState) activeAndStagingEntryStates.get ( 1442 i); 1443 if (entryState.isStaging () && 1445 (ContentObject.SHARED_LANGUAGE.equals (entryState.getLanguageCode ()) 1446 || languageCodes.contains (entryState.getLanguageCode ())) && 1447 (newWorkflowState >= ContentObjectEntryState.WORKFLOW_STATE_START_STAGING)) { 1448 ContentObjectEntryState newEntryState = 1451 new ContentObjectEntryState (newWorkflowState, 1452 entryState.getVersionID (), 1453 entryState.getLanguageCode ()); 1454 1455 this.changeEntryState (entryState, newEntryState, jParams, stateModifContext); 1456 1457 ContentFieldDB.getInstance ().changeDBEntryState (this, entryState, newEntryState); 1458 1459 newActiveAndStagingEntryStates.add (newEntryState); 1460 1461 } else { 1462 newActiveAndStagingEntryStates.add (entryState); 1463 } 1464 1465 } 1466 activeAndStagingEntryStates = newActiveAndStagingEntryStates; 1467 1468 ContentFieldTools.getInstance ().updateCache(this); 1471 1472 } 1473 1474 1486 public synchronized ContentField changeType (int aFieldType, 1487 String fieldValue, 1488 ParamBean jParams, 1489 EntrySaveRequest entrySaveRequest) 1490 throws JahiaException { 1491 1496 boolean versioningEnabled = ServicesRegistry.getInstance ().getJahiaVersionService ().isVersioningEnabled (jahiaID); 1497 Set languageCodes = new HashSet (); 1498 1499 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1501 ContentObjectEntryState actEntryState = 1502 (ContentObjectEntryState) activeAndStagingEntryStates.get (i); 1503 if (actEntryState.isStaging ()) { 1504 languageCodes.add (actEntryState.getLanguageCode ()); 1505 } 1506 if (actEntryState.isActive ()) { 1507 if (versioningEnabled) { 1509 ContentObjectEntryState backupEntryState = ContentFieldDB.getInstance ().backupDBValue (this, 1511 actEntryState); 1512 if (backupEntryState != null) { 1514 if (versioningEntryStates != null) { 1516 versioningEntryStates.add (backupEntryState); 1517 } 1518 StateModificationContext stateModifContext = new StateModificationContext ( 1520 new ContentFieldKey (getID ()), languageCodes); 1521 stateModifContext.setDescendingInSubPages (false); 1522 this.changeEntryState (actEntryState, backupEntryState, jParams, 1523 stateModifContext); 1524 } 1525 } else { 1526 this.deleteEntry (actEntryState); 1528 } 1529 ContentFieldDB.getInstance ().deleteDBValue (this, actEntryState); 1531 activeAndStagingEntryStates.remove (i); 1532 i -= 1; 1533 } 1534 } 1535 1536 this.deleteStagingEntries (languageCodes); 1538 1539 this.fieldType = aFieldType; 1541 this.preSet (fieldValue, entrySaveRequest); 1542 1543 return ContentFieldTools.getInstance ().getField (this.getID (), true); 1545 } 1546 1547 1564 public synchronized void serializeToXML (XmlWriter xmlWriter, 1565 XMLSerializationOptions xmlSerializationOptions, 1566 ParamBean paramBean) throws IOException { 1567 1568 String name = null; 1571 try { 1572 JahiaFieldDefinition definition = JahiaFieldDefinitionsRegistry.getInstance () 1573 .getDefinition (getFieldDefID ()); 1574 name = definition.getName (); 1575 } catch (JahiaException je) { 1576 logger.debug ( 1577 "Error while accessing field definition registry for field " + getID (), 1578 je); 1579 } 1580 1581 xmlWriter.writeEntity ("contentField"); 1582 if (name != null) { 1583 xmlWriter.writeAttribute ("name", name); 1584 } 1585 xmlWriter.writeAttribute ("type", this.getClass ().getName ()); 1586 xmlWriter.writeAttribute ("shared", new Boolean (isShared ()).toString ()); 1587 1588 1593 1594 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1595 ContentObjectEntryState entryState = 1596 (ContentObjectEntryState) activeAndStagingEntryStates.get (i); 1597 1598 xmlWriter.writeEntity ("entry"). 1599 writeAttribute ("language", entryState.getLanguageCode ()). 1600 writeAttribute ("workflowState", 1601 Integer.toString (entryState.getWorkflowState ())). 1602 writeAttribute ("versionID", Long.toString (entryState.getVersionID ())); 1603 1604 serializeContentToXML (xmlWriter, xmlSerializationOptions, entryState, paramBean); 1605 1606 xmlWriter.endEntity (); 1607 } 1608 1609 xmlWriter.endEntity (); 1610 1611 } 1612 1613 1616 private void deleteStagingEntries (Set languageCodes) 1617 throws JahiaException { 1618 ArrayList toBeRemoved = new ArrayList (); 1620 for (int i = 0; i < activeAndStagingEntryStates.size (); i++) { 1621 ContentObjectEntryState entryState = 1622 (ContentObjectEntryState) activeAndStagingEntryStates.get (i); 1623 if (languageCodes.contains (entryState.getLanguageCode ())) { 1624 if (entryState.isStaging ()) { 1625 toBeRemoved.add (entryState); 1626 } 1627 } 1628 } 1629 1630 Iterator toBeRemovedIter = toBeRemoved.iterator (); 1631 while (toBeRemovedIter.hasNext ()) { 1632 ContentObjectEntryState curEntryState = (ContentObjectEntryState) toBeRemovedIter.next (); 1633 deleteEntry (curEntryState); 1634 } 1635 } 1636 1637 1640 private synchronized void loadVersioningEntryStates () throws JahiaException { 1641 if (this.versioningEntryStates == null) { 1642 this.versioningEntryStates = ContentFieldDB.getInstance ().loadOldEntryStates (this); 1643 } 1644 } 1645 1646 public ArrayList getChilds (JahiaUser user, 1647 EntryLoadRequest loadRequest) 1648 throws JahiaException { 1649 return new ArrayList (); 1651 } 1652 1653 public ContentObject getParent (JahiaUser user, 1654 EntryLoadRequest loadRequest, 1655 String operationMode) 1656 throws JahiaException { 1657 if (getContainerID () > 0) { 1658 return ContentContainer.getContainer (getContainerID ()); 1659 } else { 1660 return ContentPage.getPage (getPageID ()); 1661 } 1662 } 1663 1664 private boolean hasEntry (EntryStateable entryState) { 1665 ContentObjectEntryState entryStateObject = new ContentObjectEntryState (entryState); 1666 if (entryStateObject.getWorkflowState () >= ContentObjectEntryState.WORKFLOW_STATE_ACTIVE) { 1667 int objectPos = activeAndStagingEntryStates.indexOf (entryStateObject); 1668 if (objectPos != -1) { 1669 return true; 1670 } 1671 } else { 1672 int objectPos = versioningEntryStates.indexOf (entryStateObject); 1673 if (objectPos != -1) { 1674 return true; 1675 } 1676 1677 } 1678 return false; 1679 } 1680 1681 1689 protected void copyEntry (EntryStateable fromEntryState, 1690 EntryStateable toEntryState) 1691 throws JahiaException { 1692 1693 ContentObjectEntryState fromE = new ContentObjectEntryState (fromEntryState); 1694 ContentObjectEntryState toE = new ContentObjectEntryState (toEntryState); 1695 if (this.isShared ()) { 1696 fromE = new ContentObjectEntryState (fromEntryState.getWorkflowState (), 1698 fromEntryState.getVersionID (), ContentObject.SHARED_LANGUAGE); 1699 1700 toE = new ContentObjectEntryState (toEntryState.getWorkflowState (), 1701 toEntryState.getVersionID (), ContentObject.SHARED_LANGUAGE); 1702 } 1703 1704 if (hasEntry (toE)) { 1705 deleteEntry (toE); 1706 } 1707 1708 ContentFieldDB.getInstance ().copyEntry (getID (), fromE, toE); 1709 if (toE.getWorkflowState () < ContentObjectEntryState.WORKFLOW_STATE_ACTIVE) { 1710 versioningEntryStates.add (toE); 1711 } else { 1712 activeAndStagingEntryStates.add (toE); 1713 } 1714 loadedDBValues.put (toE, getDBValue (toE)); 1715 } 1716 1717 1728 protected void deleteEntry (EntryStateable deleteEntryState) 1729 throws JahiaException { 1730 ContentFieldDB.getInstance ().deleteEntry (getID (), deleteEntryState); 1731 if (deleteEntryState.getWorkflowState () < ContentObjectEntryState.WORKFLOW_STATE_ACTIVE) { 1732 versioningEntryStates.remove (deleteEntryState); 1733 } else { 1734 activeAndStagingEntryStates.remove (deleteEntryState); 1735 } 1736 loadedDBValues.remove (deleteEntryState); 1737 } 1738 1739 1751 public RestoreVersionTestResults restoreVersion (JahiaUser user, 1752 String operationMode, 1753 ContentObjectEntryState entryState, 1754 boolean removeMoreRecentActive, 1755 RestoreVersionStateModificationContext stateModificationContext) 1756 throws JahiaException { 1757 1758 RestoreVersionTestResults result = 1759 super.restoreVersion(user,operationMode,entryState, 1760 removeMoreRecentActive,stateModificationContext); 1761 1762 notifyFieldUpdate(); 1763 ContentFieldTools.getInstance ().updateCache(this); 1766 1767 if (result.getStatus() != 1768 RestoreVersionTestResults.FAILED_OPERATION_STATUS ){ 1769 try { 1770 ServicesRegistry.getInstance().getJahiaSearchService() 1771 .removeFieldFromSearchEngine(this); 1772 1773 ServicesRegistry.getInstance().getJahiaSearchService() 1774 .indexField(this.getID(),false,Jahia.getThreadParamBean(), true); 1775 } catch ( Throwable t ){ 1776 logger.debug("Error re-indexing the field " + this.getID() 1777 + " after restore version operation.",t); 1778 } 1779 } 1780 return result; 1781 } 1782 1783 1796 public JahiaField getJahiaField (EntryLoadRequest entryLoadRequest) 1797 throws JahiaException { 1798 return ServicesRegistry.getInstance ().getJahiaFieldService (). 1799 contentFieldToJahiaField (this, entryLoadRequest); 1800 } 1801 1802 1807 private void notifyFieldUpdate(){ 1808 1809 FieldsChangeEventListener listener = ( 1810 FieldsChangeEventListener)JahiaListenersRegistry. 1811 getInstance () 1812 .getListener (FieldsChangeEventListener.class.getName ()); 1813 if ( listener != null ){ 1814 listener.notifyChange(this); 1815 } 1816 } 1817 1818 1825 public int getActiveVersionID () 1826 throws JahiaException { 1827 int versionID = 0; 1828 Iterator iterator = this.getActiveAndStagingEntryStates().iterator (); 1829 ContentObjectEntryState entryState = null; 1830 while (iterator.hasNext ()) { 1831 entryState = (ContentObjectEntryState) iterator.next (); 1832 if ( entryState.getWorkflowState() == EntryLoadRequest.ACTIVE_WORKFLOW_STATE 1833 && entryState.getVersionID() > versionID ){ 1834 versionID = entryState.getVersionID(); 1835 } 1836 } 1837 return versionID; 1838 } 1839 1840} 1841 | Popular Tags |