001/*
002 * (C) Copyright 2006-2007 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.contentbrowser;
023
024import static org.jboss.seam.ScopeType.CONVERSATION;
025
026import java.io.Serializable;
027import java.security.Principal;
028import java.util.ArrayList;
029import java.util.List;
030
031import org.apache.commons.logging.Log;
032import org.apache.commons.logging.LogFactory;
033import org.jboss.seam.annotations.Begin;
034import org.jboss.seam.annotations.End;
035import org.jboss.seam.annotations.Factory;
036import org.jboss.seam.annotations.In;
037import org.jboss.seam.annotations.Name;
038import org.jboss.seam.annotations.Scope;
039import org.jboss.seam.core.Manager;
040import org.nuxeo.ecm.core.api.Blob;
041import org.nuxeo.ecm.core.api.CoreSession;
042import org.nuxeo.ecm.core.api.DocumentModel;
043import org.nuxeo.ecm.core.api.DocumentModelList;
044import org.nuxeo.ecm.core.api.DocumentRef;
045import org.nuxeo.ecm.core.api.IdRef;
046import org.nuxeo.ecm.core.api.pathsegment.PathSegmentService;
047import org.nuxeo.ecm.core.api.security.SecurityConstants;
048import org.nuxeo.ecm.platform.el.ContextStringWrapper;
049import org.nuxeo.ecm.platform.ui.web.util.BaseURL;
050import org.nuxeo.ecm.platform.usermanager.UserManager;
051import org.nuxeo.ecm.webapp.base.InputController;
052import org.nuxeo.ecm.webapp.documenttemplates.DocumentTemplatesActions;
053import org.nuxeo.ecm.webapp.security.PrincipalListManager;
054import org.nuxeo.ecm.webapp.security.SecurityActions;
055import org.nuxeo.runtime.api.Framework;
056
057/**
058 * Action listener that deals with operations with the workspaces.
059 * <p>
060 * This action listener handles the workspace creation wizard.
061 *
062 * @author <a href="mailto:rcaraghin@nuxeo.com">Razvan Caraghin</a>
063 */
064@Name("workspaceActions")
065@Scope(CONVERSATION)
066public class WorkspaceActionsBean extends InputController implements WorkspaceActions, Serializable {
067
068    private static final long serialVersionUID = 1L;
069
070    private static final Log log = LogFactory.getLog(WorkspaceActionsBean.class);
071
072    @In(create = true, required = false)
073    private transient CoreSession documentManager;
074
075    @In(create = true)
076    private transient Principal currentUser;
077
078    @In(required = false)
079    private transient DocumentActions documentActions;
080
081    @In(create = true)
082    private transient PrincipalListManager principalListManager;
083
084    @In(create = true)
085    protected transient UserManager userManager;
086
087    @In(create = true)
088    private transient SecurityActions securityActions;
089
090    @In(value = "org.jboss.seam.core.manager")
091    private transient Manager conversationManager;
092
093    // Wizard implementation : driven by PageFlow addWorkspace
094
095    private Boolean useTemplateFlag;
096
097    @In(required = false)
098    private transient DocumentModel tmpWorkspace;
099
100    @In(create = true)
101    private transient DocumentModelList availableTemplates;
102
103    // inject wizard vars
104    @In(value = "#{selectedTemplateId.value}", required = false)
105    private transient String selectedTemplateId;
106
107    @In(value = "#{selectedSecurityModel.value}", required = false)
108    private transient String selectedSecurityModel;
109
110    @In(value = "#{selectedOwnerModel.value}", required = false)
111    private transient String selectedOwnerModel;
112
113    @In(create = true)
114    private transient DocumentTemplatesActions documentTemplatesActions;
115
116    public String cancel() {
117        return "view_workspaces";
118    }
119
120    // Flag for indicating if template will be used
121    @Override
122    public void setUseTemplate(Boolean value) {
123        useTemplateFlag = value;
124    }
125
126    @Override
127    public Boolean getUseTemplate() {
128        if (availableTemplates == null) {
129            return false;
130        }
131        if (useTemplateFlag == null) {
132            return false;
133        }
134        return useTemplateFlag;
135    }
136
137    // initialize pageflow context using Factories
138    @Override
139    @Factory(value = "selectedTemplateId")
140    public ContextStringWrapper FactoryForSelectedTemplateId() {
141        return new ContextStringWrapper("none");
142    }
143
144    @Override
145    @Factory(value = "selectedSecurityModel")
146    public ContextStringWrapper FactoryForSelectSecurityModel() {
147        return new ContextStringWrapper("inherit");
148    }
149
150    @Override
151    @Factory(value = "selectedOwnerModel")
152    public ContextStringWrapper FactoryForSelectSecurityOwner() {
153        return new ContextStringWrapper("me");
154    }
155
156    @Override
157    @Begin(pageflow = "createWorkspace", nested = true)
158    @Factory(value = "tmpWorkspace")
159    public DocumentModel getTmpWorkspace() {
160        if (tmpWorkspace == null) {
161            tmpWorkspace = documentManager.createDocumentModel("Workspace");
162        }
163        return tmpWorkspace;
164    }
165
166    @Override
167    @Factory(value = "availableWorkspaceTemplates")
168    public DocumentModelList getTemplates() {
169        availableTemplates = documentTemplatesActions.getTemplates("Workspace");
170        return availableTemplates;
171    }
172
173    @Override
174    public String finishPageFlow() {
175        return "done";
176    }
177
178    @Override
179    public String getSelectedTemplateDescription() {
180        if (selectedTemplateId == null) {
181            return "";
182        }
183        if (selectedTemplateId.equals("none")) {
184            return "no_template";
185        }
186        for (DocumentModel t : getTemplates()) {
187            if (selectedTemplateId.equals(t.getId())) {
188                return (String) t.getProperty("dublincore", "description");
189            }
190        }
191        return "";
192    }
193
194    @Override
195    public DocumentModel getSelectedTemplate() {
196        if (selectedTemplateId == null) {
197            return null;
198        }
199        if (selectedTemplateId.equals("none")) {
200            return null;
201        }
202        for (DocumentModel t : getTemplates()) {
203            if (selectedTemplateId.equals(t.getId())) {
204                return t;
205            }
206        }
207        return null;
208    }
209
210    // @End(beforeRedirect = true)
211    @Override
212    @End
213    public String createWorkspace() {
214        String navResult = null;
215
216        if (useTemplateFlag == null || !useTemplateFlag || selectedTemplateId == null
217                || selectedTemplateId.equals("none")) {
218            // create the new Workspace without Template
219            // and navigate to it
220            navResult = documentTemplatesActions.createDocumentFromTemplate(tmpWorkspace, null);
221        } else {
222            // create the workspace from template
223            navResult = documentTemplatesActions.createDocumentFromTemplate(tmpWorkspace, selectedTemplateId);
224        }
225
226        if (!selectedSecurityModel.equals("inherit")) {
227            List<String> principalsName;
228
229            // get principals list to apply rights to
230            if (selectedOwnerModel.equals("me")) {
231                principalsName = new ArrayList<String>();
232                principalsName.add(currentUser.getName());
233            } else {
234                principalsName = principalListManager.getSelectedUsers();
235            }
236
237            // Force addition of administrators groups
238            principalsName.addAll(userManager.getAdministratorsGroups());
239
240            // Grant to principalList
241            for (String principalName : principalsName) {
242                securityActions.addPermission(principalName, SecurityConstants.EVERYTHING, true);
243            }
244
245            // DENY at root
246            securityActions.addPermission(SecurityConstants.EVERYONE, SecurityConstants.EVERYTHING, false);
247            securityActions.updateSecurityOnDocument();
248        }
249
250        String res = navigationContext.navigateToDocument(navigationContext.getCurrentDocument());
251        navigationContext.setChangeableDocument(navigationContext.getCurrentDocument());
252        return res;
253    }
254
255    @End(beforeRedirect = true)
256    public String createWorkspaceOld() {
257        String navResult = null;
258
259        if (!useTemplateFlag || selectedTemplateId.equals("none")) {
260            // create the new Workspace without Template
261            // and navigate to it
262            navResult = documentActions.saveDocument(tmpWorkspace);
263        } else {
264            // create the workspace from template
265
266            DocumentRef currentDocRef = navigationContext.getCurrentDocument().getRef();
267
268            // duplicate the template
269            String title = (String) tmpWorkspace.getProperty("dublincore", "title");
270            String name = Framework.getService(PathSegmentService.class).generatePathSegment(title);
271            documentManager.copy(new IdRef(selectedTemplateId), currentDocRef, name);
272            DocumentModel created = documentManager.getChild(currentDocRef, name);
273
274            // Update from user input.
275            created.setProperty("dublincore", "title", title);
276            String descr = (String) tmpWorkspace.getProperty("dublincore", "description");
277            if (!descr.equals("")) {
278                created.setProperty("dublincore", "description", descr);
279            }
280            Blob blob = (Blob) tmpWorkspace.getProperty("file", "content");
281            if (blob != null) {
282                created.setProperty("file", "content", blob);
283            }
284
285            created = documentManager.saveDocument(created);
286            documentManager.save();
287
288            // navigate to the newly created doc
289            navResult = navigationContext.navigateToDocument(created, "after-create");
290        }
291
292        if (!selectedSecurityModel.equals("inherit")) {
293            List<String> principalsName;
294
295            // get principals list to apply rights to
296            if (selectedOwnerModel.equals("me")) {
297                principalsName = new ArrayList<String>();
298                principalsName.add(currentUser.getName());
299            } else {
300                principalsName = principalListManager.getSelectedUsers();
301            }
302
303            // Grant to principalList
304            for (String principalName : principalsName) {
305                securityActions.addPermission(principalName, SecurityConstants.EVERYTHING, true);
306            }
307
308            // Force addition of administrators groups
309            principalsName.addAll(userManager.getAdministratorsGroups());
310
311            // DENY at root
312            securityActions.addPermission(SecurityConstants.EVERYONE, SecurityConstants.EVERYTHING, false);
313            securityActions.updateSecurityOnDocument();
314        }
315
316        String res = navigationContext.navigateToDocument(navigationContext.getCurrentDocument());
317        navigationContext.setChangeableDocument(navigationContext.getCurrentDocument());
318        return res;
319    }
320
321    @Override
322    @End(beforeRedirect = true)
323    public String exitWizard() {
324        return navigationContext.navigateToDocument(navigationContext.getCurrentDocument());
325    }
326
327    @Override
328    public String getA4JHackingURL() {
329        String url = BaseURL.getBaseURL() + "wizards/createWorkspace/a4jUploadHack.faces?";
330        url = conversationManager.encodeConversationId(url);
331        return url;
332    }
333
334}