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