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        if (currentDocument == null) {
176            return false;
177        }
178        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
179        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
180        return collectionManager.canAddToCollection(currentDocument, session);
181    }
182
183    public boolean canAddToSelectedCollection() {
184        final boolean result = canAddToCollection(getSelectedCollection()) || isCreateNewCollection();
185        return result;
186    }
187
188    public void cancel() {
189        selectedCollectionUid = null;
190        newDescription = null;
191        newTitle = null;
192        docUidsToBeAdded = null;
193    }
194
195    public boolean canCurrentDocumentBeCollected() {
196        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
197        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
198        if (currentDocument == null) {
199            return false;
200        }
201        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
202        return collectionManager.isCollectable(currentDocument);
203    }
204
205    public boolean canManage(final DocumentModel collection) {
206        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
207        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
208        return collectionManager.canManage(collection, session);
209    }
210
211    public boolean canRemoveFromCollection() {
212        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
213        final List<DocumentModel> doccumentListToBeRemoved = documentsListsManager.getWorkingList(COLLECTION_CURRENT_SELECTION);
214        if (doccumentListToBeRemoved == null || doccumentListToBeRemoved.isEmpty()) {
215            return false;
216        }
217        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
218        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
219        return canAddToCollection(currentDocument);
220    }
221
222    public boolean canRemoveFromCollection(DocumentModel collection) {
223        return canAddToCollection(collection);
224    }
225
226    public List<String> getDocUidsToBeAdded() {
227        return docUidsToBeAdded;
228    }
229
230    protected DocumentsListsManager getDocumentsListsManager() {
231        return (DocumentsListsManager) Component.getInstance("documentsListsManager", true);
232    }
233
234    public List<DocumentModel> getMultipleDocumentToBeAdded() {
235        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
236        return documentsListsManager.getWorkingList(DocumentsListsManager.CURRENT_DOCUMENT_SELECTION);
237    }
238
239    public String getNewDescription() {
240        return newDescription;
241    }
242
243    public String getNewTitle() {
244        return newTitle;
245    }
246
247    public DocumentModel getSelectedCollection() {
248        if (selectedCollection == null && StringUtils.isNotBlank(selectedCollectionUid) && !isCreateNewCollection()) {
249            try {
250                final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
251                selectedCollection = session.getDocument(new IdRef(selectedCollectionUid));
252            } catch (DocumentNotFoundException e) {
253                log.error("Cannot fetch collection");
254            }
255        }
256        return selectedCollection;
257    }
258
259    public String getSelectedCollectionDescription() throws PropertyException {
260        if (isCreateNewCollection()) {
261            return null;
262        } else {
263            return (String) getSelectedCollection().getProperty("dc:description").getValue();
264        }
265    }
266
267    public String getSelectedCollectionUid() {
268        return selectedCollectionUid;
269    }
270
271    public boolean hasCurrentDocumentVisibleCollection() {
272        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
273        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
274        return hasVisibleCollection(currentDocument);
275    }
276
277    public boolean hasVisibleCollection(DocumentModel doc) {
278        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
279        if (doc == null || !collectionManager.isCollectable(doc)) {
280            return false;
281        }
282        if (collectionManager.isCollected(doc)) {
283            final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
284            return collectionManager.hasVisibleCollection(doc, session);
285        }
286        return false;
287    }
288
289    public boolean isCreateNewCollection() {
290        return selectedCollectionUid != null && selectedCollectionUid.startsWith(CollectionConstants.MAGIC_PREFIX_ID);
291    }
292
293    public boolean isCurrentDocumentCollection() {
294        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
295        final DocumentModel currentDocument = navigationContext.getCurrentDocument();
296        if (currentDocument == null) {
297            return false;
298        }
299        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
300        return collectionManager.isCollection(currentDocument);
301    }
302
303    public void removeCurrentDocumentFromCollection(final ActionEvent event) {
304        FacesContext context = FacesContext.getCurrentInstance();
305        ExternalContext eContext = context.getExternalContext();
306        String collectionId = eContext.getRequestParameterMap().get("collectionId");
307        if (StringUtils.isNotBlank(collectionId)) {
308            final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
309            final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
310            final DocumentRef collectionRef = new IdRef(collectionId);
311            if (session.exists(collectionRef)) {
312                final DocumentModel collection = session.getDocument(collectionRef);
313                if (collectionManager.canAddToCollection(collection, session)) {
314                    final NavigationContext navigationContext = (NavigationContext) Component.getInstance(
315                            "navigationContext", true);
316                    final DocumentModel currentDocument = navigationContext.getCurrentDocument();
317                    collectionManager.removeFromCollection(collection, currentDocument, session);
318
319                    Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
320
321                    addFacesMessage(StatusMessage.Severity.INFO, "collection.removeCurrentDocumentFromCollection",
322                            collection.getTitle());
323                }
324            }
325        }
326    }
327
328    public void removeCurrentSelectionFromCollection() {
329        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
330        final List<DocumentModel> doccumentListToBeRemoved = documentsListsManager.getWorkingList(COLLECTION_CURRENT_SELECTION);
331        final NavigationContext navigationContext = (NavigationContext) Component.getInstance("navigationContext", true);
332        final DocumentModel collection = navigationContext.getCurrentDocument();
333        removeFromCollection(collection, doccumentListToBeRemoved);
334        documentsListsManager.resetWorkingList(COLLECTION_CURRENT_SELECTION);
335    }
336
337    public void removeFromCollection(DocumentModel collection, List<DocumentModel> documentListToBeRemoved)
338            {
339        final CollectionManager collectionManager = Framework.getLocalService(CollectionManager.class);
340        final CoreSession session = (CoreSession) Component.getInstance("documentManager", true);
341        collectionManager.removeAllFromCollection(collection, documentListToBeRemoved, session);
342
343        Events.instance().raiseEvent(EventNames.DOCUMENT_CHANGED);
344
345        addFacesMessage(StatusMessage.Severity.INFO, "collection.removeCurrentSelectionFromCollection",
346                collection.getTitle());
347    }
348
349    public void removeFromMultipleDocumentToBeAdded(ActionEvent event) {
350        FacesContext context = FacesContext.getCurrentInstance();
351        ExternalContext eContext = context.getExternalContext();
352        String index = eContext.getRequestParameterMap().get("index");
353
354        final DocumentsListsManager documentsListsManager = getDocumentsListsManager();
355        final DocumentModel toBeRemovedFromWorkingList = documentsListsManager.getWorkingList(
356                DocumentsListsManager.CURRENT_DOCUMENT_SELECTION).get(Integer.valueOf(index).intValue());
357        documentsListsManager.removeFromWorkingList(DocumentsListsManager.CURRENT_DOCUMENT_SELECTION,
358                toBeRemovedFromWorkingList);
359    }
360
361    public void setDocUidsToBeAdded(final List<String> docUidsToBeAdded) {
362        this.docUidsToBeAdded = docUidsToBeAdded;
363    }
364
365    public void setNewDescription(final String newDescription) {
366        this.newDescription = newDescription;
367    }
368
369    public void setNewTitle(final String newTitle) {
370        this.newTitle = newTitle;
371    }
372
373    public void setSelectedCollectionUid(final String selectedCollectionUid) {
374        this.selectedCollection = null;
375        this.selectedCollectionUid = selectedCollectionUid;
376        if (isCreateNewCollection()) {
377            setNewTitle(selectedCollectionUid.substring(CollectionConstants.MAGIC_PREFIX_ID.length()));
378        }
379    }
380
381}