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.apps.sessions;
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.CmsSessionInfo;
035import org.opencms.main.OpenCms;
036import org.opencms.ui.A_CmsUI;
037import org.opencms.ui.CmsVaadinUtils;
038import org.opencms.ui.apps.CmsFileExplorerConfiguration;
039import org.opencms.ui.apps.Messages;
040import org.opencms.ui.apps.sessions.CmsSessionsTable.TableProperty;
041import org.opencms.ui.components.CmsBasicDialog;
042import org.opencms.ui.components.CmsUserInfo;
043import org.opencms.ui.components.OpenCmsTheme;
044import org.opencms.util.CmsDateUtil;
045
046import java.text.DateFormat;
047import java.util.ArrayList;
048import java.util.Date;
049import java.util.Iterator;
050import java.util.List;
051
052import org.apache.commons.logging.Log;
053
054import com.vaadin.ui.Button;
055import com.vaadin.ui.Button.ClickEvent;
056import com.vaadin.ui.Button.ClickListener;
057import com.vaadin.ui.Window;
058import com.vaadin.v7.ui.VerticalLayout;
059
060/**
061 * Dialog to show user information and to switch to user session.<p>
062 */
063public class CmsUserInfoDialog extends CmsBasicDialog {
064
065    /**vaadin serial id.*/
066    private static final long serialVersionUID = -8358238253459658269L;
067
068    /** Log instance for this class. */
069    static final Log LOG = CmsLog.getLog(CmsUserInfoDialog.class);
070
071    /**CmsObject.*/
072    protected CmsObject m_cms;
073
074    /**Session info (if showing specific session). */
075    protected CmsSessionInfo m_session;
076
077    /**vaadin component. */
078    private Button m_cancelButton;
079
080    /**vaadin component.*/
081    private VerticalLayout m_layout;
082
083    /**vaadin component. */
084    private Button m_okButton;
085
086    /**User to show iformation for. */
087    private CmsUser m_user;
088
089    /**
090     * private empty constructor.<p>
091     */
092    private CmsUserInfoDialog() {
093        //
094    }
095
096    /**
097     * private constructor.<p>
098     *
099     * @param sessionInfo id to session
100     * @param closeRunnable runnable called by closing window
101     */
102    private CmsUserInfoDialog(final CmsSessionInfo sessionInfo, final Runnable closeRunnable) {
103
104        m_session = sessionInfo;
105
106        m_cms = A_CmsUI.getCmsObject();
107        try {
108            m_user = m_cms.readUser(sessionInfo.getUserId());
109            init(closeRunnable);
110        } catch (CmsException e) {
111            LOG.error("Can not read user.", e);
112        }
113
114    }
115
116    /**
117     * private constructor.<p>
118     *
119     * @param user to show dialog for
120     * @param closeRunnable runnable called by closing window
121     */
122    private CmsUserInfoDialog(final CmsUser user, final Runnable closeRunnable) {
123
124        m_cms = A_CmsUI.getCmsObject();
125        m_user = user;
126        init(closeRunnable);
127
128    }
129
130    /**
131     * Gets the status text from given session.
132     *
133     * @param lastActivity miliseconds since last activity
134     * @return status string
135     */
136    public static String getStatusForItem(Long lastActivity) {
137
138        if (lastActivity.longValue() < CmsSessionsTable.INACTIVE_LIMIT) {
139            return CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_BROADCAST_COLS_STATUS_ACTIVE_0);
140        }
141        return CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_BROADCAST_COLS_STATUS_INACTIVE_0);
142    }
143
144    /**
145     * Gets the status style for given session.<p>
146     *
147     * @param lastActivity miliseconds since last activity
148     * @return style
149     */
150    public static String getStatusStyleForItem(Long lastActivity) {
151
152        if (lastActivity.longValue() < CmsSessionsTable.INACTIVE_LIMIT) {
153            return OpenCmsTheme.TABLE_COLUMN_BOX_CYAN;
154        }
155        return OpenCmsTheme.TABLE_COLUMN_BOX_GRAY;
156    }
157
158    /**
159     * Shows a dialog with user information for given session.
160     *
161     * @param session to show information for
162     */
163    public static void showUserInfo(CmsSessionInfo session) {
164
165        final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide);
166        CmsUserInfoDialog dialog = new CmsUserInfoDialog(session, new Runnable() {
167
168            public void run() {
169
170                window.close();
171            }
172
173        });
174        window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_SHOW_USER_0));
175        window.setContent(dialog);
176        A_CmsUI.get().addWindow(window);
177    }
178
179    /**
180     * Shows a dialog with user information.<p>
181     *
182     * @param user to show information for.
183     */
184    public static void showUserInfo(CmsUser user) {
185
186        final Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide);
187        CmsBasicDialog dialog = new CmsUserInfoDialog(user, new Runnable() {
188
189            public void run() {
190
191                window.close();
192
193            }
194
195        });
196        window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_SHOW_USER_0));
197        window.setContent(dialog);
198        A_CmsUI.get().addWindow(window);
199    }
200
201    /**
202     * Adds information lines to the user dialog.<p>
203     * @param currentSession the session which gets displayed or null
204     * @return list of lines
205     */
206    private List<String> getFurtherInfoLines(CmsSessionInfo currentSession) {
207
208        boolean neverActive = false;
209        Long inacTime = new Long(0L);
210        List<String> res = new ArrayList<String>();
211        if (currentSession == null) {
212            inacTime = new Long(System.currentTimeMillis() - m_user.getLastlogin());
213            neverActive = m_user.getLastlogin() == 0L;
214        } else {
215            inacTime = new Long(System.currentTimeMillis() - currentSession.getTimeUpdated());
216        }
217
218        String[] inactiveTime = CmsSessionInfo.getHourMinuteSecondTimeString(inacTime.longValue());
219
220        if (!neverActive) {
221            if (currentSession != null) {
222                res.add("");
223                res.add("<p>Session info:</p>");
224                res.add(
225                    CmsVaadinUtils.getMessageText(
226                        Messages.GUI_MESSAGES_LAST_ACTIVITY_2,
227                        inactiveTime[1] + ":" + inactiveTime[2],
228                        CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_MINUTES_0)) + getStatusHTML(inacTime));
229            } else {
230                res.add(getLastLoginMessage(inacTime));
231            }
232        }
233        res.add(
234            CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_USER_DATE_CREATED_0)
235                + ": "
236                + CmsDateUtil.getDateTime(
237                    new Date(m_user.getDateCreated()),
238                    DateFormat.SHORT,
239                    A_CmsUI.get().getLocale()));
240        if (currentSession != null) {
241            res.add(TableProperty.Site.getLocalizedMessage() + ": " + getSiteTitle(currentSession));
242
243            try {
244                res.add(
245                    TableProperty.Project.getLocalizedMessage()
246                        + ": "
247                        + A_CmsUI.getCmsObject().readProject(currentSession.getProject()).getName());
248            } catch (CmsException e) {
249                LOG.error("Unable to read project", e);
250            }
251        }
252        return res;
253    }
254
255    /**
256     * Get Message for show last login information.<p>
257     *
258     * @param inacTime time since last login in milli sec
259     * @return HTML String
260     */
261    private String getLastLoginMessage(Long inacTime) {
262
263        int days = (int)(inacTime.longValue() / (1000 * 60 * 60 * 24));
264        if (days == 0) {
265            return CmsVaadinUtils.getMessageText(Messages.GUI_USER_INFO_LAST_LOGIN_LESS_A_DAY_0);
266        }
267        if (days == 1) {
268            return CmsVaadinUtils.getMessageText(Messages.GUI_USER_INFO_LAST_LOGIN_YESTERDAY_0);
269        }
270        return CmsVaadinUtils.getMessageText(Messages.GUI_USER_INFO_LAST_LOGIN_DAYS_AGO_1, new Integer(days));
271    }
272
273    /**
274     * Gets the most current session for given user.<p>
275     *
276     * @param user CmsUser to get session for
277     * @return CmsSessionInfo or null if no session is available for user
278     */
279    private CmsSessionInfo getSessionForUser(CmsUser user) {
280
281        List<CmsSessionInfo> sessions = OpenCms.getSessionManager().getSessionInfos(user.getId());
282
283        if (sessions.isEmpty()) {
284            return null;
285        }
286
287        CmsSessionInfo currentSession = sessions.get(0);
288        for (CmsSessionInfo session : sessions) {
289            if (session.getTimeUpdated() > currentSession.getTimeUpdated()) {
290                currentSession = session;
291            }
292        }
293        return currentSession;
294    }
295
296    /**
297     * Gets the title for the site of the session.<p>
298     *
299     * @param currentSession to get site-title for
300     * @return title of site as string
301     */
302    private String getSiteTitle(CmsSessionInfo currentSession) {
303
304        String siteRoot = currentSession.getSiteRoot();
305        return (siteRoot.isEmpty() | siteRoot.equals("/"))
306        ? CmsVaadinUtils.getMessageText(org.opencms.ade.galleries.Messages.GUI_ROOT_SITE_0)
307        : OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot).getTitle();
308    }
309
310    /**
311     * Get status span.<p>
312     *
313     * @param inacTime time
314     * @return html
315     */
316    private String getStatusHTML(Long inacTime) {
317
318        return "<span class=\"" + getStatusStyleForItem(inacTime) + "\">" + getStatusForItem(inacTime) + "</span> ";
319    }
320
321    /**
322     * Initializes the dialog.<p>
323     *
324     * @param closeRunnable runnable
325     */
326    private void init(final Runnable closeRunnable) {
327
328        CmsVaadinUtils.readAndLocalizeDesign(this, CmsVaadinUtils.getWpMessagesForCurrentLocale(), null);
329
330        //Fix the width. Dialog can only be used by calling static method which creates a wide window.
331        CmsUserInfo info = new CmsUserInfo(m_user.getId(), "640px");
332        CmsSessionInfo session = m_session == null ? getSessionForUser(m_user) : m_session;
333        Iterator<String> iterator = getFurtherInfoLines(session).iterator();
334
335        while (iterator.hasNext()) {
336            info.addDetailLine(iterator.next());
337        }
338        m_layout.addComponent(info);
339
340        if (session != null) {
341            m_okButton.addClickListener(new ClickListener() {
342
343                private static final long serialVersionUID = 3096577957489665752L;
344
345                public void buttonClick(ClickEvent event) {
346
347                    try {
348                        A_CmsUI.get().changeProject(m_cms.readProject(session.getProject()));
349                        A_CmsUI.get().changeSite(session.getSiteRoot());
350
351                        String path = OpenCms.getSessionManager().switchUserFromSession(
352                            m_cms,
353                            CmsVaadinUtils.getRequest(),
354                            m_cms.readUser(session.getUserId()),
355                            session);
356
357                        if (path == null) {
358                            path = CmsVaadinUtils.getWorkplaceLink()
359                                + "?_lrid="
360                                + (new Date()).getTime()
361                                + "#!"
362                                + CmsFileExplorerConfiguration.APP_ID
363                                + "/"
364                                + session.getProject().getStringValue()
365                                + "!!"
366                                + session.getSiteRoot()
367                                + "!!!!";
368                        }
369                        A_CmsUI.get().getPage().setLocation(path);
370                        if (path.contains("workplace#")) {
371                            A_CmsUI.get().getPage().reload();
372                        }
373                    } catch (CmsException e) {
374                        //
375                    }
376                    closeRunnable.run();
377                }
378
379            });
380        }
381        setHideSwitchButton(session);
382
383        m_cancelButton.addClickListener(new ClickListener() {
384
385            private static final long serialVersionUID = -1033076596404978498L;
386
387            public void buttonClick(ClickEvent event) {
388
389                closeRunnable.run();
390
391            }
392        });
393    }
394
395    /**
396     * Hides the switch user button.<p>
397     *
398     * @param session to be checked
399     */
400    @SuppressWarnings("null")
401    private void setHideSwitchButton(CmsSessionInfo session) {
402
403        boolean visible = session != null;
404
405        if (visible) {
406            visible = !OpenCms.getSessionManager().getSessionInfo(CmsVaadinUtils.getRequest()).getSessionId().equals(
407                session.getSessionId());
408        }
409        m_okButton.setVisible(visible);
410
411    }
412
413}