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}