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}