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