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.sitemanager;
029
030import org.opencms.file.CmsFile;
031import org.opencms.file.CmsObject;
032import org.opencms.file.CmsResource;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.main.OpenCms;
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.A_CmsWorkplaceApp;
041import org.opencms.ui.apps.CmsAppWorkplaceUi;
042import org.opencms.ui.apps.CmsFileExplorerConfiguration;
043import org.opencms.ui.apps.CmsPageEditorConfiguration;
044import org.opencms.ui.apps.CmsSitemapEditorConfiguration;
045import org.opencms.ui.apps.Messages;
046import org.opencms.ui.apps.user.I_CmsFilterableTable;
047import org.opencms.ui.components.CmsResourceIcon;
048import org.opencms.ui.components.OpenCmsTheme;
049import org.opencms.ui.contextmenu.CmsContextMenu;
050import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode;
051import org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry;
052import org.opencms.util.CmsFileUtil;
053import org.opencms.util.CmsStringUtil;
054
055import java.io.ByteArrayInputStream;
056import java.io.InputStream;
057import java.util.ArrayList;
058import java.util.List;
059import java.util.Locale;
060import java.util.Set;
061
062import org.apache.commons.logging.Log;
063
064import com.vaadin.event.MouseEvents;
065import com.vaadin.server.Resource;
066import com.vaadin.server.StreamResource;
067import com.vaadin.shared.MouseEventDetails.MouseButton;
068import com.vaadin.ui.Component;
069import com.vaadin.ui.Image;
070import com.vaadin.ui.themes.ValoTheme;
071import com.vaadin.v7.data.Item;
072import com.vaadin.v7.data.util.IndexedContainer;
073import com.vaadin.v7.data.util.filter.Or;
074import com.vaadin.v7.data.util.filter.SimpleStringFilter;
075import com.vaadin.v7.event.ItemClickEvent;
076import com.vaadin.v7.event.ItemClickEvent.ItemClickListener;
077import com.vaadin.v7.shared.ui.label.ContentMode;
078import com.vaadin.v7.ui.Label;
079import com.vaadin.v7.ui.Table;
080import com.vaadin.v7.ui.VerticalLayout;
081
082/**
083 *  Class to create Vaadin Table object with all available sites.<p>
084 */
085@SuppressWarnings("deprecation")
086public class CmsSitesTable extends Table implements I_CmsFilterableTable {
087
088    /**
089     * The edit project context menu entry.<p>
090     */
091    public class EditEntry
092    implements I_CmsSimpleContextMenuEntry<Set<String>>, I_CmsSimpleContextMenuEntry.I_HasCssStyles {
093
094        /**
095         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
096         */
097        public void executeAction(Set<String> data) {
098
099            String siteRoot = data.iterator().next();
100            m_manager.openEditDialog(siteRoot);
101        }
102
103        /**
104         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry.I_HasCssStyles#getStyles()
105         */
106        public String getStyles() {
107
108            return ValoTheme.LABEL_BOLD;
109        }
110
111        /**
112         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
113         */
114        public String getTitle(Locale locale) {
115
116            return CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_EDIT_0);
117        }
118
119        /**
120         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
121         */
122        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
123
124            if ((data == null) || (data.size() != 1) || (m_manager.getElement(data.iterator().next()) == null)) {
125                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
126            }
127
128            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
129        }
130    }
131
132    /**Table properties. */
133    protected enum TableProperty {
134
135        /**Status. */
136        Changed("", Boolean.class, new Boolean(false)),
137        /**Status. */
138        CmsSite("", CmsSite.class, null),
139        /**OU. */
140        Favicon("", Image.class, null),
141        /**Icon. */
142        Icon(null, Label.class, new Label(new CmsCssIcon(OpenCmsTheme.ICON_SITE).getHtml(), ContentMode.HTML)),
143        /**Last login. */
144        Is_Webserver("", Boolean.class, new Boolean(true)),
145        /**IsIndirect?. */
146        New("", Boolean.class, new Boolean(false)),
147        /**Is the user disabled? */
148        OK("", Boolean.class, new Boolean(true)),
149        /**Path. */
150        Path(Messages.GUI_SITE_PATH_0, String.class, ""),
151        /**Description. */
152        Server(Messages.GUI_SITE_SERVER_0, String.class, ""),
153        /**From Other ou?. */
154        SSL("", Integer.class, new Integer(1)),
155        /**Name. */
156        Title(Messages.GUI_SITE_TITLE_0, String.class, ""),
157        /**Is the user new? */
158        Under_Other_Site("", Boolean.class, new Boolean(false));
159
160        /**Default value for column.*/
161        private Object m_defaultValue;
162
163        /**Header Message key.*/
164        private String m_headerMessage;
165
166        /**Type of column property.*/
167        private Class<?> m_type;
168
169        /**
170         * constructor.<p>
171         *
172         * @param name Name
173         * @param type type
174         * @param defaultValue value
175         */
176        TableProperty(String name, Class<?> type, Object defaultValue) {
177
178            m_headerMessage = name;
179            m_type = type;
180            m_defaultValue = defaultValue;
181        }
182
183        /**
184         * The default value.<p>
185         *
186         * @return the default value object
187         */
188        Object getDefault() {
189
190            return m_defaultValue;
191        }
192
193        /**
194         * Gets the name of the property.<p>
195         *
196         * @return a name
197         */
198        String getName() {
199
200            if (!CmsStringUtil.isEmptyOrWhitespaceOnly(m_headerMessage)) {
201                return CmsVaadinUtils.getMessageText(m_headerMessage);
202            }
203            return "";
204        }
205
206        /**
207         * Gets the type of property.<p>
208         *
209         * @return the type
210         */
211        Class<?> getType() {
212
213            return m_type;
214        }
215
216    }
217
218    /**
219     * The delete project context menu entry.<p>
220     */
221    class DeleteEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
222
223        /**
224         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
225         */
226        public void executeAction(final Set<String> data) {
227
228            m_manager.openDeleteDialog(data);
229        }
230
231        /**
232         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
233         */
234        public String getTitle(Locale locale) {
235
236            return CmsVaadinUtils.getMessageText(Messages.GUI_PROJECTS_DELETE_0);
237        }
238
239        /**
240         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
241         */
242        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
243
244            if (m_manager.getElement(data.iterator().next()) == null) {
245                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
246            }
247            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
248        }
249    }
250
251    /**
252     * The menu entry to switch to the explorer of concerning site.<p>
253     */
254    class ExplorerEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
255
256        /**
257         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
258         */
259        public void executeAction(Set<String> data) {
260
261            String siteRoot = data.iterator().next();
262            A_CmsUI.getCmsObject().getRequestContext().setSiteRoot(siteRoot);
263            CmsAppWorkplaceUi.get().showApp(
264                CmsFileExplorerConfiguration.APP_ID,
265                A_CmsUI.getCmsObject().getRequestContext().getCurrentProject().getUuid()
266                    + A_CmsWorkplaceApp.PARAM_SEPARATOR
267                    + siteRoot
268                    + A_CmsWorkplaceApp.PARAM_SEPARATOR);
269        }
270
271        /**
272         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
273         */
274        public String getTitle(Locale locale) {
275
276            return Messages.get().getBundle(locale).key(Messages.GUI_EXPLORER_TITLE_0);
277        }
278
279        /**
280         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
281         */
282        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
283
284            if (data == null) {
285                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
286            }
287
288            if (data.size() > 1) {
289                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
290            }
291            try {
292                CmsObject cms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
293                cms.getRequestContext().setSiteRoot("");
294                if (cms.existsResource(data.iterator().next())) {
295                    return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
296                }
297            } catch (CmsException e) {
298                LOG.error("Unable to inti OpenCms Object", e);
299            }
300            return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
301
302        }
303
304    }
305
306    /**
307     * Column with FavIcon.<p>
308     */
309    class FavIconColumn implements Table.ColumnGenerator {
310
311        /**Serial version id.*/
312        private static final long serialVersionUID = -3772456970393398685L;
313
314        /**
315         * @see com.vaadin.v7.ui.Table.ColumnGenerator#generateCell(com.vaadin.v7.ui.Table, java.lang.Object, java.lang.Object)
316         */
317        public Object generateCell(Table source, Object itemId, Object columnId) {
318
319            return getImageFavIcon((String)itemId);
320        }
321    }
322
323    /**
324     * The menu entry to switch to the page editor of concerning site.<p>
325     */
326    class PageEditorEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
327
328        /**
329         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
330         */
331        public void executeAction(Set<String> data) {
332
333            String siteRoot = data.iterator().next();
334            A_CmsUI.get().changeSite(siteRoot);
335
336            CmsPageEditorConfiguration pageeditorApp = new CmsPageEditorConfiguration();
337            pageeditorApp.getAppLaunchCommand().run();
338
339        }
340
341        /**
342         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
343         */
344        public String getTitle(Locale locale) {
345
346            return CmsVaadinUtils.getMessageText(Messages.GUI_PAGEEDITOR_TITLE_0);
347        }
348
349        /**
350         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
351         */
352        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
353
354            if (data == null) {
355                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
356            }
357
358            if (data.size() > 1) {
359                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
360            }
361            String siteRoot = data.iterator().next();
362            if (m_manager.getElement(siteRoot) == null) {
363                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
364            }
365            if (!((Boolean)getItem(siteRoot).getItemProperty(TableProperty.OK).getValue()).booleanValue()) {
366                return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
367            }
368
369            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
370        }
371
372    }
373
374    /**
375     * The menu entry to switch to the sitemap editor of concerning site.<p>
376     */
377    class SitemapEntry implements I_CmsSimpleContextMenuEntry<Set<String>> {
378
379        /**
380         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
381         */
382        public void executeAction(Set<String> data) {
383
384            String siteRoot = data.iterator().next();
385            A_CmsUI.get().changeSite(siteRoot);
386
387            CmsSitemapEditorConfiguration sitemapApp = new CmsSitemapEditorConfiguration();
388            sitemapApp.getAppLaunchCommand().run();
389        }
390
391        /**
392         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
393         */
394        public String getTitle(Locale locale) {
395
396            return CmsVaadinUtils.getMessageText(Messages.GUI_SITEMAP_TITLE_0);
397        }
398
399        /**
400         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
401         */
402        public CmsMenuItemVisibilityMode getVisibility(Set<String> data) {
403
404            if ((data == null) || (data.size() != 1)) {
405                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
406            }
407            String siteRoot = data.iterator().next();
408            if (m_manager.getElement(siteRoot) == null) {
409                return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
410            }
411            return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
412        }
413
414    }
415
416    /** The logger for this class. */
417    protected static Log LOG = CmsLog.getLog(CmsSitesTable.class.getName());
418
419    /**vaadin serial id.*/
420    private static final long serialVersionUID = 4655464609332605219L;
421
422    /** The project manager instance. */
423    public CmsSiteManager m_manager;
424
425    /** The available menu entries. */
426    protected List<I_CmsSimpleContextMenuEntry<Set<String>>> m_menuEntries;
427
428    /** The data container. */
429    private IndexedContainer m_container;
430
431    /** The context menu. */
432    private CmsContextMenu m_menu;
433
434    /**Counter for valid sites.*/
435    private int m_siteCounter;
436
437    /**
438     * Constructor.<p>
439     *
440     * @param manager the project manager
441     */
442    public CmsSitesTable(CmsSiteManager manager) {
443
444        m_manager = manager;
445
446        m_container = new IndexedContainer();
447        for (TableProperty prop : TableProperty.values()) {
448            m_container.addContainerProperty(prop, prop.getType(), prop.getDefault());
449            setColumnHeader(prop, prop.getName());
450        }
451
452        setContainerDataSource(m_container);
453
454        setColumnAlignment(TableProperty.Favicon, Align.CENTER);
455        setColumnExpandRatio(TableProperty.Server, 2);
456        setColumnExpandRatio(TableProperty.Title, 2);
457        setColumnExpandRatio(TableProperty.Path, 2);
458        setColumnWidth(TableProperty.Favicon, 40);
459        setColumnWidth(TableProperty.SSL, 130);
460
461        setSelectable(true);
462        setMultiSelect(true);
463        m_menu = new CmsContextMenu();
464        m_menu.setAsTableContextMenu(this);
465        addItemClickListener(new ItemClickListener() {
466
467            private static final long serialVersionUID = 1L;
468
469            public void itemClick(ItemClickEvent event) {
470
471                onItemClick(event, event.getItemId(), event.getPropertyId());
472            }
473        });
474        setCellStyleGenerator(new CellStyleGenerator() {
475
476            private static final long serialVersionUID = 1L;
477
478            public String getStyle(Table source, Object itemId, Object propertyId) {
479
480                String styles = "";
481
482                if (TableProperty.SSL.equals(propertyId)) {
483                    styles += " "
484                        + getSSLStyle(
485                            (CmsSite)source.getItem(itemId).getItemProperty(TableProperty.CmsSite).getValue());
486                }
487
488                if (TableProperty.Server.equals(propertyId)) {
489                    styles += " " + OpenCmsTheme.HOVER_COLUMN;
490                    if (!((Boolean)source.getItem(itemId).getItemProperty(
491                        TableProperty.OK).getValue()).booleanValue()) {
492                        if (((Boolean)source.getItem(itemId).getItemProperty(
493                            TableProperty.Changed).getValue()).booleanValue()) {
494                            styles += " " + OpenCmsTheme.STATE_CHANGED;
495                        } else {
496                            styles += " " + OpenCmsTheme.EXPIRED;
497                        }
498                    } else {
499                        if (((Boolean)source.getItem(itemId).getItemProperty(
500                            TableProperty.New).getValue()).booleanValue()) {
501                            styles += " " + OpenCmsTheme.STATE_NEW;
502                        }
503                    }
504                }
505                if (TableProperty.Title.equals(propertyId)
506                    & ((Boolean)source.getItem(itemId).getItemProperty(
507                        TableProperty.Is_Webserver).getValue()).booleanValue()) {
508                    styles += " " + OpenCmsTheme.IN_NAVIGATION;
509                }
510                if (styles.isEmpty()) {
511                    return null;
512                }
513
514                return styles;
515            }
516        });
517
518        addGeneratedColumn(TableProperty.SSL, new ColumnGenerator() {
519
520            private static final long serialVersionUID = -2144476865774782965L;
521
522            public Object generateCell(Table source, Object itemId, Object columnId) {
523
524                return getSSLStatus((CmsSite)source.getItem(itemId).getItemProperty(TableProperty.CmsSite).getValue());
525
526            }
527
528        });
529        addGeneratedColumn(TableProperty.Favicon, new FavIconColumn());
530
531        setItemDescriptionGenerator(new ItemDescriptionGenerator() {
532
533            private static final long serialVersionUID = 7367011213487089661L;
534
535            public String generateDescription(Component source, Object itemId, Object propertyId) {
536
537                if (TableProperty.Favicon.equals(propertyId)) {
538
539                    return ((CmsSite)(((Table)source).getItem(itemId).getItemProperty(
540                        TableProperty.CmsSite).getValue())).getSSLMode().getLocalizedMessage();
541                }
542                return null;
543            }
544        });
545
546        setColumnCollapsingAllowed(false);
547
548        setVisibleColumns(
549            TableProperty.Icon,
550            TableProperty.SSL,
551            TableProperty.Favicon,
552            TableProperty.Server,
553            TableProperty.Title,
554            TableProperty.Path);
555
556        setColumnWidth(TableProperty.Icon, 40);
557    }
558
559    /**
560     * Gets the style for ssl badget.<p>
561     *
562     * @param site to get style for
563     * @return style string
564     */
565    public static String getSSLStyle(CmsSite site) {
566
567        if ((site != null) && site.getSSLMode().isSecure()) {
568            return OpenCmsTheme.TABLE_COLUMN_BOX_CYAN;
569        }
570        return OpenCmsTheme.TABLE_COLUMN_BOX_GRAY;
571    }
572
573    /**
574     * @see org.opencms.ui.apps.user.I_CmsFilterableTable#filter(java.lang.String)
575     */
576    @SuppressWarnings("unchecked")
577    public void filter(String search) {
578
579        m_container.removeAllContainerFilters();
580        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(search)) {
581            m_container.addContainerFilter(
582                new Or(
583                    new SimpleStringFilter(TableProperty.Title, search, true, false),
584                    new SimpleStringFilter(TableProperty.Path, search, true, false),
585                    new SimpleStringFilter(TableProperty.Server, search, true, false)));
586        }
587        if ((getValue() != null) & !((Set<String>)getValue()).isEmpty()) {
588            setCurrentPageFirstItemId(((Set<String>)getValue()).iterator().next());
589        }
590
591    }
592
593    /**
594     * Get the container.<p>
595     *
596     * @return IndexedContainer
597     */
598    public IndexedContainer getContainer() {
599
600        return m_container;
601    }
602
603    /**
604     * @see org.opencms.ui.apps.user.I_CmsFilterableTable#getEmptyLayout()
605     */
606    public VerticalLayout getEmptyLayout() {
607
608        return null;
609    }
610
611    /**
612     * Returns the available menu entries.<p>
613     *
614     * @return the menu entries
615     */
616    public List<I_CmsSimpleContextMenuEntry<Set<String>>> getMenuEntries() {
617
618        if (m_menuEntries == null) {
619            m_menuEntries = new ArrayList<I_CmsSimpleContextMenuEntry<Set<String>>>();
620            m_menuEntries.add(new EditEntry());
621            m_menuEntries.add(new DeleteEntry());
622            m_menuEntries.add(new ExplorerEntry());
623            m_menuEntries.add(new PageEditorEntry());
624        }
625        return m_menuEntries;
626    }
627
628    /**
629     * Returns number of correctly configured sites.<p>
630     *
631     * @return number of sites
632     */
633    public int getSitesCount() {
634
635        return m_siteCounter;
636    }
637
638    /**
639     *  Reads sites from Site Manager and adds them to table.<p>
640     */
641    public void loadSites() {
642
643        m_container.removeAllItems();
644        List<CmsSite> sites = m_manager.getAllElements();
645        m_siteCounter = 0;
646        CmsCssIcon icon = new CmsCssIcon(OpenCmsTheme.ICON_SITE);
647        icon.setOverlay(OpenCmsTheme.STATE_CHANGED + " " + CmsResourceIcon.ICON_CLASS_CHANGED);
648        for (CmsSite site : sites) {
649            if (site.getSiteMatcher() != null) {
650                m_siteCounter++;
651                Item item = m_container.addItem(site.getSiteRoot());
652                item.getItemProperty(TableProperty.CmsSite).setValue(site);
653                item.getItemProperty(TableProperty.Server).setValue(site.getUrl());
654                item.getItemProperty(TableProperty.Title).setValue(site.getTitle());
655                item.getItemProperty(TableProperty.Is_Webserver).setValue(new Boolean(site.isWebserver()));
656                item.getItemProperty(TableProperty.Path).setValue(site.getSiteRoot());
657                if (OpenCms.getSiteManager().isOnlyOfflineSite(site)) {
658                    item.getItemProperty(TableProperty.New).setValue(new Boolean(true));
659                    item.getItemProperty(TableProperty.Icon).setValue(
660                        new Label(icon.getHtmlWithOverlay(), ContentMode.HTML));
661                } else {
662                    item.getItemProperty(TableProperty.Icon).setValue(new Label(icon.getHtml(), ContentMode.HTML));
663                }
664                item.getItemProperty(TableProperty.OK).setValue(isNotNestedSite(site, sites));
665            }
666        }
667
668        for (CmsSite site : m_manager.getCorruptedSites()) {
669
670            Item item = m_container.addItem(site.getSiteRoot());
671
672            //Make sure item doesn't exist in table yet.. should never happen
673            if (item != null) {
674                item.getItemProperty(TableProperty.CmsSite).setValue(site);
675                item.getItemProperty(TableProperty.Icon).setValue(new Label(icon.getHtml(), ContentMode.HTML));
676                item.getItemProperty(TableProperty.Server).setValue(site.getUrl());
677                item.getItemProperty(TableProperty.Title).setValue(site.getTitle());
678                item.getItemProperty(TableProperty.Is_Webserver).setValue(new Boolean(site.isWebserver()));
679                item.getItemProperty(TableProperty.Path).setValue(site.getSiteRoot());
680                item.getItemProperty(TableProperty.OK).setValue(new Boolean(false));
681                if (!site.getSiteRootUUID().isNullUUID()) {
682                    if (m_manager.getRootCmsObject().existsResource(site.getSiteRootUUID())) {
683                        item.getItemProperty(TableProperty.Changed).setValue(new Boolean(true));
684                        item.getItemProperty(TableProperty.Icon).setValue(
685                            new Label(icon.getHtmlWithOverlay(), ContentMode.HTML));
686                    }
687                }
688            }
689        }
690    }
691
692    /**
693     * Sets the menu entries.<p>
694     *
695     * @param newEntries to be set
696     */
697    public void setMenuEntries(List<I_CmsSimpleContextMenuEntry<Set<String>>> newEntries) {
698
699        m_menuEntries = newEntries;
700    }
701
702    /**
703     * Get the ssl status label.<p>
704     *
705     * @param site to get ssl status for
706     * @return Label for status
707     */
708    protected String getSSLStatus(CmsSite site) {
709
710        if ((site != null) && site.getSSLMode().isSecure()) {
711            return CmsVaadinUtils.getMessageText(Messages.GUI_SITE_ENCRYPTED_0);
712        }
713        return CmsVaadinUtils.getMessageText(Messages.GUI_SITE_UNENCRYPTED_0);
714    }
715
716    /**
717     * Returns an favicon image with click listener on right clicks.<p>
718     *
719     * @param itemId of row to put image in.
720     * @return Vaadin Image.
721     */
722    Image getImageFavIcon(final String itemId) {
723
724        Resource resource = getFavIconResource(itemId);
725
726        if (resource != null) {
727
728            Image favIconImage = new Image("", resource);
729            favIconImage.setWidth("24px");
730            favIconImage.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_SITE_FAVICON_0));
731
732            favIconImage.addClickListener(new MouseEvents.ClickListener() {
733
734                private static final long serialVersionUID = 5954790734673665522L;
735
736                public void click(com.vaadin.event.MouseEvents.ClickEvent event) {
737
738                    onItemClick(event, itemId, TableProperty.Favicon);
739
740                }
741            });
742
743            return favIconImage;
744        } else {
745            return null;
746        }
747    }
748
749    /**
750     * Handles the table item clicks, including clicks on images inside of a table item.<p>
751     *
752     * @param event the click event
753     * @param itemId of the clicked row
754     * @param propertyId column id
755     */
756    @SuppressWarnings("unchecked")
757    void onItemClick(MouseEvents.ClickEvent event, Object itemId, Object propertyId) {
758
759        if (!event.isCtrlKey() && !event.isShiftKey()) {
760
761            changeValueIfNotMultiSelect(itemId);
762
763            // don't interfere with multi-selection using control key
764            if (event.getButton().equals(MouseButton.RIGHT) || (propertyId == TableProperty.Icon)) {
765
766                m_menu.setEntries(getMenuEntries(), (Set<String>)getValue());
767                m_menu.openForTable(event, itemId, propertyId, this);
768            } else if (event.getButton().equals(MouseButton.LEFT) && TableProperty.Server.equals(propertyId)) {
769                String siteRoot = (String)itemId;
770                m_manager.defaultAction(siteRoot);
771            }
772        }
773    }
774
775    /**
776     * Checks value of table and sets it new if needed:<p>
777     * if multiselect: new itemId is in current Value? -> no change of value<p>
778     * no multiselect and multiselect, but new item not selected before: set value to new item<p>
779     *
780     * @param itemId if of clicked item
781     */
782    private void changeValueIfNotMultiSelect(Object itemId) {
783
784        @SuppressWarnings("unchecked")
785        Set<String> value = (Set<String>)getValue();
786        if (value == null) {
787            select(itemId);
788        } else if (!value.contains(itemId)) {
789            setValue(null);
790            select(itemId);
791        }
792    }
793
794    /**
795     * Loads the FavIcon of a given site.<p>
796     *
797     * @param siteRoot of the given site.
798     * @return the favicon as resource or default image if no faicon was found.
799     */
800    private Resource getFavIconResource(String siteRoot) {
801
802        try {
803            CmsResource favicon = m_manager.getRootCmsObject().readResource(siteRoot + "/" + CmsSiteManager.FAVICON);
804            CmsFile faviconFile = m_manager.getRootCmsObject().readFile(favicon);
805            final byte[] imageData = faviconFile.getContents();
806            return new StreamResource(new StreamResource.StreamSource() {
807
808                private static final long serialVersionUID = -8868657402793427460L;
809
810                public InputStream getStream() {
811
812                    return new ByteArrayInputStream(imageData);
813
814                }
815            }, "");
816        } catch (CmsException e) {
817            return null;
818        }
819    }
820
821    /**
822     * Is the given site NOT nested in any of the given sites?<p>
823     *
824     * @param site to check
825     * @param sites to check
826     *
827     * @return TRUE if the site is NOT nested
828     */
829    private Boolean isNotNestedSite(CmsSite site, List<CmsSite> sites) {
830
831        for (CmsSite s : sites) {
832            if ((site.getSiteRoot().length() > s.getSiteRoot().length())
833                & site.getSiteRoot().startsWith(CmsFileUtil.addTrailingSeparator(s.getSiteRoot()))) {
834                return Boolean.FALSE;
835            }
836        }
837        return Boolean.TRUE;
838    }
839}