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