001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.ui.components;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsUser;
032import org.opencms.main.CmsException;
033import org.opencms.main.CmsLog;
034import org.opencms.main.OpenCms;
035import org.opencms.ui.A_CmsUI;
036import org.opencms.ui.CmsUserIconHelper;
037import org.opencms.ui.CmsVaadinUtils;
038import org.opencms.ui.FontOpenCms;
039import org.opencms.ui.I_CmsDialogContext;
040import org.opencms.ui.actions.CmsPreferencesDialogAction;
041import org.opencms.ui.apps.CmsAppWorkplaceUi;
042import org.opencms.ui.components.CmsUploadButton.I_UploadListener;
043import org.opencms.ui.dialogs.CmsEmbeddedDialogContext;
044import org.opencms.ui.dialogs.CmsUserDataDialog;
045import org.opencms.ui.login.CmsChangePasswordDialog;
046import org.opencms.ui.login.CmsLoginController;
047import org.opencms.ui.shared.components.CmsUploadState.UploadType;
048import org.opencms.util.CmsStringUtil;
049import org.opencms.util.CmsUUID;
050import org.opencms.workplace.CmsAccountInfo;
051import org.opencms.workplace.CmsAccountInfo.Field;
052
053import java.text.DateFormat;
054import java.util.Date;
055import java.util.Locale;
056
057import org.apache.commons.logging.Log;
058
059import com.vaadin.server.ExternalResource;
060import com.vaadin.server.Resource;
061import com.vaadin.shared.ui.ContentMode;
062import com.vaadin.ui.Button;
063import com.vaadin.ui.Button.ClickEvent;
064import com.vaadin.ui.Button.ClickListener;
065import com.vaadin.ui.Component;
066import com.vaadin.ui.CssLayout;
067import com.vaadin.ui.HorizontalLayout;
068import com.vaadin.ui.Image;
069import com.vaadin.ui.Label;
070import com.vaadin.ui.UI;
071import com.vaadin.ui.VerticalLayout;
072
073/**
074 * Displays the current user info.<p>
075 */
076public class CmsUserInfo extends VerticalLayout {
077
078    /** The HTML line break. */
079    private static final String LINE_BREAK = "<br />";
080
081    /** The serial version id. */
082    private static final long serialVersionUID = 7215454442218119869L;
083    /** The logger for this class. */
084    static Log LOG = CmsLog.getLog(CmsUserInfo.class.getName());
085
086    /**HTML open div tag.*/
087    static final String DIV_HTML = "<div style=\"vertical-align:middle;\">";
088
089    /**Free space. */
090    static final String HTML_SPACE = "&nbsp;";
091
092    /**Html close div tag.*/
093    static final String DIV_END = "</div>";
094
095    /** The dialog context. */
096    I_CmsDialogContext m_context;
097
098    /** The current user. */
099    CmsUser m_user;
100
101    /** The info. */
102    private Label m_info;
103
104    /** The details. */
105    private Label m_details;
106
107    /** The info panel. */
108    private HorizontalLayout m_infoPanel;
109
110    /** The user menu. */
111    private CmsVerticalMenu m_menu;
112
113    /** The upload listener. */
114    private I_UploadListener m_uploadListener;
115
116    /**
117     * Constructor.<p>
118     *
119     * @param cmsUUID uuid of user to show info for
120     */
121    public CmsUserInfo(CmsUUID cmsUUID) {
122
123        this(cmsUUID, null);
124
125    }
126
127    /**
128     * Constructor with the option to set a width for the name label.<p>
129     *
130     * @param cmsUUID of user
131     * @param widthString valid width string or null
132     */
133    public CmsUserInfo(CmsUUID cmsUUID, String widthString) {
134
135        CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
136
137        if (widthString != null) {
138            m_info.setWidth(widthString);
139        }
140
141        try {
142            CmsObject cms = A_CmsUI.getCmsObject();
143            m_user = cms.readUser(cmsUUID);
144
145            m_info.setContentMode(ContentMode.HTML);
146            m_info.setValue(generateInfo(cms, UI.getCurrent().getLocale()));
147            m_details.setContentMode(ContentMode.HTML);
148            m_details.setValue(generateInfoDetails(cms, UI.getCurrent().getLocale()));
149            m_infoPanel.addComponent(createImageButton(), 0);
150            m_menu.setVisible(false);
151        } catch (CmsException e) {
152            LOG.error("Unable to read user", e);
153        }
154
155    }
156
157    /**
158     * Constructor.<p>
159     *
160     * @param uploadListener the user image upload listener
161     * @param context the dialog context
162     */
163    public CmsUserInfo(I_UploadListener uploadListener, I_CmsDialogContext context) {
164
165        CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
166        CmsObject cms = A_CmsUI.getCmsObject();
167        m_uploadListener = uploadListener;
168        m_user = cms.getRequestContext().getCurrentUser();
169        m_context = context;
170        m_info.setContentMode(ContentMode.HTML);
171        m_info.setValue(generateInfo(cms, UI.getCurrent().getLocale()));
172        m_details.setContentMode(ContentMode.HTML);
173        m_details.setValue(generateInfoDetails(cms, UI.getCurrent().getLocale()));
174        m_infoPanel.addComponent(createImageButton(), 0);
175        initUserMenu();
176
177    }
178
179    /**
180     * Adds a line to the details label.<p>
181     *
182     * @param lineHtml the line to be added
183     */
184    public void addDetailLine(String lineHtml) {
185
186        lineHtml = lineHtml.isEmpty() ? HTML_SPACE : lineHtml;
187
188        m_details.setValue(m_details.getValue() + DIV_HTML + lineHtml + DIV_END);
189    }
190
191    /**
192     * Shows the user preferences dialog.<p>
193     */
194    void editUserData() {
195
196        if (m_context instanceof CmsEmbeddedDialogContext) {
197            ((CmsEmbeddedDialogContext)m_context).closeWindow(true);
198        } else {
199            A_CmsUI.get().closeWindows();
200        }
201        CmsUserDataDialog dialog = new CmsUserDataDialog(m_context);
202        m_context.start(CmsVaadinUtils.getMessageText(Messages.GUI_USER_EDIT_0), dialog);
203    }
204
205    /**
206     * Executes the logout.<p>
207     */
208    void logout() {
209
210        CmsLoginController.logout();
211    }
212
213    /**
214     * Creates the user image button.<p>
215     *
216     * @return the created button
217     */
218    private Component createImageButton() {
219
220        CssLayout layout = new CssLayout();
221        layout.addStyleName(OpenCmsTheme.USER_IMAGE);
222        Image userImage = new Image();
223        userImage.setSource(
224            new ExternalResource(
225                OpenCms.getWorkplaceAppManager().getUserIconHelper().getBigIconPath(A_CmsUI.getCmsObject(), m_user)));
226
227        layout.addComponent(userImage);
228
229        if (!CmsAppWorkplaceUi.isOnlineProject() & (m_uploadListener != null)) {
230            CmsUploadButton uploadButton = createImageUploadButton(
231                null,
232                FontOpenCms.UPLOAD_SMALL,
233                m_user,
234                m_uploadListener);
235            layout.addComponent(uploadButton);
236            if (CmsUserIconHelper.hasUserImage(m_user)) {
237                Button deleteButton = new Button(FontOpenCms.TRASH_SMALL);
238                deleteButton.addClickListener(new ClickListener() {
239
240                    private static final long serialVersionUID = 1L;
241
242                    public void buttonClick(ClickEvent event) {
243
244                        OpenCms.getWorkplaceAppManager().getUserIconHelper().deleteUserImage(A_CmsUI.getCmsObject());
245                        m_context.updateUserInfo();
246
247                    }
248                });
249                layout.addComponent(deleteButton);
250            }
251        }
252
253        return layout;
254    }
255
256    /**
257     * Creates an user image upload button.<p>
258     *
259     * @param label the label to use
260     * @param icon the icon to use
261     * @param user the user
262     * @param uploadListener the upload listener
263     *
264     * @return the button
265     */
266    private CmsUploadButton createImageUploadButton(
267        String label,
268        Resource icon,
269        CmsUser user,
270        I_UploadListener uploadListener) {
271
272        CmsUploadButton uploadButton = new CmsUploadButton(
273            CmsUserIconHelper.USER_IMAGE_FOLDER + CmsUserIconHelper.TEMP_FOLDER);
274        if (label != null) {
275            uploadButton.setCaption(label);
276        }
277        if (icon != null) {
278            uploadButton.setIcon(icon);
279        }
280        uploadButton.getState().setUploadType(UploadType.singlefile);
281        uploadButton.getState().setTargetFileNamePrefix(user.getId().toString());
282        uploadButton.getState().setDialogTitle(
283            CmsVaadinUtils.getMessageText(Messages.GUI_USER_INFO_UPLOAD_IMAGE_DIALOG_TITLE_0));
284        uploadButton.addUploadListener(uploadListener);
285        return uploadButton;
286
287    }
288
289    /**
290     * Generates the info data HTML.<p>
291     *
292     * @param cms the cms context
293     * @param locale the locale
294     *
295     * @return the info data HTML
296     */
297    private String generateInfo(CmsObject cms, Locale locale) {
298
299        StringBuffer infoHtml = new StringBuffer(128);
300        infoHtml.append("<p>").append(CmsStringUtil.escapeHtml(m_user.getSimpleName())).append("</p>");
301        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_user.getFirstname())) {
302            infoHtml.append(CmsStringUtil.escapeHtml(m_user.getFirstname())).append("&nbsp;");
303        }
304        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_user.getLastname())) {
305            infoHtml.append(CmsStringUtil.escapeHtml(m_user.getLastname()));
306        }
307        infoHtml.append(LINE_BREAK);
308        return infoHtml.toString();
309    }
310
311    /**
312     * Generates the user info details.<p>
313     *
314     * @param cms the cms context
315     * @param locale the locale
316     *
317     * @return the user info details
318     */
319    private String generateInfoDetails(CmsObject cms, Locale locale) {
320
321        StringBuffer infoHtml = new StringBuffer(128);
322        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_user.getEmail())) {
323            infoHtml.append(CmsStringUtil.escapeHtml(m_user.getEmail())).append(LINE_BREAK);
324        }
325        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_user.getOuFqn())) {
326            infoHtml.append(CmsStringUtil.escapeHtml(m_user.getOuFqn())).append(LINE_BREAK);
327        }
328        for (CmsAccountInfo info : OpenCms.getWorkplaceManager().getAccountInfos()) {
329            if (!info.getField().equals(Field.firstname)
330                && !info.getField().equals(Field.lastname)
331                && !Field.email.equals(info.getField())) {
332                String value = info.getValue(m_user);
333                if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(value)) {
334                    infoHtml.append(CmsStringUtil.escapeHtml(value)).append(LINE_BREAK);
335                }
336            }
337        }
338        if (OpenCms.getSessionManager().getSessionInfos(m_user.getId()).size() > 0) {
339            infoHtml.append(
340                Messages.get().getBundle(locale).key(
341                    Messages.GUI_USER_INFO_ONLINE_SINCE_1,
342                    DateFormat.getTimeInstance(DateFormat.DEFAULT, locale).format(
343                        new Date(m_user.getLastlogin())))).append(LINE_BREAK);
344        }
345
346        return infoHtml.toString();
347    }
348
349    /**
350     * Initializes the use menu.<p>
351     */
352    private void initUserMenu() {
353
354        if (!m_user.isManaged()) {
355            m_menu.addMenuEntry(
356                CmsVaadinUtils.getMessageText(org.opencms.ui.Messages.GUI_CHANGE_PASSWORD_BUTTON_0),
357                null).addClickListener(new ClickListener() {
358
359                    private static final long serialVersionUID = 1L;
360
361                    public void buttonClick(ClickEvent event) {
362
363                        m_context.start(
364                            CmsVaadinUtils.getMessageText(org.opencms.ui.Messages.GUI_PWCHANGE_HEADER_0)
365                                + m_user.getSimpleName(),
366                            new CmsChangePasswordDialog(m_context));
367                    }
368                });
369        }
370        final CmsPreferencesDialogAction preferencesAction = new CmsPreferencesDialogAction();
371        m_menu.addMenuEntry(preferencesAction.getTitle(A_CmsUI.get().getLocale()), null).addClickListener(
372            new ClickListener() {
373
374                private static final long serialVersionUID = 1L;
375
376                public void buttonClick(ClickEvent event) {
377
378                    preferencesAction.executeAction(m_context);
379                }
380            });
381        if (!m_user.isManaged()) {
382            m_menu.addMenuEntry(CmsVaadinUtils.getMessageText(Messages.GUI_USER_EDIT_0), null).addClickListener(
383                new Button.ClickListener() {
384
385                    private static final long serialVersionUID = 1L;
386
387                    public void buttonClick(ClickEvent event) {
388
389                        editUserData();
390                    }
391                });
392        }
393        m_menu.addMenuEntry(
394            CmsVaadinUtils.getMessageText(org.opencms.workplace.explorer.Messages.GUI_EXPLORER_CONTEXT_LOGOUT_0),
395            null).addClickListener(new Button.ClickListener() {
396
397                private static final long serialVersionUID = 1L;
398
399                public void buttonClick(ClickEvent event) {
400
401                    logout();
402                }
403            });
404    }
405}