001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS (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 * Nuxeo - initial API and implementation 016 * 017 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $ 018 */ 019 020package org.nuxeo.ecm.webapp.documenttemplates; 021 022import static org.jboss.seam.ScopeType.CONVERSATION; 023import static org.jboss.seam.ScopeType.EVENT; 024import static org.nuxeo.ecm.webapp.helpers.EventNames.DOCUMENT_CHILDREN_CHANGED; 025import static org.nuxeo.ecm.webapp.helpers.EventNames.DOMAIN_SELECTION_CHANGED; 026 027import java.io.Serializable; 028import java.util.ArrayList; 029import java.util.Iterator; 030import java.util.List; 031 032import org.apache.commons.logging.Log; 033import org.apache.commons.logging.LogFactory; 034import org.jboss.seam.annotations.Factory; 035import org.jboss.seam.annotations.In; 036import org.jboss.seam.annotations.Name; 037import org.jboss.seam.annotations.Observer; 038import org.jboss.seam.annotations.Scope; 039import org.jboss.seam.annotations.intercept.BypassInterceptors; 040import org.jboss.seam.core.Events; 041import org.jboss.seam.international.StatusMessage; 042import org.nuxeo.ecm.core.api.Blob; 043import org.nuxeo.ecm.core.api.CoreSession; 044import org.nuxeo.ecm.core.api.DocumentModel; 045import org.nuxeo.ecm.core.api.DocumentModelList; 046import org.nuxeo.ecm.core.api.DocumentRef; 047import org.nuxeo.ecm.core.api.IdRef; 048import org.nuxeo.ecm.core.api.LifeCycleConstants; 049import org.nuxeo.ecm.core.api.pathsegment.PathSegmentService; 050import org.nuxeo.ecm.core.query.sql.NXQL; 051import org.nuxeo.ecm.platform.ui.web.api.NavigationContext; 052import org.nuxeo.ecm.webapp.action.TypesTool; 053import org.nuxeo.ecm.webapp.base.InputController; 054import org.nuxeo.ecm.webapp.contentbrowser.DocumentActions; 055import org.nuxeo.ecm.webapp.helpers.EventNames; 056import org.nuxeo.runtime.api.Framework; 057 058/** 059 * Implementation for the documentTemplatesBean component available on the session. 060 */ 061@Name("documentTemplatesActions") 062@Scope(CONVERSATION) 063public class DocumentTemplatesActionsBean extends InputController implements DocumentTemplatesActions, Serializable { 064 065 public static final String TemplateRoot = "TemplateRoot"; 066 067 private static final Log log = LogFactory.getLog(DocumentTemplatesActionsBean.class); 068 069 private static final long serialVersionUID = -4031259222075515590L; 070 071 @In(create = true, required = false) 072 private transient CoreSession documentManager; 073 074 @In(required = false) 075 private transient DocumentActions documentActions; 076 077 @In(required = false) 078 private TypesTool typesTool; 079 080 @In(required = false) 081 protected DocumentModel changeableDocument; 082 083 @In(required = false, create = true) 084 protected transient NavigationContext navigationContext; 085 086 // cached list of templates 087 private DocumentModelList templates; 088 089 private String selectedTemplateId; 090 091 private String targetType = "Workspace"; 092 093 @Override 094 @Factory(value = "availableTemplates", scope = EVENT) 095 public DocumentModelList templatesListFactory() { 096 templates = getTemplates(); 097 return templates; 098 } 099 100 @Override 101 public DocumentModelList getTemplates(String targetTypeName) { 102 if (documentManager == null) { 103 log.error("Unable to access documentManager"); 104 return null; 105 } 106 107 String query = "SELECT * FROM Document where ecm:primaryType = '%s' AND ecm:path STARTSWITH %s"; 108 DocumentModelList tl = documentManager.query(String.format(query, TemplateRoot, 109 NXQL.escapeString(navigationContext.getCurrentDomainPath()))); 110 111 if (tl.isEmpty()) { 112 templates = tl; 113 } else { 114 templates = documentManager.getChildren(tl.get(0).getRef(), targetTypeName); 115 List<DocumentModel> deleted = new ArrayList<DocumentModel>(); 116 for (Iterator<DocumentModel> it = templates.iterator(); it.hasNext();) { 117 DocumentModel current = it.next(); 118 if (LifeCycleConstants.DELETED_STATE.equals(current.getCurrentLifeCycleState())) { 119 deleted.add(current); 120 } 121 } 122 templates.removeAll(deleted); 123 } 124 return templates; 125 } 126 127 @Override 128 public DocumentModelList getTemplates() { 129 if (targetType == null || targetType.equals("")) { 130 targetType = typesTool.getSelectedType().getId(); 131 } 132 return getTemplates(targetType); 133 } 134 135 @Override 136 public String createDocumentFromTemplate(DocumentModel doc, String templateId) { 137 selectedTemplateId = templateId; 138 return createDocumentFromTemplate(doc); 139 } 140 141 @Override 142 public String createDocumentFromTemplate(DocumentModel doc) { 143 144 if (documentManager == null) { 145 log.error("Unable to access documentManager"); 146 return null; 147 } 148 149 // Currently templating works with Workspace only 150 // Hardcoded that way. 151 152 if (selectedTemplateId == null || selectedTemplateId.equals("")) { 153 if (documentActions != null) { 154 return documentActions.saveDocument(doc); 155 } else { 156 log.error("Unable to find documentActions"); 157 return null; 158 } 159 } 160 161 // Remove this once it is available from the context 162 DocumentRef currentDocRef = navigationContext.getCurrentDocument().getRef(); 163 164 PathSegmentService pss = Framework.getService(PathSegmentService.class); 165 String name = pss.generatePathSegment(doc); 166 DocumentModel created = documentManager.copy(new IdRef(selectedTemplateId), currentDocRef, name); 167 168 // Update from user input. 169 // This part is for now harcoded for Workspace type. 170 String title = (String) doc.getProperty("dublincore", "title"); 171 created.setProperty("dublincore", "title", title); 172 173 String descr = (String) doc.getProperty("dublincore", "description"); 174 created.setProperty("dublincore", "description", descr); 175 176 Blob blob = (Blob) doc.getProperty("file", "content"); 177 if (blob != null) { 178 created.setProperty("file", "content", blob); 179 String fname = (String) doc.getProperty("file", "filename"); 180 created.setProperty("file", "filename", fname); 181 } 182 183 created = documentManager.saveDocument(created); 184 documentManager.save(); 185 186 selectedTemplateId = ""; 187 188 logDocumentWithTitle("Created the document: ", created); 189 facesMessages.add(StatusMessage.Severity.INFO, resourcesAccessor.getMessages().get("document_saved"), 190 resourcesAccessor.getMessages().get(created.getType())); 191 Events.instance().raiseEvent(EventNames.DOCUMENT_CHILDREN_CHANGED, currentDocument); 192 return navigationContext.navigateToDocument(created, "after-create"); 193 } 194 195 @Override 196 public String createDocumentFromTemplate() { 197 return createDocumentFromTemplate(changeableDocument); 198 } 199 200 @Override 201 public String getSelectedTemplateId() { 202 return selectedTemplateId; 203 } 204 205 @Override 206 public void setSelectedTemplateId(String requestedId) { 207 selectedTemplateId = requestedId; 208 } 209 210 @Override 211 public String getTargetType() { 212 return targetType; 213 } 214 215 @Override 216 public void setTargetType(String targetType) { 217 this.targetType = targetType; 218 } 219 220 @Override 221 @Observer(value = { DOCUMENT_CHILDREN_CHANGED }, create = false) 222 @BypassInterceptors 223 public void documentChildrenChanged() { 224 if (templates != null) { 225 templates.clear(); 226 } 227 } 228 229 @Override 230 @Observer(value = { DOMAIN_SELECTION_CHANGED }, create = false) 231 @BypassInterceptors 232 public void domainChanged() { 233 if (templates != null) { 234 templates.clear(); 235 } 236 } 237 238}