KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jahia > services > containers > ContentContainer


1 //
2
// ____.
3
// __/\ ______| |__/\. _______
4
// __ .____| | \ | +----+ \
5
// _______| /--| | | - \ _ | : - \_________
6
// \\______: :---| : : | : | \________>
7
// |__\---\_____________:______: :____|____:_____\
8
// /_____|
9
//
10
// . . . i n j a h i a w e t r u s t . . .
11
//
12

13 package org.jahia.services.containers;
14
15 import java.io.Serializable JavaDoc;
16 import java.util.*;
17
18 import org.jahia.content.ContainerDefinitionKey;
19 import org.jahia.content.ContentContainerKey;
20 import org.jahia.content.ContentObject;
21 import org.jahia.content.JahiaObject;
22 import org.jahia.content.ObjectKey;
23 import org.jahia.content.PageReferenceableInterface;
24 import org.jahia.data.containers.ContainersChangeEventListener;
25 import org.jahia.data.containers.JahiaContainer;
26 import org.jahia.data.fields.LoadFlags;
27 import org.jahia.data.fields.JahiaPageField;
28 import org.jahia.exceptions.JahiaException;
29 import org.jahia.params.ParamBean;
30 import org.jahia.registries.JahiaListenersRegistry;
31 import org.jahia.registries.ServicesRegistry;
32 import org.jahia.services.fields.ContentField;
33 import org.jahia.services.fields.ContentPageField;
34 import org.jahia.services.pages.ContentPage;
35 import org.jahia.services.usermanager.JahiaUser;
36 import org.jahia.services.version.ContentObjectEntryState;
37 import org.jahia.services.version.EntryLoadRequest;
38 import org.jahia.services.version.EntryStateable;
39 import org.jahia.services.version.RestoreVersionStateModificationContext;
40 import org.jahia.services.version.RestoreVersionTestResults;
41 import org.jahia.services.version.StateModificationContext;
42 import org.jahia.services.version.VersioningDifferenceStatus;
43 import org.jahia.utils.LanguageCodeConverters;
44
45 /**
46  * <p>Title: </p>
47  * <p>Description: </p>
48  * <p>Copyright: Copyright (c) 2002</p>
49  * <p>Company: </p>
50  *
51  * @author Serge Huber
52  * @version 1.0
53  */

