001/*
002 * (C) Copyright 2010 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.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 * Thomas Roger
016 */
017
018package org.nuxeo.ecm.webapp.contentbrowser;
019
020import static org.nuxeo.ecm.webapp.documentsLists.DocumentsListsManager.CURRENT_DOCUMENT_SECTION_SELECTION;
021import static org.nuxeo.ecm.webapp.documentsLists.DocumentsListsManager.CURRENT_DOCUMENT_SELECTION;
022import static org.nuxeo.ecm.webapp.helpers.EventNames.DOCUMENT_CHILDREN_CHANGED;
023
024import java.io.Serializable;
025import java.util.List;
026
027import org.apache.commons.logging.Log;
028import org.apache.commons.logging.LogFactory;
029import org.jboss.seam.ScopeType;
030import org.jboss.seam.annotations.In;
031import org.jboss.seam.annotations.Name;
032import org.jboss.seam.annotations.Scope;
033import org.jboss.seam.core.Events;
034import org.jboss.seam.faces.FacesMessages;
035import org.jboss.seam.international.StatusMessage;
036import org.nuxeo.ecm.core.api.CoreSession;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.ecm.core.api.DocumentRef;
039import org.nuxeo.ecm.core.api.IdRef;
040import org.nuxeo.ecm.core.schema.FacetNames;
041import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
042import org.nuxeo.ecm.webapp.documentsLists.DocumentsListsManager;
043import org.nuxeo.ecm.webapp.helpers.ResourcesAccessor;
044
045/**
046 * Seam bean used for Orderable documents.
047 *
048 * @author <a href="mailto:troger@nuxeo.com">Thomas Roger</a>
049 */
050@Name("orderableDocumentActions")
051@Scope(ScopeType.CONVERSATION)
052public class OrderableDocumentActions implements Serializable {
053
054    /**
055     *
056     */
057    private static final long serialVersionUID = 1L;
058
059    private static final Log log = LogFactory.getLog(OrderableDocumentActions.class);
060
061    public static final String SECTION_TYPE = "Section";
062
063    @In(create = true)
064    protected transient NavigationContext navigationContext;
065
066    @In(create = true, required = false)
067    protected transient CoreSession documentManager;
068
069    @In(required = false, create = true)
070    protected transient DocumentsListsManager documentsListsManager;
071
072    @In(create = true, required = false)
073    protected transient FacesMessages facesMessages;
074
075    @In(create = true)
076    protected transient ResourcesAccessor resourcesAccessor;
077
078    /*
079     * -------- Web Actions --------
080     */
081
082    public boolean getCanMoveDown() {
083        DocumentModel currentDocument = navigationContext.getCurrentDocument();
084        if (!isOrderable(currentDocument)) {
085            return false;
086        }
087        if (isSectionType(currentDocument)) {
088            return getCanMoveDown(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
089        } else {
090            return getCanMoveDown(currentDocument, CURRENT_DOCUMENT_SELECTION);
091        }
092    }
093
094    protected boolean getCanMoveDown(DocumentModel container, String documentsListName) {
095        List<DocumentModel> docs = documentsListsManager.getWorkingList(documentsListName);
096        if (docs.isEmpty() || docs.size() > 1) {
097            return false;
098        }
099
100        DocumentModel selectedDocument = docs.get(0);
101        List<DocumentRef> children = documentManager.getChildrenRefs(container.getRef(), null);
102        int selectedDocumentIndex = children.indexOf(new IdRef(selectedDocument.getId()));
103        int nextIndex = selectedDocumentIndex + 1;
104        if (nextIndex == children.size()) {
105            // can't move down the last document
106            return false;
107        }
108        return true;
109    }
110
111    public String moveDown() {
112        DocumentModel currentDocument = navigationContext.getCurrentDocument();
113        if (currentDocument == null) {
114            return null;
115        }
116        if (isSectionType(currentDocument)) {
117            return moveDown(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
118        } else {
119            return moveDown(currentDocument, CURRENT_DOCUMENT_SELECTION);
120        }
121    }
122
123    protected String moveDown(DocumentModel container, String documentsListName) {
124        DocumentModel selectedDocument = documentsListsManager.getWorkingList(documentsListName).get(0);
125
126        List<DocumentRef> children = documentManager.getChildrenRefs(container.getRef(), null);
127        int selectedDocumentIndex = children.indexOf(new IdRef(selectedDocument.getId()));
128        int nextIndex = selectedDocumentIndex + 1;
129        DocumentRef nextDocumentRef = children.get(nextIndex);
130
131        documentManager.orderBefore(container.getRef(), documentManager.getDocument(nextDocumentRef).getName(),
132                selectedDocument.getName());
133        documentManager.save();
134
135        notifyChildrenChanged(container);
136        addFacesMessage("feedback.order.movedDown");
137        return null;
138    }
139
140    protected void notifyChildrenChanged(DocumentModel containerDocument) {
141        if (containerDocument != null) {
142            Events.instance().raiseEvent(DOCUMENT_CHILDREN_CHANGED, containerDocument);
143        }
144    }
145
146    public boolean getCanMoveUp() {
147        DocumentModel currentDocument = navigationContext.getCurrentDocument();
148        if (!isOrderable(currentDocument)) {
149            return false;
150        }
151        if (isSectionType(currentDocument)) {
152            return getCanMoveUp(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
153        } else {
154            return getCanMoveUp(currentDocument, CURRENT_DOCUMENT_SELECTION);
155        }
156    }
157
158    protected boolean getCanMoveUp(DocumentModel container, String documentsListName) {
159        List<DocumentModel> docs = documentsListsManager.getWorkingList(documentsListName);
160        if (docs.isEmpty() || docs.size() > 1) {
161            return false;
162        }
163
164        DocumentModel selectedDocument = docs.get(0);
165        List<DocumentRef> children = documentManager.getChildrenRefs(container.getRef(), null);
166        int selectedDocumentIndex = children.indexOf(new IdRef(selectedDocument.getId()));
167        int previousIndex = selectedDocumentIndex - 1;
168        if (previousIndex < 0) {
169            // can't move up the first document
170            return false;
171        }
172        return true;
173    }
174
175    public String moveUp() {
176        DocumentModel currentDocument = navigationContext.getCurrentDocument();
177        if (currentDocument == null) {
178            return null;
179        }
180        if (isSectionType(currentDocument)) {
181            return moveUp(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
182        } else {
183            return moveUp(currentDocument, CURRENT_DOCUMENT_SELECTION);
184        }
185    }
186
187    protected String moveUp(DocumentModel container, String documentsListName) {
188        DocumentModel selectedDocument = documentsListsManager.getWorkingList(documentsListName).get(0);
189
190        List<DocumentRef> children = documentManager.getChildrenRefs(container.getRef(), null);
191        int selectedDocumentIndex = children.indexOf(new IdRef(selectedDocument.getId()));
192        int previousIndex = selectedDocumentIndex - 1;
193        DocumentRef previousDocumentRef = children.get(previousIndex);
194
195        documentManager.orderBefore(container.getRef(), selectedDocument.getName(),
196                documentManager.getDocument(previousDocumentRef).getName());
197        documentManager.save();
198
199        notifyChildrenChanged(container);
200        addFacesMessage("feedback.order.movedUp");
201        return null;
202    }
203
204    public boolean getCanMoveToTop() {
205        DocumentModel currentDocument = navigationContext.getCurrentDocument();
206        if (!isOrderable(currentDocument)) {
207            return false;
208        }
209        if (isSectionType(currentDocument)) {
210            return getCanMoveToTop(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
211        } else {
212            return getCanMoveToTop(currentDocument, CURRENT_DOCUMENT_SELECTION);
213        }
214    }
215
216    protected boolean getCanMoveToTop(DocumentModel container, String documentsListName) {
217        List<DocumentModel> docs = documentsListsManager.getWorkingList(documentsListName);
218        if (docs.isEmpty() || docs.size() > 1) {
219            return false;
220        }
221
222        DocumentModel selectedDocument = docs.get(0);
223        List<DocumentRef> children = documentManager.getChildrenRefs(container.getRef(), null);
224        int selectedDocumentIndex = children.indexOf(new IdRef(selectedDocument.getId()));
225        if (selectedDocumentIndex <= 0) {
226            // can't move to top the first document
227            return false;
228        }
229        return true;
230    }
231
232    public String moveToTop() {
233        DocumentModel currentDocument = navigationContext.getCurrentDocument();
234        if (currentDocument == null) {
235            return null;
236        }
237        if (isSectionType(currentDocument)) {
238            return moveToTop(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
239        } else {
240            return moveToTop(currentDocument, CURRENT_DOCUMENT_SELECTION);
241        }
242    }
243
244    protected String moveToTop(DocumentModel container, String documentsListName) {
245        DocumentModel selectedDocument = documentsListsManager.getWorkingList(documentsListName).get(0);
246        List<DocumentRef> children = documentManager.getChildrenRefs(container.getRef(), null);
247        DocumentRef firstDocumentRef = children.get(0);
248
249        documentManager.orderBefore(container.getRef(), selectedDocument.getName(),
250                documentManager.getDocument(firstDocumentRef).getName());
251        documentManager.save();
252
253        notifyChildrenChanged(container);
254        addFacesMessage("feedback.order.movedToTop");
255        return null;
256    }
257
258    public boolean getCanMoveToBottom() {
259        DocumentModel currentDocument = navigationContext.getCurrentDocument();
260        if (!isOrderable(currentDocument)) {
261            return false;
262        }
263        if (isSectionType(currentDocument)) {
264            return getCanMoveToBottom(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
265        } else {
266            return getCanMoveToBottom(currentDocument, CURRENT_DOCUMENT_SELECTION);
267        }
268    }
269
270    protected boolean getCanMoveToBottom(DocumentModel container, String documentsListName) {
271        List<DocumentModel> docs = documentsListsManager.getWorkingList(documentsListName);
272        if (docs.isEmpty() || docs.size() > 1) {
273            return false;
274        }
275
276        DocumentModel selectedDocument = docs.get(0);
277        List<DocumentRef> children = documentManager.getChildrenRefs(container.getRef(), null);
278        int selectedDocumentIndex = children.indexOf(new IdRef(selectedDocument.getId()));
279        if (selectedDocumentIndex >= children.size() - 1) {
280            // can't move to bottom the last document
281            return false;
282        }
283        return true;
284    }
285
286    public String moveToBottom() {
287        DocumentModel currentDocument = navigationContext.getCurrentDocument();
288        if (currentDocument == null) {
289            return null;
290        }
291        if (isSectionType(currentDocument)) {
292            return moveToBottom(currentDocument, CURRENT_DOCUMENT_SECTION_SELECTION);
293        } else {
294            return moveToBottom(currentDocument, CURRENT_DOCUMENT_SELECTION);
295        }
296    }
297
298    protected String moveToBottom(DocumentModel container, String documentsListName) {
299        DocumentRef containerRef = container.getRef();
300        DocumentModel selectedDocument = documentsListsManager.getWorkingList(documentsListName).get(0);
301        documentManager.orderBefore(containerRef, selectedDocument.getName(), null);
302        documentManager.save();
303
304        notifyChildrenChanged(container);
305        addFacesMessage("feedback.order.movedToBottom");
306        return null;
307    }
308
309    protected boolean isOrderable(DocumentModel doc) {
310        return doc.hasFacet(FacetNames.ORDERABLE);
311    }
312
313    protected boolean isSectionType(DocumentModel doc) {
314        return doc.hasFacet(FacetNames.PUBLISH_SPACE);
315    }
316
317    protected void addFacesMessage(String messageLabel) {
318        facesMessages.add(StatusMessage.Severity.INFO, resourcesAccessor.getMessages().get(messageLabel));
319    }
320
321}