001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     <a href="mailto:grenard@nuxeo.com">Guillaume</a>
018 */
019package org.nuxeo.ecm.collections.jsf.actions;
020
021import java.io.Serializable;
022import java.util.ArrayList;
023import java.util.List;
024
025import javax.faces.context.ExternalContext;
026import javax.faces.context.FacesContext;
027import javax.faces.event.ActionEvent;
028
029import org.apache.commons.lang.StringUtils;
030import org.apache.commons.logging.Log;
031import org.apache.commons.logging.LogFactory;
032import org.jboss.seam.Component;
033import org.jboss.seam.ScopeType;
034import org.jboss.seam.annotations.Name;
035import org.jboss.seam.annotations.Scope;
036import org.jboss.seam.annotations.intercept.BypassInterceptors;
037import org.jboss.seam.core.Events;
038import org.jboss.seam.faces.FacesMessages;
039import org.jboss.seam.international.Messages;
040import org.jboss.seam.international.StatusMessage;
041import org.nuxeo.ecm.collections.api.CollectionConstants;
042import org.nuxeo.ecm.collections.api.CollectionManager;
043import org.nuxeo.ecm.core.api.CoreSession;
044import org.nuxeo.ecm.core.api.DocumentModel;
045import org.nuxeo.ecm.core.api.DocumentNotFoundException;
046import org.nuxeo.ecm.core.api.DocumentRef;
047import org.nuxeo.ecm.core.api.IdRef;
048import org.nuxeo.ecm.core.api.PropertyException;
049import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
050import org.nuxeo.ecm.webapp.documentsLists.DocumentsListsManager;
051import org.nuxeo.ecm.webapp.helpers.EventNames;
052import org.nuxeo.runtime.api.Framework;
053
054/**
055 * @since 5.9.3
056 */
057@Name("collectionActions")
058@Scope(ScopeType.PAGE)
059@BypassInterceptors
060public class CollectionActionsBean implements Serializable {
061
062    private static final long serialVersionUID = 1L;
063
064    public static final String COLLECTION_CURRENT_SELECTION = "COLLECTION_CURRENT_SELECTION";
065
066    public static final String DOCUMENT_ADDED_TO_COLLECTION_EVENT = "documentAddedToCollection";
067
068    public static final String DOCUMENT_REMOVED_FROM_COLLECTION_EVENT = "documentRemovedFromCollection";
069
070    private static final Log log = LogFactory.getLog(CollectionActionsBean.class);
071
072    protected static void addFacesMessage(StatusMessage.Severity severity, String message, String arguments) {
073        final FacesMessages facesMessages = (FacesMessages) Component.getInstance("facesMessages", true);
074        facesMessages.add(severity, Messages.instance().get(message), Messages.instance().get(arguments));
075    }
076
077    private List<String> docUidsToBeAdded;
078
079    private String newDescription;
080
081    private String newTitle;
082
083    private DocumentModel selectedCollection;
084
085    private String selectedCollectionUid;
086
087    public void addCurrentDocumentToSelectedCollection() {
088        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
089        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
090        if (currentDocument != null) {
091            final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
092            final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
093            if (isCreateNewCollection()) {
094                collectionManager.addToNewCollection(getNewTitle(), getNewDescription(), currentDocument, session);
095            } else {
096                collectionManager.addToCollection(getSelectedCollection(), currentDocument, session);
097            }
098
099            Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
100
101            navigationContext.invalidateCurrentDocument();
102
103            addFacesMessage(StatusMessage.Severity.INFO, "collection.addedToCollection",
104                    isCreateNewCollection() ? getNewTitle() : getSelectedCollection().getTitle());
105        }
106    }
107
108    public void addCurrentSelectionToSelectedCollection() {
109        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
110        addToSelectedCollection(documentsListsManager.getWorkingList(DocumentsListsManager.CURRENT_DOCUMENT_SELECTION));
111    }
112
113    public void addDocUidsToBeAddedToCurrentCollection() {
114        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
115        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
116        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
117
118        List<DocumentModel> documentListToBeAdded = new ArrayList<DocumentModel>(docUidsToBeAdded.size());
119
120        for (String uid : docUidsToBeAdded) {
121            documentListToBeAdded.add(session.getDocument(new IdRef(uid)));
122        }
123
124        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
125        collectionManager.addToCollection(currentDocument, documentListToBeAdded, session);
126
127        Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
128
129        addFacesMessage(StatusMessage.Severity.INFO, "collection.allAddedToCollection", currentDocument.getTitle());
130    }
131
132    public void addToSelectedCollection(final List<DocumentModel> documentListToBeAdded) {
133        if (documentListToBeAdded != null && !documentListToBeAdded.isEmpty()) {
134            final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
135            final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
136            if (isCreateNewCollection()) {
137                collectionManager.addToNewCollection(getNewTitle(), getNewDescription(), documentListToBeAdded, session);
138            } else {
139                collectionManager.addToCollection(getSelectedCollection(), documentListToBeAdded, session);
140            }
141
142            Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
143
144            addFacesMessage(StatusMessage.Severity.INFO, "collection.allAddedToCollection",
145                    isCreateNewCollection() ? getNewTitle() : getSelectedCollection().getTitle());
146        }
147    }
148
149    public boolean canAddSelectedDocumentBeCollected() {
150        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
151        List<DocumentModel> documents = documentsListsManager.getWorkingList(DocumentsListsManager.CURRENT_DOCUMENT_SELECTION);
152        if (documents == null || documents.isEmpty()) {
153            return false;
154        }
155        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
156        for (DocumentModel doc : documents) {
157            if (!collectionManager.isCollectable(doc)) {
158                return false;
159            }
160        }
161        return true;
162    }
163
164    public boolean canAddToCollection(DocumentModel collection) {
165        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
166        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
167        final boolean result = collection != null && collectionManager.isCollection(collection)
168                && collectionManager.canAddToCollection(collection, session);
169        return result;
170    }
171
172    public boolean canAddToDocsToCurrentCollection() {
173        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
174        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
175        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
176        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
177        return collectionManager.canAddToCollection(currentDocument, session);
178    }
179
180    public boolean canAddToSelectedCollection() {
181        final boolean result = canAddToCollection(getSelectedCollection()) || isCreateNewCollection();
182        return result;
183    }
184
185    public void cancel() {
186        selectedCollectionUid = null;
187        newDescription = null;
188        newTitle = null;
189        docUidsToBeAdded = null;
190    }
191
192    public boolean canCurrentDocumentBeCollected() {
193        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
194        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
195        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
196        return collectionManager.isCollectable(currentDocument);
197    }
198
199    public boolean canManage(final DocumentModel collection) {
200        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
201        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
202        return collectionManager.canManage(collection, session);
203    }
204
205    public boolean canRemoveFromCollection() {
206        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
207        final List<DocumentModel> doccumentListToBeRemoved = documentsListsManager.getWorkingList(COLLECTION_CURRENT_SELECTION);
208        if (doccumentListToBeRemoved == null || doccumentListToBeRemoved.isEmpty()) {
209            return false;
210        }
211        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
212        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
213        return canAddToCollection(currentDocument);
214    }
215
216    public boolean canRemoveFromCollection(DocumentModel collection) {
217        return canAddToCollection(collection);
218    }
219
220    public List<String> getDocUidsToBeAdded() {
221        return docUidsToBeAdded;
222    }
223
224    protected DocumentsListsManager getDocumentsListsManager() {
225        return (DocumentsListsManager) Component.getInstance("documentsListsManager", true);
226    }
227
228    public List<DocumentModel> getMultipleDocumentToBeAdded() {
229        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
230        return documentsListsManager.getWorkingList(DocumentsListsManager.CURRENT_DOCUMENT_SELECTION);
231    }
232
233    public String getNewDescription() {
234        return newDescription;
235    }
236
237    public String getNewTitle() {
238        return newTitle;
239    }
240
241    public DocumentModel getSelectedCollection() {
242        if (selectedCollection == null && StringUtils.isNotBlank(selectedCollectionUid) && !isCreateNewCollection()) {
243            try {
244                final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
245                selectedCollection = session.getDocument(new IdRef(selectedCollectionUid));
246            } catch (DocumentNotFoundException e) {
247                log.error("Cannot fetch collection");
248            }
249        }
250        return selectedCollection;
251    }
252
253    public String getSelectedCollectionDescription() throws PropertyException {
254        if (isCreateNewCollection()) {
255            return null;
256        } else {
257            return (String) getSelectedCollection().getProperty("dc:description").getValue();
258        }
259    }
260
261    public String getSelectedCollectionUid() {
262        return selectedCollectionUid;
263    }
264
265    public boolean hasCurrentDocumentVisibleCollection() {
266        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
267        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
268        return hasVisibleCollection(currentDocument);
269    }
270
271    public boolean hasVisibleCollection(DocumentModel doc) {
272        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
273        if (doc == null || !collectionManager.isCollectable(doc)) {
274            return false;
275        }
276        if (collectionManager.isCollected(doc)) {
277            final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
278            return collectionManager.hasVisibleCollection(doc, session);
279        }
280        return false;
281    }
282
283    public boolean isCreateNewCollection() {
284        return selectedCollectionUid != null && selectedCollectionUid.startsWith(CollectionConstants.MAGIC_PREFIX_ID);
285    }
286
287    public boolean isCurrentDocumentCollection() {
288        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
289        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
290        if (currentDocument == null) {
291            return false;
292        }
293        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
294        return collectionManager.isCollection(currentDocument);
295    }
296
297    public void removeCurrentDocumentFromCollection(final ActionEvent event) {
298        FacesContext context = FacesContext.getCurrentInstance();
299        ExternalContext eContext = context.getExternalContext();
300        String collectionId = eContext.getRequestParameterMap().get("collectionId");
301        if (StringUtils.isNotBlank(collectionId)) {
302            final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
303            final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
304            final DocumentRef collectionRef = new IdRef(collectionId);
305            if (session.exists(collectionRef)) {
306                final DocumentModel collection = session.getDocument(collectionRef);
307                if (collectionManager.canAddToCollection(collection, session)) {
308                    final NavigationContext navigationContext = (NavigationContext) Component.getInstance(
309                            "navigationContext", true);
310                    final DocumentModel currentDocument = navigationContext.getCurrentDocument();
311                    collectionManager.removeFromCollection(collection, currentDocument, session);
312
313                    Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
314
315                    addFacesMessage(StatusMessage.Severity.INFO, "collection.removeCurrentDocumentFromCollection",
316                            collection.getTitle());
317                }
318            }
319        }
320    }
321
322    public void removeCurrentSelectionFromCollection() {
323        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
324        final List<DocumentModel> doccumentListToBeRemoved = documentsListsManager.getWorkingList(COLLECTION_CURRENT_SELECTION);
325        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
326        final DocumentModel collection = navigationContext.getCurrentDocument();
327        removeFromCollection(collection, doccumentListToBeRemoved);
328        documentsListsManager.resetWorkingList(COLLECTION_CURRENT_SELECTION);
329    }
330
331    public void removeFromCollection(DocumentModel collection, List<DocumentModel> documentListToBeRemoved)
332            {
333        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
334        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
335        collectionManager.removeAllFromCollection(collection, documentListToBeRemoved, session);
336
337        Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
338
339        addFacesMessage(StatusMessage.Severity.INFO, "collection.removeCurrentSelectionFromCollection",
340                collection.getTitle());
341    }
342
343    public void removeFromMultipleDocumentToBeAdded(ActionEvent event) {
344        FacesContext context = FacesContext.getCurrentInstance();
345        ExternalContext eContext = context.getExternalContext();
346        String index = eContext.getRequestParameterMap().get("index");
347
348        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
349        final DocumentModel toBeRemovedFromWorkingList = documentsListsManager.getWorkingList(
350                DocumentsListsManager.CURRENT_DOCUMENT_SELECTION).get(Integer.valueOf(index).intValue());
351        documentsListsManager.removeFromWorkingList(DocumentsListsManager.CURRENT_DOCUMENT_SELECTION,
352                toBeRemovedFromWorkingList);
353    }
354
355    public void setDocUidsToBeAdded(final List<String> docUidsToBeAdded) {
356        this.docUidsToBeAdded = docUidsToBeAdded;
357    }
358
359    public void setNewDescription(final String newDescription) {
360        this.newDescription = newDescription;
361    }
362
363    public void setNewTitle(final String newTitle) {
364        this.newTitle = newTitle;
365    }
366
367    public void setSelectedCollectionUid(final String selectedCollectionUid) {
368        this.selectedCollection = null;
369        this.selectedCollectionUid = selectedCollectionUid;
370        if (isCreateNewCollection()) {
371            setNewTitle(selectedCollectionUid.substring(CollectionConstants.MAGIC_PREFIX_ID.length()));
372        }
373    }
374
375}