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.CmsUser;
031import org.opencms.main.CmsException;
032import org.opencms.main.CmsLog;
033import org.opencms.main.CmsSessionInfo;
034import org.opencms.main.OpenCms;
035import org.opencms.security.CmsOrganizationalUnit;
036import org.opencms.site.CmsSite;
037import org.opencms.ui.A_CmsUI;
038import org.opencms.ui.CmsCssIcon;
039import org.opencms.ui.CmsVaadinUtils;
040import org.opencms.ui.apps.CmsAppWorkplaceUi;
041import org.opencms.ui.apps.CmsFileExplorerConfiguration;
042import org.opencms.ui.apps.CmsPageEditorConfiguration;
043import org.opencms.ui.apps.Messages;
044import org.opencms.ui.components.CmsBasicDialog;
045import org.opencms.ui.components.CmsResourceIcon;
046import org.opencms.ui.components.OpenCmsTheme;
047import org.opencms.ui.contextmenu.CmsContextMenu;
048import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode;
049import org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry;
050import org.opencms.util.CmsStringUtil;
051import org.opencms.util.CmsUUID;
052
053import java.util.ArrayList;
054import java.util.List;
055import java.util.Locale;
056import java.util.Set;
057
058import org.apache.commons.logging.Log;
059
060import com.vaadin.event.MouseEvents;
061import com.vaadin.shared.MouseEventDetails.MouseButton;
062import com.vaadin.ui.Component;
063import com.vaadin.ui.Window;
064import com.vaadin.ui.themes.ValoTheme;
065import com.vaadin.v7.data.Item;
066import com.vaadin.v7.data.util.IndexedContainer;
067import com.vaadin.v7.data.util.filter.Or;
068import com.vaadin.v7.data.util.filter.SimpleStringFilter;
069import com.vaadin.v7.event.ItemClickEvent;
070import com.vaadin.v7.event.ItemClickEvent.ItemClickListener;
071import com.vaadin.v7.shared.ui.label.ContentMode;
072import com.vaadin.v7.ui.Label;
073import com.vaadin.v7.ui.Table;
074
075/**
076 * Class for the table to show all current sessions.<p>
077 */
078public class CmsSessionsTable extends Table {
079
080    /**
081     * The menu entry to switch to the explorer of concerning site.<p>
082     */
083    class ExplorerEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
084
085        /**
086         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
087         */
088        public void executeAction(Set<String> data) {
089
090            try {
091                String sessionId = data.iterator().next();
092                CmsSessionInfo session = OpenCms.getSessionManager().getSessionInfo(new CmsUUID(sessionId));
093                String siteRoot = session.getSiteRoot();
094                A_CmsUI.getCmsObject().getRequestContext().setSiteRoot(siteRoot);
095                A_CmsUI.getCmsObject().getRequestContext().setCurrentProject(
096                    A_CmsUI.getCmsObject().readProject(session.getProject()));
097                CmsAppWorkplaceUi.get().getNavigator().navigateTo(
098                    CmsFileExplorerConfiguration.APP_ID + "/" + session.getProject() + "!!" + siteRoot + "!!");
099            } catch (CmsException e) {
100                LOG.error("Cannot read project", e);
101            }
102        }
103
104        /**
105         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
106         */
107        public String getTitle(Locale locale) {
108
109            return Messages.get().getBundle(locale).key(Messages.GUI_EXPLORER_TITLE_0);
110        }
111
112        /**
113         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
114         */
115        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
116
117            if ((data == null) || (data.size() > 1)) {
118                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
119            }
120
121            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
122
123        }
124    }
125
126    /**
127     * The menu entry to switch to the explorer of concerning site.<p>
128     */
129    class KillEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
130
131        /**
132         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
133         */
134        public void executeAction(Set<String> data) {
135
136            showKillDialog(
137                data,
138                CmsVaadinUtils.getMessageText(
139                    Messages.GUI_MESSAGES_DESTROY_SESSIONS_1,
140                    CmsSessionsApp.getUserNames(data, CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_AND_0))),
141                CmsSessionsTable.this);
142
143        }
144
145        /**
146         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
147         */
148        public String getTitle(Locale locale) {
149
150            return CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_DESTROY_SESSION_0);
151        }
152
153        /**
154         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
155         */
156        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
157
158            if ((data.size() == 1) & data.iterator().next().equals(m_mySessionId)) {
159                return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
160            }
161
162            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
163        }
164
165    }
166
167    /**
168     * The menu entry to switch to the page editor of concerning site.<p>
169     */
170    class PageEditorEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
171
172        /**
173         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
174         */
175        public void executeAction(Set<String> data) {
176
177            try {
178                String sessionId = data.iterator().next();
179                CmsSessionInfo session = OpenCms.getSessionManager().getSessionInfo(new CmsUUID(sessionId));
180                String siteRoot = session.getSiteRoot();
181                A_CmsUI.get().changeSite(siteRoot);
182                A_CmsUI.get().changeProject(A_CmsUI.getCmsObject().readProject(session.getProject()));
183
184                CmsPageEditorConfiguration pageeditorApp = new CmsPageEditorConfiguration();
185                pageeditorApp.getAppLaunchCommand().run();
186            } catch (CmsException e) {
187                LOG.error("Cannot read project", e);
188            }
189        }
190
191        /**
192         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
193         */
194        public String getTitle(Locale locale) {
195
196            return CmsVaadinUtils.getMessageText(Messages.GUI_PAGEEDITOR_TITLE_0);
197        }
198
199        /**
200         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
201         */
202        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
203
204            if ((data == null) || (data.size() > 1)) {
205                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
206            }
207            String sessionId = data.iterator().next();
208            CmsSessionInfo session = OpenCms.getSessionManager().getSessionInfo(new CmsUUID(sessionId));
209            String siteRoot = session.getSiteRoot();
210            if (CmsStringUtil.isEmptyOrWhitespaceOnly(siteRoot)
211                || OpenCms.getSiteManager().getSharedFolder().startsWith(siteRoot)) {
212                return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
213            }
214            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
215        }
216
217    }
218
219    /**
220     * The menu entry to switch to the explorer of concerning site.<p>
221     */
222    class SendBroadcastEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
223
224        /**
225         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
226         */
227        public void executeAction(Set<String> data) {
228
229            CmsSessionsApp.showSendBroadcastDialog(
230                data,
231                CmsVaadinUtils.getMessageText(
232                    Messages.GUI_MESSAGES_BROADCAST_SESSIONS_1,
233                    CmsSessionsApp.getUserNames(data, CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_AND_0))),
234                CmsSessionsTable.this);
235
236        }
237
238        /**
239         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
240         */
241        public String getTitle(Locale locale) {
242
243            return CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_BROADCAST_SEND_0);
244        }
245
246        /**
247         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
248         */
249        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
250
251            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
252        }
253
254    }
255
256    /**
257     * All table properties.<p>
258     */
259    enum TableProperty {
260
261        /**Date of release column.*/
262        DateCreated(Messages.GUI_MESSAGES_BROADCAST_COLS_CREATION_0, String.class, "", false),
263        /**Icon.*/
264        Icon(null, Label.class, null, false),
265
266        /**Icon column.*/
267        IS_ACTIVE(Messages.GUI_MESSAGES_BROADCAST_COLS_STATUS_0, Long.class, Long.valueOf(0L), false),
268
269        /**Is Broadcast send but not displayed.*/
270        IS_WAITING(null, Boolean.class, Boolean.valueOf(false), false),
271
272        /**Date of expiration column. */
273        OrgUnit(Messages.GUI_MESSAGES_BROADCAST_COLS_ORGUNIT_0, String.class, "", false),
274
275        /**Last modified column. */
276        Project(Messages.GUI_MESSAGES_BROADCAST_COLS_PROJECT_0, String.class, "", false),
277
278        /**Path column.*/
279        Site(Messages.GUI_MESSAGES_BROADCAST_COLS_SITE_0, String.class, "", false),
280
281        /**Broken links column. */
282        UserName(Messages.GUI_MESSAGES_BROADCAST_COLS_USER_0, String.class, "", false);
283
284        /**Indicates if column is collapsable.*/
285        private boolean m_collapsable;
286
287        /**Default value for column.*/
288        private Object m_defaultValue;
289
290        /**Header Message key.*/
291        private String m_headerMessage;
292
293        /**Type of column property.*/
294        private Class<?> m_type;
295
296        /**
297         * constructor.
298         *
299         * @param headerMessage key
300         * @param type to property
301         * @param defaultValue of column
302         * @param collapsable should this column be collapsable?
303         */
304        TableProperty(String headerMessage, Class<?> type, Object defaultValue, boolean collapsable) {
305
306            m_headerMessage = headerMessage;
307            m_type = type;
308            m_defaultValue = defaultValue;
309            m_collapsable = collapsable;
310        }
311
312        /**
313         * Returns list of all properties with non-empty header.<p>
314         *
315         * @return list of properties
316         */
317        static List<TableProperty> withHeader() {
318
319            List<TableProperty> props = new ArrayList<TableProperty>();
320
321            for (TableProperty prop : TableProperty.values()) {
322                if (prop.m_headerMessage != null) {
323                    props.add(prop);
324                }
325            }
326            return props;
327        }
328
329        /**
330         * Returns the default value of property.<p>
331         *
332         * @return object
333         */
334        Object getDefaultValue() {
335
336            return m_defaultValue;
337        }
338
339        /**
340         * Returns localized header.<p>
341         *
342         * @return string for header
343         */
344        String getLocalizedMessage() {
345
346            if (m_headerMessage == null) {
347                return "";
348            }
349            return CmsVaadinUtils.getMessageText(m_headerMessage);
350        }
351
352        /**
353         * Returns tye of value for given property.<p>
354         *
355         * @return type
356         */
357        Class<?> getType() {
358
359            return m_type;
360        }
361
362        /**
363         * Indicates if column is collapsable.<p>
364         *
365         * @return boolean, true = is collapsable
366         */
367        boolean isCollapsable() {
368
369            return m_collapsable;
370        }
371
372    }
373
374    /**
375     * User entry.<p>
376     */
377    class UserEntry implements I_CmsSimpleContextMenuEntry<Set<String>>, I_CmsSimpleContextMenuEntry.I_HasCssStyles {
378
379        /**
380         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
381         */
382        public void executeAction(Set<String> context) {
383
384            showUserInfoWindow(context.iterator().next());
385
386        }
387
388        /**
389         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry.I_HasCssStyles#getStyles()
390         */
391        public String getStyles() {
392
393            return ValoTheme.LABEL_BOLD;
394        }
395
396        /**
397         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
398         */
399        public String getTitle(Locale locale) {
400
401            return CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_SHOW_USER_0);
402        }
403
404        /**
405         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
406         */
407        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
408
409            return (data != null) && (data.size() == 1)
410            ? CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE
411            : CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
412        }
413
414    }
415
416    /** The logger for this class. */
417    static Log LOG = CmsLog.getLog(CmsSessionsTable.class.getName());
418
419    /**Time limit (in milliseconds) since when a user is inactive.*/
420    public static final long INACTIVE_LIMIT = 450 * 1000; //7.5 minutes
421
422    /**vaadin serial id.*/
423    private static final long serialVersionUID = 4136423899776482696L;
424
425    /**Session id of user who uses the tool.*/
426    protected String m_mySessionId;
427
428    /**Container holding table data.*/
429    private IndexedContainer m_container;
430
431    /** The context menu. */
432    private CmsContextMenu m_menu;
433
434    /** The available menu entries. */
435    private List<I_CmsSimpleContextMenuEntry<Set<String>>> m_menuEntries;
436
437    /**
438     * public constructor.<p>
439     */
440    public CmsSessionsTable() {
441
442        try {
443
444            m_mySessionId = OpenCms.getSessionManager().getSessionInfo(
445                CmsVaadinUtils.getRequest()).getSessionId().getStringValue();
446
447            ini();
448
449            setColumnWidth(TableProperty.IS_ACTIVE, 80);
450
451            addGeneratedColumn(TableProperty.Icon, new ColumnGenerator() {
452
453                private static final long serialVersionUID = 1431421875590401227L;
454
455                public Object generateCell(Table source, Object itemId, Object columnId) {
456
457                    CmsCssIcon icon = new CmsCssIcon(OpenCmsTheme.ICON_SESSION);
458                    if (((Boolean)source.getItem(itemId).getItemProperty(
459                        TableProperty.IS_WAITING).getValue()).booleanValue()) {
460                        icon.setOverlay(OpenCmsTheme.STATE_CHANGED + " " + CmsResourceIcon.ICON_CLASS_CHANGED);
461                    }
462                    return new Label(icon.getHtmlWithOverlay(), ContentMode.HTML);
463                }
464
465            });
466
467            setCellStyleGenerator(new CellStyleGenerator() {
468
469                private static final long serialVersionUID = 1L;
470
471                public String getStyle(Table source, Object itemId, Object propertyId) {
472
473                    String furtherClass = "";
474                    if (m_mySessionId.equals(itemId)) {
475                        furtherClass = " " + OpenCmsTheme.IN_NAVIGATION;
476                    }
477
478                    if (TableProperty.UserName.equals(propertyId)) {
479                        return " " + OpenCmsTheme.HOVER_COLUMN + furtherClass;
480                    }
481
482                    if (((Boolean)source.getItem(itemId).getItemProperty(
483                        TableProperty.IS_WAITING).getValue()).booleanValue() & (propertyId == null)) {
484                        return " " + OpenCmsTheme.STATE_CHANGED;
485                    }
486
487                    if (TableProperty.IS_ACTIVE.equals(propertyId)) {
488                        return CmsUserInfoDialog.getStatusStyleForItem(
489                            (Long)source.getItem(itemId).getItemProperty(TableProperty.IS_ACTIVE).getValue());
490
491                    }
492
493                    return null;
494                }
495            });
496            addItemClickListener(new ItemClickListener() {
497
498                private static final long serialVersionUID = 7957778390938304845L;
499
500                public void itemClick(ItemClickEvent event) {
501
502                    onItemClick(event, event.getItemId(), event.getPropertyId());
503                }
504
505            });
506
507            addGeneratedColumn(TableProperty.IS_ACTIVE, new ColumnGenerator() {
508
509                private static final long serialVersionUID = -6781906011584975559L;
510
511                public Object generateCell(Table source, Object itemId, Object columnId) {
512
513                    return CmsUserInfoDialog.getStatusForItem(
514                        (Long)source.getItem(itemId).getItemProperty(TableProperty.IS_ACTIVE).getValue());
515
516                }
517
518            });
519
520            setItemDescriptionGenerator(new ItemDescriptionGenerator() {
521
522                private static final long serialVersionUID = 7367011213487089661L;
523
524                public String generateDescription(Component source, Object itemId, Object propertyId) {
525
526                    if (TableProperty.IS_ACTIVE.equals(propertyId)) {
527
528                        String[] ret = CmsSessionInfo.getHourMinuteSecondTimeString(
529                            ((Long)((Table)source).getItem(itemId).getItemProperty(propertyId).getValue()).longValue());
530
531                        if (Integer.parseInt(ret[1]) == 1) {
532                            return CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_LAST_ACTIVITY_ONE_MINUTE_0);
533                        }
534                        if (Integer.parseInt(ret[1]) == 0) {
535                            return CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_LAST_ACTIVITY_LESS_ONE_MINUTE_0);
536                        }
537                        return CmsVaadinUtils.getMessageText(
538                            Messages.GUI_MESSAGES_LAST_ACTIVITY_MINUTES_1,
539                            Integer.valueOf(ret[1]));
540                    }
541                    return null;
542                }
543            });
544
545        } catch (CmsException e) {
546            LOG.error("Unable to read sessions", e);
547        }
548
549    }
550
551    /**
552     * Runnable called when a window should be closed.<p>
553     * Reinitializes the table.<p>
554     *
555     * @param window to be closed
556     * @param table to be updated
557     * @return a runnable
558     */
559    protected static Runnable getCloseRunnable(final Window window, final CmsSessionsTable table) {
560
561        return new Runnable() {
562
563            public void run() {
564
565                window.close();
566                try {
567                    table.ini();
568                } catch (CmsException e) {
569                    LOG.error("Error on reading session information", e);
570                }
571
572            }
573
574        };
575    }
576
577    /**
578     *Shows the dialog to destroy given sessions.<p>
579     *
580     * @param ids to kill session
581     * @param caption of the window
582     * @param table to be updated
583     */
584    protected static void showKillDialog(Set<String> ids, String caption, final CmsSessionsTable table) {
585
586        final Window window = CmsBasicDialog.prepareWindow();
587        window.setCaption(caption);
588        window.setContent(new CmsKillSessionDialog(ids, getCloseRunnable(window, table)));
589        A_CmsUI.get().addWindow(window);
590    }
591
592    /**
593     * Filters the table according to given search string.<p>
594     *
595     * @param search string to be looked for.
596     */
597    public void filterTable(String search) {
598
599        m_container.removeAllContainerFilters();
600        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(search)) {
601            m_container.addContainerFilter(
602                new Or(
603                    new SimpleStringFilter(TableProperty.UserName, search, true, false),
604                    new SimpleStringFilter(TableProperty.Site, search, true, false),
605                    new SimpleStringFilter(TableProperty.Project, search, true, false)));
606        }
607        if ((getValue() != null) & !((Set<String>)getValue()).isEmpty()) {
608            setCurrentPageFirstItemId(((Set<String>)getValue()).iterator().next());
609        }
610    }
611
612    /**
613     * Initializes the table.<p>
614     *
615     * @throws CmsException when something goes wrong
616     */
617    protected void ini() throws CmsException {
618
619        if (m_container == null) {
620            m_container = new IndexedContainer();
621            setContainerDataSource(m_container);
622        } else {
623            m_container.removeAllItems();
624        }
625        for (TableProperty prop : TableProperty.values()) {
626            m_container.addContainerProperty(prop, prop.getType(), prop.getDefaultValue());
627            setColumnHeader(prop, prop.getLocalizedMessage());
628        }
629
630        setColumnWidth(TableProperty.Icon, 40);
631        setSelectable(true);
632        setMultiSelect(true);
633
634        m_menu = new CmsContextMenu();
635        m_menu.setAsTableContextMenu(this);
636
637        List<CmsSessionInfo> sessionInfos = OpenCms.getSessionManager().getSessionInfos();
638        List<CmsOrganizationalUnit> manageableOus = OpenCms.getRoleManager().getManageableOrgUnits(
639            A_CmsUI.getCmsObject(),
640            "",
641            true,
642            false);
643        for (CmsSessionInfo session : sessionInfos) {
644            CmsUser user = A_CmsUI.getCmsObject().readUser(session.getUserId());
645            CmsOrganizationalUnit userOu = OpenCms.getOrgUnitManager().readOrganizationalUnit(
646                A_CmsUI.getCmsObject(),
647                user.getOuFqn());
648            if (!(manageableOus.contains(userOu) && !user.isWebuser())) {
649                continue;
650            }
651            //            CmsListItem item = getList().newItem(sessionInfo.getSessionId().toString());
652            Item item = m_container.addItem(session.getSessionId().getStringValue());
653            item.getItemProperty(TableProperty.UserName).setValue(user.getName());
654            item.getItemProperty(TableProperty.DateCreated).setValue(
655                session.getAgeOfSession() + " " + CmsVaadinUtils.getMessageText(Messages.GUI_MESSAGES_HOUR_0));
656            item.getItemProperty(TableProperty.IS_ACTIVE).setValue(
657                Long.valueOf(System.currentTimeMillis() - session.getTimeLastAction()));
658            item.getItemProperty(TableProperty.OrgUnit).setValue(userOu.getName());
659            item.getItemProperty(TableProperty.Project).setValue(
660                A_CmsUI.getCmsObject().readProject(session.getProject()).getName());
661            CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(session.getSiteRoot());
662            String siteTitle = site == null
663            ? CmsVaadinUtils.getMessageText(org.opencms.ade.galleries.Messages.GUI_ROOT_SITE_0)
664            : site.getTitle();
665            item.getItemProperty(TableProperty.Site).setValue(siteTitle);
666
667            item.getItemProperty(TableProperty.IS_WAITING).setValue(
668                Boolean.valueOf(!session.getBroadcastQueue().isEmpty()));
669
670        }
671
672        setVisibleColumns(
673            TableProperty.Icon,
674            TableProperty.IS_ACTIVE,
675            TableProperty.UserName,
676            TableProperty.DateCreated,
677            TableProperty.Site,
678            TableProperty.Project);
679
680    }
681
682    /**
683     * Shows window with user information.<p>
684     *
685     * @param data sessionid to be shown user off
686     */
687    protected void showUserInfoWindow(String data) {
688
689        CmsUserInfoDialog.showUserInfo(OpenCms.getSessionManager().getSessionInfo(data));
690    }
691
692    /**
693     * Returns the available menu entries.<p>
694     *
695     * @return the menu entries
696     */
697    List<I_CmsSimpleContextMenuEntry<Set<String>>> getMenuEntries() {
698
699        if (m_menuEntries == null) {
700            m_menuEntries = new ArrayList<I_CmsSimpleContextMenuEntry<Set<String>>>();
701            m_menuEntries.add(new UserEntry());
702            m_menuEntries.add(new ExplorerEntry());
703            m_menuEntries.add(new PageEditorEntry());
704            m_menuEntries.add(new SendBroadcastEntry());
705            m_menuEntries.add(new KillEntry());
706        }
707        return m_menuEntries;
708    }
709
710    /**
711     * Handles the table item clicks, including clicks on images inside of a table item.<p>
712     *
713     * @param event the click event
714     * @param itemId of the clicked row
715     * @param propertyId column id
716     */
717    void onItemClick(MouseEvents.ClickEvent event, Object itemId, Object propertyId) {
718
719        if (!event.isCtrlKey() && !event.isShiftKey()) {
720
721            changeValueIfNotMultiSelect(itemId);
722
723            // don't interfere with multi-selection using control key
724            if (event.getButton().equals(MouseButton.RIGHT) || (TableProperty.Icon.equals(propertyId))) {
725
726                m_menu.setEntries(getMenuEntries(), (Set<String>)getValue());
727                m_menu.openForTable(event, itemId, propertyId, this);
728            } else if (event.getButton().equals(MouseButton.LEFT) && TableProperty.UserName.equals(propertyId)) {
729                showUserInfoWindow(((Set<String>)getValue()).iterator().next());
730            }
731        }
732    }
733
734    /**
735     * Checks value of table and sets it new if needed:<p>
736     * if multiselect: new itemId is in current Value? -> no change of value<p>
737     * no multiselect and multiselect, but new item not selected before: set value to new item<p>
738     *
739     * @param itemId if of clicked item
740     */
741    private void changeValueIfNotMultiSelect(Object itemId) {
742
743        @SuppressWarnings("unchecked")
744        Set<String> value = (Set<String>)getValue();
745        if (value == null) {
746            select(itemId);
747        } else if (!value.contains(itemId)) {
748            setValue(null);
749            select(itemId);
750        }
751    }
752
753}