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