54
55 public class ContentContainer extends ContentObject
56     implements PageReferenceableInterface, Cloneable JavaDoc, Serializable JavaDoc {
57
58     private static org.apache.log4j.Logger logger =
59             org.apache.log4j.Logger.getLogger (ContentContainer.class);
60
61     private ArrayList activeAndStagedEntryStates;
62     private ArrayList versionedEntryStates = null;
63     private int parentContainerListID;
64     private int aclID;
65
66     private int jahiaID;
67     private int pageID;
68     private int ctnDefID;
69
70     static {
71         JahiaObject.registerType (ContentContainerKey.CONTAINER_TYPE,
72                 ContentContainer.class.getName ());
73     }
74
75     /**
76      * Return the pageID
77      *
78      * @return the page identification number
79      */

80     public int getPageID () {
81         return this.pageID;
82     }
83
84     public int getSiteID() {
85         return this.jahiaID;
86     }
87
88     /**
89      * Returns the ContentPage ancestor.
90      *
91      * @return Return the ContentPage ancestor.
92      */

93     public ContentPage getPage () throws JahiaException {
94         return ContentPage.getPage (this.getPageID ());
95     }
96
97     /**
98      * Returns the Container definition id for this Content object.
99      *
100      * @param loadRequest not used, can be null
101      *
102      * @return
103      */

104     public int getDefinitionID (EntryLoadRequest loadRequest) {
105         return this.ctnDefID;
106     }
107
108     /**
109      * Returns the Definition Key of the Content Definition for this Content object.
110      * This is a ContainerDefinition
111      *
112      * @param loadRequest
113      *
114      * @return
115      */

116     public ObjectKey getDefinitionKey (EntryLoadRequest loadRequest) {
117         int defID = getDefinitionID (loadRequest);
118         ContainerDefinitionKey ctnDefKey = (ContainerDefinitionKey)
119                 ContainerDefinitionKey.getChildInstance (String.valueOf (defID));
120         return ctnDefKey;
121     }
122
123     public static ContentObject getChildInstance (String JavaDoc IDInType) {
124         try {
125             return getContainer (Integer.parseInt (IDInType));
126         } catch (JahiaException je) {
127             logger.debug ("Error retrieving container instance for id : " + IDInType, je);
128         }
129         return null;
130     }
131
132     protected ContentContainer (int ID, int aJahiaID, int aPageID, int aCtnDefID, int listID,
133                                 int anAclID, ArrayList anActiveAndStagedEntryStates) {
134         super (new ContentContainerKey (ID));
135         this.jahiaID = aJahiaID;
136         this.pageID = aPageID;
137         this.ctnDefID = aCtnDefID;
138         this.parentContainerListID = listID;
139         this.activeAndStagedEntryStates = anActiveAndStagedEntryStates;
140         this.aclID = anAclID;
141     }
142
143     /**
144      * Get an enumeration of active and staged entry state.
145      */

146     public SortedSet getActiveAndStagingEntryStates () {
147         SortedSet entries = new TreeSet ();
148         entries.addAll (activeAndStagedEntryStates);
149         return entries;
150     }
151     
152     public SortedSet getEntryStates ()
153             throws JahiaException {
154         SortedSet resultSet = new TreeSet ();
155         if (versionedEntryStates == null) {
156             versionedEntryStates =
157                     ContentContainerDB.getInstance ().getVersionedEntryStates (getID (), false);
158         }
159         resultSet.addAll (activeAndStagedEntryStates);
160         resultSet.addAll (versionedEntryStates);
161         return resultSet;
162     }
163
164     public ArrayList getChilds(JahiaUser user, EntryLoadRequest loadRequest) throws JahiaException {
165         return getChilds(user, loadRequest, ContainerFactoryProxy.LOAD_FIELD_AND_SUBCONTAINER_LISTS);
166     }
167     
168     public ArrayList getChilds (JahiaUser user,
169                                 EntryLoadRequest loadRequest,
170                                 int loadFlag)
171             throws JahiaException {
172
173         ArrayList resultList = new ArrayList ();
174         if ((loadFlag & ContainerFactoryProxy.LOAD_FIELDS) != 0) {
175             Vector fieldIDs = ContentContainerTools.getInstance().getFieldIDsByContainer(getID(), loadRequest);
176
177             Enumeration fieldIDEnum = fieldIDs.elements();
178             if (fieldIDEnum.hasMoreElements()) {
179                 int fieldID = ((Integer JavaDoc) fieldIDEnum.nextElement()).intValue();
180                 ContentField currentField = ContentField.getFieldFromCacheOnly(fieldID);
181                 if (currentField == null) {
182                     ContentField.preloadActiveOrStagedFieldsByContainerID(getID());
183                 }
184                 currentField = ContentField.getField(fieldID);
185                 if (currentField != null) {
186                     resultList.add(currentField);
187                 }
188
189                 while (fieldIDEnum.hasMoreElements()) {
190                     fieldID = ((Integer JavaDoc) fieldIDEnum.nextElement()).intValue();
191                     currentField = ContentField.getField(fieldID);
192                     if (currentField != null) {
193                         resultList.add(currentField);
194                     }
195                 }
196             }
197         }
198         if ((loadFlag & ContainerFactoryProxy.LOAD_SUBCONTAINER_LISTS) != 0) {
199             // now let's check that the case of subcontainer lists. If they
200
// cannot be marked for deletion, neither can this container.
201
Enumeration subContainerListIDEnum = JahiaContainerUtilsDB.getInstance().getContainerSubContainerListIDs(
202                     getID(), loadRequest).elements();
203             while (subContainerListIDEnum.hasMoreElements()) {
204                 Integer JavaDoc curContainerListID = (Integer JavaDoc) subContainerListIDEnum.nextElement();
205                 ContentContainerList curContainerList = ContentContainerList.getContainerList(curContainerListID
206                         .intValue());
207                 if (curContainerList != null) {
208                     resultList.add(curContainerList);
209                 }
210             }
211         }
212         return resultList;
213     }
214
215     public ContentObject getParent (JahiaUser user,
216                                     EntryLoadRequest loadRequest,
217                                     String JavaDoc operationMode)
218             throws JahiaException {
219         return ContentContainerList.getContainerList (parentContainerListID);
220     }
221
222     public static ContentContainer getContainer (int containerID)
223             throws JahiaException {
224         return ContentContainerTools.getInstance()
225             .getContainer(containerID);
226     }
227
228     /**
229      * If loadFromDB is true, force reload from db
230      * @param containerID
231      * @param loadFromDB
232      * @return
233      * @throws JahiaException
234      */

235     public static ContentContainer getContainer (int containerID, boolean loadFromDB)
236             throws JahiaException {
237         return ContentContainerTools.getInstance()
238             .getContainer(containerID,loadFromDB);
239     }
240
241     /**
242      * Returns properties of the specified container.
243      *
244      * @param containerID the Id of the container
245      * @return properties of the specified container
246      * @throws JahiaException If the container doesn't exist, or there's a DB
247      * error
248      */

249       public static Properties getContainerProperties(int containerID)
250         throws JahiaException
251       {
252         return ContentContainerTools.getInstance().getContainerProperties(
253           containerID);
254       }
255     
256     public RestoreVersionTestResults isValidForRestore (JahiaUser user,
257                                                         String JavaDoc operationMode,
258                                                         ContentObjectEntryState entryState,
259                                                         boolean removeMoreRecentActive,
260                                                         StateModificationContext stateModificationContext)
261             throws JahiaException {
262         // first let's check if we have entries that correspond for this
263
// container
264
RestoreVersionTestResults opResult = new RestoreVersionTestResults ();
265         opResult.merge (
266                 super.isValidForRestore (user, operationMode, entryState,
267                         removeMoreRecentActive, stateModificationContext));
268         if (opResult.getStatus () == RestoreVersionTestResults.FAILED_OPERATION_STATUS) {
269             return opResult;
270         }
271
272         // now let's check for the children of this container. If only
273
// one of them fails, we fail the whole container.
274
ArrayList locales = new ArrayList ();
275         locales.add (
276                 LanguageCodeConverters.languageCodeToLocale (ContentObject.SHARED_LANGUAGE));
277         locales.add (LanguageCodeConverters.languageCodeToLocale (entryState.getLanguageCode ()));
278         EntryLoadRequest loadRequest = new EntryLoadRequest (entryState.getWorkflowState (),
279                 entryState.getVersionID (), locales);
280         ArrayList children = getChilds (user, loadRequest);
281         ListIterator childrenIter = children.listIterator ();
282         while (childrenIter.hasNext ()) {
283             ContentObject curChild = (ContentObject) childrenIter.next ();
284             opResult.merge (
285                     curChild.isValidForRestore (user, operationMode, entryState,
286                             removeMoreRecentActive, stateModificationContext));
287         }
288         return opResult;
289     }
290
291     private boolean hasEntry (EntryStateable entryState)
292             throws JahiaException {
293         getEntryStates (); // this insures we have the loaded the versioned
294
// entry states
295
ContentObjectEntryState entryStateObject = new ContentObjectEntryState (entryState);
296         if (entryStateObject.getWorkflowState () >= ContentObjectEntryState.WORKFLOW_STATE_ACTIVE) {
297             int objectPos = activeAndStagedEntryStates.indexOf (entryStateObject);
298             if (objectPos != -1) {
299                 return true;
300             }
301         } else {
302             int objectPos = versionedEntryStates.indexOf (entryStateObject);
303             if (objectPos != -1) {
304                 return true;
305             }
306
307         }
308         return false;
309     }
310
311     private void removeEntryFromCaches (EntryStateable entryState)
312             throws JahiaException {
313         getEntryStates (); // this insures we have the loaded the versioned
314
// entry states
315
ContentObjectEntryState entryStateObject = new ContentObjectEntryState (entryState);
316         if (entryStateObject.getWorkflowState () >= ContentObjectEntryState.WORKFLOW_STATE_ACTIVE) {
317             int objectPos = activeAndStagedEntryStates.indexOf (entryStateObject);
318             if (objectPos != -1) {
319                 activeAndStagedEntryStates.remove (objectPos);
320             }
321         } else {
322             int objectPos = versionedEntryStates.indexOf (entryStateObject);
323             if (objectPos != -1) {
324                 versionedEntryStates.remove (objectPos);
325             }
326
327         }
328     }
329
330     /**
331      * This method is called when a entry should be copied into a new entry
332      * it is called when an old version -> active version move occurs
333      * This method should not write/change the DBValue, the service handles that.
334      *
335      * @param fromEntryState the entry state that is currently was in the database
336      * @param toEntryState the entry state that will be written to the database
337      */

338     protected void copyEntry (EntryStateable fromEntryState,
339                               EntryStateable toEntryState)
340             throws JahiaException {
341
342         ContentObjectEntryState fromE = new ContentObjectEntryState (fromEntryState);
343         ContentObjectEntryState toE = new ContentObjectEntryState (toEntryState);
344         if (this.isShared ()) {
345             // swith to Shared lang
346
fromE = new ContentObjectEntryState (fromEntryState.getWorkflowState (),
347                     fromEntryState.getVersionID (), ContentObject.SHARED_LANGUAGE);
348
349             toE = new ContentObjectEntryState (toEntryState.getWorkflowState (),
350                     toEntryState.getVersionID (), ContentObject.SHARED_LANGUAGE);
351         }
352
353         if (hasEntry (toE)) {
354             deleteEntry (toE);
355         }
356
357         ContentContainerDB.getInstance ().copyEntry (getID (), fromE, toE);
358
359         if (toE.getWorkflowState () >= ContentObjectEntryState.WORKFLOW_STATE_ACTIVE) {
360             activeAndStagedEntryStates.add (toE);
361         } else {
362             versionedEntryStates.add (toE);
363         }
364     }
365
366     /**
367      * This method is called when an entry should be deleted for real.
368      * It is called when a object is deleted, and versioning is disabled, or
369      * when staging values are undone.
370      * For a bigtext content fields for instance, this method should delete
371      * the text file corresponding to the field entry
372      *
373      * @param deleteEntryState the entry state to delete
374      */

375     protected void deleteEntry (EntryStateable deleteEntryState)
376             throws JahiaException {
377         removeEntryFromCaches (deleteEntryState);
378         ContentContainerDB.getInstance ().deleteEntry (getID (), deleteEntryState);
379     }
380
381     /**
382      * Mark a content object's language for deletion. Does nothing if the
383      * language doesn't exist, but if it exists only in staging, the staging
384      * entry is removed.
385      *
386      * @param user the user performing the operation, in order to perform
387      * rights checks
388      * @param languageCode the language to mark for deletion
389      * @param stateModificationContext contains the start object of the
390      * operation, as well as settings such as recursive descending in sub pages,
391      * and content object stack trace.
392      *
393      * @throws JahiaException raised if there was a problem while marking the
394      * content object for deletion (mostly related to communication with the
395      * database)
396      */

397     public void markLanguageForDeletion (JahiaUser user,
398                                          String JavaDoc languageCode,
399                                          StateModificationContext
400             stateModificationContext)
401             throws JahiaException {
402         ServicesRegistry.getInstance ().getJahiaContainersService ()
403                 .markContainerLanguageForDeletion (getID (), user, languageCode,
404                         stateModificationContext);
405
406         notifyContainerUpdate(ContainersChangeEventListener.CONTAINER_DELETED);
407     }
408
409     public int getAclID () {
410         return aclID;
411     }
412
413     public RestoreVersionTestResults restoreVersion (JahiaUser user,
414                                                      String JavaDoc operationMode,
415                                                      ContentObjectEntryState entryState,
416                                                      boolean removeMoreRecentActive,
417                                                      RestoreVersionStateModificationContext
418                                                      stateModificationContext)
419             throws JahiaException {
420
421         RestoreVersionTestResults opResult = new RestoreVersionTestResults ();
422
423        // retrieve the exact archive entry state
424
getClosestVersionedEntryState(entryState);
425        boolean isDeleted = this.isDeletedOrDoesNotExist(entryState.getVersionID());
426
427        ArrayList locales = new ArrayList();
428        locales.add(LanguageCodeConverters.languageCodeToLocale(entryState.getLanguageCode()));
429        EntryLoadRequest loadRequest = null;
430
431         ArrayList children = null;
432         if ( !isDeleted ){
433            // 1. First restore archive
434
// load archive to restore
435
loadRequest = new EntryLoadRequest(entryState.
436                                               getWorkflowState(),
437                                               entryState.getVersionID(),
438                                               locales);
439            children = getChilds(user, loadRequest);
440
441            // For performance issue, we don't want to restore twice objects.
442
ArrayList processedChilds = new ArrayList();
443
444            ListIterator childrenIter = children.listIterator();
445            while (childrenIter.hasNext()) {
446                ContentObject curChild = (ContentObject) childrenIter.next();
447                opResult.merge(curChild.restoreVersion(user,
448                    operationMode, entryState, (removeMoreRecentActive),
449                    stateModificationContext));
450                processedChilds.add(curChild.getObjectKey().toString());
451            }
452
453            // 2.Second, remove more recent data
454
// We don't need to apply "remove more recent data here, because the overriden
455
// super.restoreVersion call will automatically mark this container for delete
456
// if it is more recent and therefore mark its fields too.
457
if ( removeMoreRecentActive ){
458                // we need to check if this container doesn't contain a page that is
459
// only in staging --> we won't re
460

461                // load staging or active to perform a restore which will mark them for delete
462
loadRequest =
463                    new EntryLoadRequest(EntryLoadRequest.STAGING_WORKFLOW_STATE,
464                        0, locales);
465                children = getChilds(user, loadRequest);
466                childrenIter = children.listIterator();
467
468                while (childrenIter.hasNext()) {
469                    ContentObject curChild = (ContentObject) childrenIter.next();
470
471                    if (!processedChilds.contains(curChild.getObjectKey().
472                                                  toString())) {
473                        opResult.merge(curChild.restoreVersion(user,
474                            operationMode, entryState, removeMoreRecentActive,
475                            stateModificationContext));
476                    }
477                }
478            }
479        }
480
481        // we need to ensure that synchronize this ContentContainer states here
482
// because childs ContentPageField could change it ( restore and page move
483
// issue ).
484
ContentContainer contentContainer
485                = ContentContainer.getContainer(this.getID(),true);
486        contentContainer.getEntryStates();
487        this.activeAndStagedEntryStates =
488                new ArrayList(contentContainer.getActiveAndStagingEntryStates());
489        this.versionedEntryStates =
490                new ArrayList(contentContainer.versionedEntryStates);
491
492        opResult.merge(super.restoreVersion(user, operationMode, entryState,
493                removeMoreRecentActive,
494                stateModificationContext));
495
496         // check to avoid link container without page
497
if (stateModificationContext.getContainerPageChildId() == -1){
498             Set stagedStates = this.getStagingLanguages(false);
499             if ( !stagedStates.isEmpty() ){
500                 loadRequest = new EntryLoadRequest(EntryLoadRequest.STAGING_WORKFLOW_STATE, 0, locales);
501                 loadRequest.setWithMarkedForDeletion(true);
502                 children = this.getChilds(user,loadRequest);
503                 Iterator it = children.iterator();
504                 boolean processLive = true;
505                 RestoreVersionStateModificationContext smc = new RestoreVersionStateModificationContext(stateModificationContext.getStartObject(),stateModificationContext.getLanguageCodes(),stateModificationContext.getEntryState());
506                 smc.pushAllLanguages(true);
507                 while ( it.hasNext() ){
508                     ContentObject curChild = (ContentObject) it.next();
509                     if ( curChild instanceof ContentPageField){
510                         JahiaPageField jahiaPageField = (JahiaPageField)((ContentPageField)curChild).getJahiaField(loadRequest);
511                         try {
512                             int pageId = Integer.parseInt(jahiaPageField.getValue());
513                             if ( pageId != -1 ){
514                                 ContentPage contentPage = ContentPage.getPage(pageId);
515                                 if ( contentPage != null ){
516                                     if ( !contentPage.hasActiveOrStagingEntries() || contentPage.isMarkedForDelete() ) {
517                                         this.markLanguageForDeletion(user,ContentObject.SHARED_LANGUAGE,stateModificationContext);
518                                     } else {
519                                         // check for moved page
520
ContentPageField pageField = (ContentPageField)contentPage.getParent(EntryLoadRequest.STAGED);
521                                         if ( pageField != null && pageField.getContainerID() != this.getID() ){
522                                             this.markLanguageForDeletion(user,ContentObject.SHARED_LANGUAGE,stateModificationContext);
523                                         }
524                                     }
525
526                                 }
527                             }
528                         } catch ( Throwable JavaDoc t ){
529                         }
530                         processLive = false;
531                         break;
532                     }
533                 }
534                 if ( processLive ){
535                     loadRequest = new EntryLoadRequest(EntryLoadRequest.VERSIONED_WORKFLOW_STATE,
536                             ServicesRegistry.getInstance()
537                                 .getJahiaVersionService().getCurrentVersionID(), locales);
538                     loadRequest.setWithDeleted(true);
539                     children = this.getChilds(user,loadRequest);
540                     it = children.iterator();
541                     while ( it.hasNext() ){
542                         ContentObject curChild = (ContentObject) it.next();
543                         if ( curChild instanceof ContentPageField ){
544                             JahiaPageField jahiaPageField = (JahiaPageField)((ContentPageField)curChild).getJahiaField(loadRequest);
545                             try {
546                                 int pageId = Integer.parseInt(jahiaPageField.getValue());
547                                 if ( pageId != -1 ){
548                                     ContentPage contentPage = ContentPage.getPage(pageId);
549                                     if ( contentPage != null ){
550                                         if ( !contentPage.hasActiveOrStagingEntries() || contentPage.isMarkedForDelete() ) {
551                                             this.markLanguageForDeletion(user,ContentObject.SHARED_LANGUAGE,stateModificationContext);
552                                         } else {
553                                             // check for moved page
554
ContentPageField pageField = (ContentPageField)contentPage.getParent(EntryLoadRequest.STAGED);
555                                             if ( pageField != null && pageField.getContainerID() != this.getID() ){
556                                                 this.markLanguageForDeletion(user,ContentObject.SHARED_LANGUAGE,stateModificationContext);
557                                             }
558                                         }
559                                     }
560                                 }
561                             } catch ( Throwable JavaDoc t ){
562                             }
563                             break;
564                         }
565                     }
566                 }
567             }
568         }
569         
570         notifyContainerUpdate(ContainersChangeEventListener.CONTAINER_UPDATED);
571
572         return opResult;
573     }
574
575     /**
576      * Is this kind of object shared (i.e. not one version for each language, but one version for every language)
577      */

578     public boolean isShared () {
579         return true;
580     }
581
582     /**
583      * Return the parent container list ID.
584      *
585      * @return This parent container list ID.
586      */

587     public int getParentContainerListID () {
588         return this.parentContainerListID;
589     }
590
591     public JahiaContainer getJahiaContainer (ParamBean jParams, EntryLoadRequest loadRequest)
592             throws JahiaException {
593         return ServicesRegistry.getInstance ().getJahiaContainersService ().loadContainer (
594                 getID (), LoadFlags.ALL, jParams, loadRequest);
595     }
596
597     /**
598      * This method removes all the data related to the staging mode of this
599      * container, effectively "undoing" all the changes and returning to the
600      * active values. Doesn't descent in childs.
601      *
602      * @throws JahiaException in the case there are errors accessing the
603      * persistant storage system.
604      */

605     public synchronized void undoStaging (ParamBean jParams)
606             throws JahiaException {
607
608         // first we construct a vector of all the staging versions
609
Vector stagedEntryStates = new Vector ();
610         for (int i = 0; i < activeAndStagedEntryStates.size (); i++) {
611             ContentObjectEntryState entryState = (ContentObjectEntryState) activeAndStagedEntryStates.get (
612                     i);
613             // ok huston, we have a staged version here, let's advise...
614
if (entryState.isStaging ()) {
615                 stagedEntryStates.add (entryState);
616             }
617         }
618
619         // now let's use that vector to destroy all staged versions
620
for (int i = 0; i < stagedEntryStates.size (); i++) {
621             ContentObjectEntryState curEntryState = (ContentObjectEntryState) stagedEntryStates.get (
622                     i);
623
624             // first we call the field to destroy it's related data
625
this.deleteEntry (curEntryState);
626         }
627         notifyContainerUpdate(ContainersChangeEventListener.CONTAINER_UPDATED);
628     }
629
630     /**
631      * Returns the status of this container, indicating if the restore will
632      * remove it, restore it or keep unchanged.
633      * oldVersion and newVersion can be : 0 -> staged entry,
634      * 1 -> active entry,
635      * x -> archive entry
636      * -1 -> staging marked for delete
637      *
638      * @param oldVersion
639      * @param newVersion
640      * @param exactRestore if <code>true</code>, remove more recent data and apply
641      * archive deleted status when restoring
642      *
643      * @return
644      */

645     public int getRestoreStatus (int oldVersion, int newVersion, boolean exactRestore)
646             throws JahiaException {
647
648         int status = VersioningDifferenceStatus.UNCHANGED;
649
650         // resolve old entry state
651
ContentObjectEntryState oldEntryState =
652                 ContentObjectEntryState.getEntryState (oldVersion,
653                         ContentObject.SHARED_LANGUAGE);
654         oldEntryState = this.getEntryState (oldEntryState, false, false);
655
656         // resolve new entry state
657
ContentObjectEntryState newEntryState =
658                 ContentObjectEntryState.getEntryState (newVersion,
659                         ContentObject.SHARED_LANGUAGE);
660         newEntryState = this.getEntryState (newEntryState, false, false);
661
662         status = getRestoreStatus (oldEntryState, newEntryState, exactRestore);
663         return status;
664     }
665
666     /**
667      * Returns the status of this container, indicating if the restore will
668      * remove it, restore it or keep unchanged.
669      *
670      * @param oldEntryState
671      * @param newEntryState
672      * @param exactRestore
673      *
674      * @return
675      */

676     public int getRestoreStatus (ContentObjectEntryState oldEntryState,
677                                  ContentObjectEntryState newEntryState,
678                                  boolean exactRestore) {
679
680         int status = VersioningDifferenceStatus.UNCHANGED;
681         if (oldEntryState == null && newEntryState == null) {
682             return status;
683         }
684
685         if (oldEntryState == null) {
686             //doesn't exist at old entry version
687
if (exactRestore) {
688                 if (newEntryState != null) {
689                     if ((newEntryState.getWorkflowState () == -1)
690                             || (newEntryState.isStaging () && newEntryState.getVersionID ()
691                             == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED)) {
692                         status = VersioningDifferenceStatus.CURRENTLY_DELETED_AND_NOT_RESTORED;
693                     } else {
694                         // to be removed because archive doesn't exist at all.
695
status = VersioningDifferenceStatus.TO_BE_REMOVED;
696                     }
697                 }
698             } else {
699                 if (newEntryState != null) {
700                     if ((newEntryState.getWorkflowState () == -1)
701                             || (newEntryState.isStaging () && newEntryState.getVersionID ()
702                             == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED)) {
703                         status = VersioningDifferenceStatus.CURRENTLY_DELETED_AND_NOT_RESTORED;
704                     } else {
705                         status = VersioningDifferenceStatus.ADDED;
706                     }
707                 } else {
708                     status = VersioningDifferenceStatus.ADDED;
709                 }
710             }
711         } else {
712             if (newEntryState == null) {
713                 if (oldEntryState.getWorkflowState ()
714                         == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED) {
715                     status = VersioningDifferenceStatus.CURRENTLY_DELETED_AND_NOT_RESTORED;
716                 }
717             } else {
718                 if (exactRestore) {
719                     if (oldEntryState.getWorkflowState ()
720                             == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED) {
721                         if (newEntryState.getWorkflowState ()
722                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED
723                                 || (newEntryState.isStaging () && newEntryState.getVersionID ()
724                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED)) {
725                             status =
726                                     VersioningDifferenceStatus.CURRENTLY_DELETED_AND_NOT_RESTORED;
727                         } else {
728                             // to be removed because archive status == delete
729
status = VersioningDifferenceStatus.TO_BE_REMOVED;
730                         }
731                     } else {
732                         if (newEntryState.getWorkflowState ()
733                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED
734                                 || (newEntryState.isStaging ()
735                                 && newEntryState.getVersionID ()
736                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED)) {
737                             // actually deleted , but will be restored
738
status = VersioningDifferenceStatus.TO_BE_RESTORED;
739                         } else {
740                             status = VersioningDifferenceStatus.TO_BE_UPDATED;
741                         }
742                     }
743                 } else {
744                     if (oldEntryState.getWorkflowState ()
745                             == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED) {
746                         if (newEntryState.getWorkflowState ()
747                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED
748                                 || (newEntryState.isStaging () && newEntryState.getVersionID ()
749                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED)) {
750                             status =
751                                     VersioningDifferenceStatus.CURRENTLY_DELETED_AND_NOT_RESTORED;
752                         }
753                     } else {
754                         if (newEntryState.getWorkflowState ()
755                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED
756                                 || (newEntryState.isStaging ()
757                                 && newEntryState.getVersionID ()
758                                 == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED)) {
759                             // actually deleted , but will be restored
760
status = VersioningDifferenceStatus.TO_BE_RESTORED;
761                         } else {
762                             status = VersioningDifferenceStatus.TO_BE_UPDATED;
763                         }
764                     }
765                 }
766             }
767         }
768         return status;
769     }
770
771     /**
772      * Returns the status of this container, indicating if an activation of staging content will
773      * remove it, update it or keep unchanged.
774      *
775      * @return
776      */

777     public int getStagingStatus ()
778             throws JahiaException {
779
780         int status = VersioningDifferenceStatus.UNCHANGED;
781
782         // resolve active entry state
783
ContentObjectEntryState activeEntryState =
784                 ContentObjectEntryState.getEntryState (1,
785                         ContentObject.SHARED_LANGUAGE);
786         activeEntryState = this.getEntryState (activeEntryState, false, false);
787
788         // resolve staging entry state
789
ContentObjectEntryState stagingEntryState =
790                 ContentObjectEntryState.getEntryState (0,
791                         ContentObject.SHARED_LANGUAGE);
792         stagingEntryState = this.getEntryState (stagingEntryState, false, false);
793
794         if (stagingEntryState != null) {
795             if (stagingEntryState.getVersionID ()
796                     == ContentObjectEntryState.WORKFLOW_STATE_VERSIONING_DELETED) {
797                 status = VersioningDifferenceStatus.TO_BE_REMOVED;
798             } else {
799                 if (activeEntryState == null) {
800                     status = VersioningDifferenceStatus.ADDED;
801                 } else {
802                     status = VersioningDifferenceStatus.TO_BE_UPDATED;
803                 }
804             }
805         }
806         return status;
807     }
808
809     /**
810      * Returns the workflow state of all the languages contained in this container.
811      * This returns the state of both the active and staged languages, the
812      * staging version taking priority over the active for a given language.
813      * This method does NOT go down into the fields and sub-containers lists
814      * to retrieve their state !
815      *
816      * @return an HashMap that contains the language code String as the key,
817      * and the current workflow state of the language is the value
818      */

819     public Map getLanguagesStatesWithoutChilds () {
820
821         int size = activeAndStagedEntryStates.size ();
822         Map languageStates = new HashMap ();
823
824         // first let's get all the active languages in the map.
825
for (int i = 0; i < size; i++) {
826             ContentObjectEntryState entryState = (ContentObjectEntryState) activeAndStagedEntryStates.get (
827                     i);
828             // ok huston, we have an active entry
829
if (!entryState.isStaging ()) {
830                 languageStates.put (entryState.getLanguageCode (),
831                         new Integer JavaDoc (entryState.getWorkflowState ()));
832             }
833         }
834
835         // now let's overwrite the languages that have a staged state.
836
for (int i = 0; i < size; i++) {
837             ContentObjectEntryState entryState = (ContentObjectEntryState) activeAndStagedEntryStates.get (
838                     i);
839             // ok huston, we have a staged entry here, let's advise...
840
if (entryState.isStaging ()) {
841                 languageStates.put (entryState.getLanguageCode (),
842                         new Integer JavaDoc (entryState.getWorkflowState ()));
843             }
844         }
845
846         return languageStates;
847     }
848
849     /**
850      * update ContainersChangeEventListener listener
851      *
852      * @param operation @see ContainersChangeEventListener
853      */

854     public static void notifyContainerUpdate(int containerID, String JavaDoc operation){
855
856         // remove from cache
857
ContentContainerTools.getInstance().invalidateContainerFromCache(containerID);
858         try {
859             // load from db
860
ContentContainer contentContainer = getContainer(containerID);
861             if ( contentContainer != null ){
862                 contentContainer.notifyContainerUpdate(operation,false);
863             }
864         } catch ( JahiaException je ){
865             logger.debug("Exception occured on ContentContainer id=" + containerID,
866                          je);
867         }
868     }
869
870     /**
871      * update ContainersChangeEventListener listener
872      *
873      * @param operation @see ContainersChangeEventListener
874      */

875     private void notifyContainerUpdate(String JavaDoc operation){
876         notifyContainerUpdate(operation,true);
877     }
878
879     /**
880      * update ContainersChangeEventListener listener
881      *
882      * @param operation @see ContainersChangeEventListener
883      */

884     private void notifyContainerUpdate(String JavaDoc operation, boolean updateCache){
885
886         if ( updateCache ){
887             // remove from cache
888
ContentContainerTools.getInstance().invalidateContainerFromCache(this.getID());
889             ServicesRegistry.getInstance ().getJahiaContainersService ()
890                 .invalidateContainerFromCache(this.getID());
891             JahiaContainerUtilsDB.getInstance().invalidateCtnIdsByCtnListCache(this.getParentContainerListID());
892         }
893         ContainersChangeEventListener listener = (
894                 ContainersChangeEventListener)JahiaListenersRegistry.
895                 getInstance ()
896                 .getListener (ContainersChangeEventListener.class.getName ());
897         if ( listener != null ){
898             listener.notifyChange(this,operation);
899         }
900     }
901
902     //-------------------------------------------------------------------------
903
/**
904      * Clone
905      */

906     public Object JavaDoc clone () {
907         ArrayList localActiveAndStagedEntryStates = new ArrayList();
908         if ( this.activeAndStagedEntryStates != null ){
909             localActiveAndStagedEntryStates = (ArrayList)
910                 this.activeAndStagedEntryStates.clone();
911         }
912         ContentContainer clone =
913             new ContentContainer (this.getID(),this.jahiaID,this.getPageID(),
914                                   this.ctnDefID, this.parentContainerListID,
915                                   this.aclID, localActiveAndStagedEntryStates);
916         if ( this.versionedEntryStates != null ){
917             clone.versionedEntryStates =
918                 (ArrayList)this.versionedEntryStates.clone();
919         }
920         return clone;
921     }
922
923     public static void invalidateContainerCache(int containerID) {
924         ContentContainerTools.getInstance().invalidateContainerFromCache(containerID);
925     }
926
927 }
928
929
Popular Tags