001/*
002 * (C) Copyright 2011 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 *     Quentin Lamerand <qlamerand@nuxeo.com>
016 */
017
018package org.nuxeo.ecm.user.center.profile;
019
020import static org.nuxeo.ecm.platform.ui.web.api.WebActions.CURRENT_TAB_CHANGED_EVENT;
021import static org.nuxeo.ecm.platform.ui.web.api.WebActions.CURRENT_TAB_SELECTED_EVENT;
022import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.MAIN_TABS_CATEGORY;
023import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.NUXEO_ADMIN_CATEGORY;
024import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.USERS_GROUPS_HOME_SUB_TAB;
025import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.USERS_GROUPS_MANAGER_SUB_TAB;
026import static org.nuxeo.ecm.webapp.security.AbstractUserGroupManagement.USER_CENTER_CATEGORY;
027import static org.nuxeo.ecm.webapp.security.UserManagementActions.USERS_LISTING_CHANGED;
028import static org.nuxeo.ecm.webapp.security.UserManagementActions.USER_SELECTED_CHANGED;
029
030import java.io.Serializable;
031
032import org.apache.commons.lang.StringUtils;
033import org.jboss.seam.ScopeType;
034import org.jboss.seam.annotations.In;
035import org.jboss.seam.annotations.Name;
036import org.jboss.seam.annotations.Observer;
037import org.jboss.seam.annotations.Scope;
038import org.jboss.seam.annotations.intercept.BypassInterceptors;
039import org.jboss.seam.international.LocaleSelector;
040import org.nuxeo.ecm.core.api.CoreSession;
041import org.nuxeo.ecm.core.api.DocumentModel;
042import org.nuxeo.ecm.core.api.NuxeoPrincipal;
043import org.nuxeo.ecm.platform.ui.web.api.NavigationContext;
044import org.nuxeo.ecm.platform.usermanager.UserManager;
045import org.nuxeo.ecm.webapp.security.UserManagementActions;
046import org.nuxeo.runtime.api.Framework;
047
048/**
049 * Seam component to manage user profile editing
050 *
051 * @author <a href="mailto:qlamerand@nuxeo.com">Quentin Lamerand</a>
052 * @since 5.5
053 */
054@Name("userProfileActions")
055@Scope(ScopeType.CONVERSATION)
056public class UserProfileActions implements Serializable {
057
058    private static final long serialVersionUID = 1L;
059
060    public static final String PROFILE_VIEW_MODE = "view";
061
062    public static final String PROFILE_EDIT_MODE = "edit";
063
064    public static final String PROFILE_EDIT_PASSWORD_MODE = "editPassword";
065
066    @In(create = true)
067    protected transient UserManagementActions userManagementActions;
068
069    @In(create = true)
070    protected NuxeoPrincipal currentUser;
071
072    @In(create = true)
073    protected transient CoreSession documentManager;
074
075    @In(create = true)
076    protected transient NavigationContext navigationContext;
077
078    @In(create = true)
079    protected transient LocaleSelector localeSelector;
080
081    @In(create = true)
082    protected transient UserManager userManager;
083
084    protected String mode = PROFILE_VIEW_MODE;
085
086    protected DocumentModel userProfileDocument;
087
088    protected DocumentModel currentUserProfile;
089
090    public void updateUser() {
091        if (userProfileDocument != null) {
092            // Ensure to remove user schema from datamodel when saving changes
093            // on user profile, otherwise an exception is thrown, see
094            // NXP-11397.
095            userProfileDocument.getDataModels().remove(userManager.getUserSchemaName());
096            documentManager.saveDocument(userProfileDocument);
097            documentManager.save();
098        }
099
100        // Update selected user after profile to prevent from
101        // org.nuxeo.ecm.webapp.security.UserManagementActions.USER_SELECTED_CHANGED
102        // event to reset userProfileDocument field.
103        userManagementActions.updateUser();
104
105        mode = PROFILE_VIEW_MODE;
106    }
107
108    public String getMode() {
109        return mode;
110    }
111
112    public boolean getCanEdit() {
113        return userManagementActions.getAllowEditUser() && userManagementActions.isNotReadOnly();
114    }
115
116    public void setMode(String mode) {
117        this.mode = mode;
118    }
119
120    public DocumentModel getCurrentUserModel() {
121        DocumentModel selectedUser = userManagementActions.getSelectedUser();
122        DocumentModel currentUserModel = currentUser.getModel();
123        if (selectedUser == null || !selectedUser.getId().equals(currentUserModel.getId())) {
124            userManagementActions.setSelectedUser(currentUserModel);
125        }
126        return currentUserModel;
127    }
128
129    public DocumentModel getUserProfileDocument() {
130        // Need to set selectedUser in UserManagementActions to avoid an NPE
131        // when calling updateUser() if UserManagementActions#selectedUser has
132        // been set to null meanwhile (by opening a new tab for instance).
133        getCurrentUserModel();
134        if (userProfileDocument == null) {
135            userProfileDocument = Framework.getService(UserProfileService.class).getUserProfileDocument(documentManager);
136            String locale = (String) userProfileDocument.getPropertyValue(UserProfileConstants.USER_PROFILE_LOCALE);
137            if (StringUtils.isEmpty(locale)) {
138                String currentLocale = localeSelector.getLocaleString();
139                if (!StringUtils.isEmpty(currentLocale)) {
140                    userProfileDocument.setPropertyValue(UserProfileConstants.USER_PROFILE_LOCALE, currentLocale);
141                }
142            }
143        }
144        return userProfileDocument;
145    }
146
147    public DocumentModel getUserProfileDocument(String userName) {
148        UserProfileService userProfileService = Framework.getService(UserProfileService.class);
149        return userProfileService.getUserProfileDocument(userName, documentManager);
150    }
151
152    public DocumentModel getUserProfile() {
153        if (currentUserProfile == null) {
154            UserProfileService userProfileService = Framework.getService(UserProfileService.class);
155            currentUserProfile = userProfileService.getUserProfile(getCurrentUserModel(), documentManager);
156        }
157        return currentUserProfile;
158    }
159
160    public DocumentModel getSelectedUserProfile() {
161        DocumentModel selectedUser = userManagementActions.getSelectedUser();
162        if (selectedUser == null) {
163            return null;
164        }
165        if (userProfileDocument == null) {
166            UserProfileService userProfileService = Framework.getService(UserProfileService.class);
167            userProfileDocument = userProfileService.getUserProfile(selectedUser, documentManager);
168        }
169        return userProfileDocument;
170    }
171
172    @Observer(value = { CURRENT_TAB_CHANGED_EVENT + "_" + MAIN_TABS_CATEGORY,
173            CURRENT_TAB_CHANGED_EVENT + "_" + NUXEO_ADMIN_CATEGORY,
174            CURRENT_TAB_CHANGED_EVENT + "_" + USER_CENTER_CATEGORY,
175            CURRENT_TAB_CHANGED_EVENT + "_" + USERS_GROUPS_MANAGER_SUB_TAB,
176            CURRENT_TAB_CHANGED_EVENT + "_" + USERS_GROUPS_HOME_SUB_TAB,
177            CURRENT_TAB_SELECTED_EVENT + "_" + MAIN_TABS_CATEGORY,
178            CURRENT_TAB_SELECTED_EVENT + "_" + NUXEO_ADMIN_CATEGORY,
179            CURRENT_TAB_SELECTED_EVENT + "_" + USER_CENTER_CATEGORY,
180            CURRENT_TAB_SELECTED_EVENT + "_" + USERS_GROUPS_MANAGER_SUB_TAB,
181            CURRENT_TAB_SELECTED_EVENT + "_" + USERS_GROUPS_HOME_SUB_TAB, USERS_LISTING_CHANGED, USER_SELECTED_CHANGED }, create = false)
182    @BypassInterceptors
183    public void resetState() {
184        userProfileDocument = null;
185        currentUserProfile = null;
186    }
187}