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