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.user;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.main.CmsException;
033import org.opencms.main.CmsLog;
034import org.opencms.main.OpenCms;
035import org.opencms.security.CmsOrganizationalUnit;
036import org.opencms.security.CmsRole;
037import org.opencms.security.CmsRoleViolationException;
038import org.opencms.ui.A_CmsUI;
039import org.opencms.ui.CmsCssIcon;
040import org.opencms.ui.CmsVaadinUtils;
041import org.opencms.ui.apps.Messages;
042import org.opencms.ui.components.CmsBasicDialog;
043import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
044import org.opencms.ui.components.OpenCmsTheme;
045import org.opencms.ui.contextmenu.CmsContextMenu;
046import org.opencms.ui.contextmenu.CmsMenuItemVisibilityMode;
047import org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry;
048import org.opencms.util.CmsStringUtil;
049
050import java.util.ArrayList;
051import java.util.Collections;
052import java.util.List;
053import java.util.Locale;
054import java.util.Set;
055
056import org.apache.commons.logging.Log;
057
058import com.vaadin.server.Resource;
059import com.vaadin.shared.MouseEventDetails.MouseButton;
060import com.vaadin.ui.Window;
061import com.vaadin.ui.themes.ValoTheme;
062import com.vaadin.v7.data.Item;
063import com.vaadin.v7.data.util.IndexedContainer;
064import com.vaadin.v7.data.util.filter.Or;
065import com.vaadin.v7.data.util.filter.SimpleStringFilter;
066import com.vaadin.v7.event.ItemClickEvent;
067import com.vaadin.v7.event.ItemClickEvent.ItemClickListener;
068import com.vaadin.v7.ui.Table;
069import com.vaadin.v7.ui.VerticalLayout;
070
071/**
072 * Class to show ous in table for account management.<p>
073 */
074public class CmsOUTable extends Table implements I_CmsFilterableTable {
075
076    /**
077     * Menu Entry for Delete option.<p>
078     */
079    class EntryDelete implements I_CmsSimpleContextMenuEntry<Set<String>> {
080
081        /**
082         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
083         */
084        public void executeAction(final Set<String> context) {
085
086            Window window = CmsBasicDialog.prepareWindow();
087            CmsDeleteOUDialog dialog = new CmsDeleteOUDialog(m_cms, context.iterator().next(), window, m_app);
088            window.setContent(dialog);
089            window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OU_DELETE_0));
090            A_CmsUI.get().addWindow(window);
091        }
092
093        /**
094         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
095         */
096        public String getTitle(Locale locale) {
097
098            return CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OU_DELETE_0);
099        }
100
101        /**
102         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
103         */
104        public CmsMenuItemVisibilityMode getVisibility(Set<String> context) {
105
106            if (getItem(context.iterator().next()).getItemProperty(TableProperty.Type).getValue().equals(
107                CmsOuTreeType.OU)) {
108                if (isAdmin()) {
109                    return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
110                }
111                return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
112            }
113
114            return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
115
116        }
117    }
118
119    /**
120     * Edit menu entry.<p>
121     */
122    class EntryEdit implements I_CmsSimpleContextMenuEntry<Set<String>> {
123
124        /**
125         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
126         */
127        public void executeAction(Set<String> context) {
128
129            Window window = CmsBasicDialog.prepareWindow();
130            window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OU_EDIT_WINDOW_CAPTION_0));
131            window.setContent(new CmsOUEditDialog(m_cms, context.iterator().next(), window, m_app));
132
133            A_CmsUI.get().addWindow(window);
134        }
135
136        /**
137         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
138         */
139        public String getTitle(Locale locale) {
140
141            return CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OU_EDIT_0);
142        }
143
144        /**
145         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
146         */
147        public CmsMenuItemVisibilityMode getVisibility(Set<String> context) {
148
149            if (getItem(context.iterator().next()).getItemProperty(TableProperty.Type).getValue().equals(
150                CmsOuTreeType.OU)) {
151                if (isAdmin()) {
152                    return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
153                }
154                return CmsMenuItemVisibilityMode.VISIBILITY_INACTIVE;
155            }
156
157            return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
158
159        }
160
161    }
162
163    /**
164     * Entry for new user in the context menu.<p>
165     */
166    class EntryImportExportUser implements I_CmsSimpleContextMenuEntry<Set<String>> {
167
168        /**
169         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
170         */
171        public void executeAction(Set<String> context) {
172
173            boolean includeTechnicalFields = false;
174            try {
175                OpenCms.getRoleManager().checkRole(m_cms, CmsRole.ADMINISTRATOR);
176                includeTechnicalFields = true;
177            } catch (CmsRoleViolationException e) {
178                // ok
179            }
180            Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide);
181            window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_USER_IMEXPORT_DIALOGNAME_0));
182            window.setContent(
183                CmsImportExportUserDialog.getExportUserDialogForOU(
184                    context.iterator().next(),
185                    window,
186                    includeTechnicalFields));
187
188            A_CmsUI.get().addWindow(window);
189        }
190
191        /**
192         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
193         */
194        public String getTitle(Locale locale) {
195
196            return CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_USER_IMEXPORT_CONTEXTMENUNAME_0);
197        }
198
199        /**
200         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
201         */
202        public CmsMenuItemVisibilityMode getVisibility(Set<String> context) {
203
204            if (getItem(context.iterator().next()).getItemProperty(TableProperty.Type).getValue().equals(
205                CmsOuTreeType.OU)) {
206                return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
207            }
208            return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
209        }
210
211    }
212
213    /**
214     * New ou menu entry.<p>
215     */
216    class EntryNewGroup implements I_CmsSimpleContextMenuEntry<Set<String>> {
217
218        /**
219         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
220         */
221        public void executeAction(Set<String> context) {
222
223            Window window = CmsBasicDialog.prepareWindow();
224            window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ADD_GROUP_0));
225            window.setContent(new CmsGroupEditDialog(m_cms, window, m_parentOu, m_app));
226
227            A_CmsUI.get().addWindow(window);
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_USERMANAGEMENT_ADD_GROUP_0);
236        }
237
238        /**
239         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
240         */
241        public CmsMenuItemVisibilityMode getVisibility(Set<String> context) {
242
243            Object typeObj = getItem(context.iterator().next()).getItemProperty(TableProperty.Type).getValue();
244            if (((I_CmsOuTreeType)typeObj).isGroup()) {
245                return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
246
247            }
248            return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
249        }
250
251    }
252
253    /**
254     * Entry for new user in the context menu.<p>
255     */
256    class EntryNewUser implements I_CmsSimpleContextMenuEntry<Set<String>> {
257
258        /**
259         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
260         */
261        public void executeAction(Set<String> context) {
262
263            Window window = CmsBasicDialog.prepareWindow();
264            window.setCaption(CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ADD_USER_0));
265            window.setContent(new CmsUserEditDialog(m_cms, window, m_parentOu, m_app));
266
267            A_CmsUI.get().addWindow(window);
268        }
269
270        /**
271         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
272         */
273        public String getTitle(Locale locale) {
274
275            return CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_ADD_USER_0);
276        }
277
278        /**
279         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
280         */
281        public CmsMenuItemVisibilityMode getVisibility(Set<String> context) {
282
283            Object typeObj = getItem(context.iterator().next()).getItemProperty(TableProperty.Type).getValue();
284            if (((I_CmsOuTreeType)typeObj).isUser()) {
285                return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
286            }
287            return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
288        }
289
290    }
291
292    /**
293     * Entry to open item in context menu.<p>
294     */
295    class EntryOpen implements I_CmsSimpleContextMenuEntry<Set<String>>, I_CmsSimpleContextMenuEntry.I_HasCssStyles {
296
297        /**
298         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#executeAction(java.lang.Object)
299         */
300        public void executeAction(Set<String> context) {
301
302            String itemId = context.iterator().next();
303            updateApp(itemId);
304
305        }
306
307        /**
308         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry.I_HasCssStyles#getStyles()
309         */
310        public String getStyles() {
311
312            return ValoTheme.LABEL_BOLD;
313        }
314
315        /**
316         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getTitle(java.util.Locale)
317         */
318        public String getTitle(Locale locale) {
319
320            return CmsVaadinUtils.getMessageText(Messages.GUI_USERMANAGEMENT_OPEN_0);
321        }
322
323        /**
324         * @see org.opencms.ui.contextmenu.I_CmsSimpleContextMenuEntry#getVisibility(java.lang.Object)
325         */
326        public CmsMenuItemVisibilityMode getVisibility(Set<String> context) {
327
328            if (m_app != null) {
329                return CmsMenuItemVisibilityMode.VISIBILITY_ACTIVE;
330            } else {
331                return CmsMenuItemVisibilityMode.VISIBILITY_INVISIBLE;
332            }
333        }
334
335    }
336
337    /**
338     * Table properties.<p>
339     */
340    enum TableProperty {
341        /** Description property.*/
342        Description(Messages.GUI_USERMANAGEMENT_OU_DESCRIPTION_0, String.class, ""),
343        /**Icon property. */
344        Icon(null, Resource.class, new CmsCssIcon(OpenCmsTheme.ICON_OU)),
345        /** Name property. */
346        Name(Messages.GUI_USERMANAGEMENT_OU_NAME_0, String.class, ""),
347        /** Resources property.*/
348        Ressources(Messages.GUI_USERMANAGEMENT_OU_EDIT_PANEL2_0, String.class, ""),
349        /** Type property. */
350        Type(null, I_CmsOuTreeType.class, CmsOuTreeType.OU);
351
352        /**Default value for column.*/
353        private Object m_defaultValue;
354
355        /**Header Message key.*/
356        private String m_headerMessage;
357
358        /**Type of column property.*/
359        private Class<?> m_type;
360
361        /**
362         * constructor.<p>
363         *
364         * @param name Name
365         * @param type type
366         * @param defaultValue value
367         */
368        TableProperty(String name, Class<?> type, Object defaultValue) {
369
370            m_headerMessage = name;
371            m_type = type;
372            m_defaultValue = defaultValue;
373        }
374
375        /**
376         * The default value.<p>
377         *
378         * @return the default value object
379         */
380        Object getDefault() {
381
382            return m_defaultValue;
383        }
384
385        /**
386         * Gets the name of the property.<p>
387         *
388         * @return a name
389         */
390        String getName() {
391
392            return m_headerMessage == null ? "" : CmsVaadinUtils.getMessageText(m_headerMessage);
393
394        }
395
396        /**
397         * Gets the type of property.<p>
398         *
399         * @return the type
400         */
401        Class<?> getType() {
402
403            return m_type;
404        }
405
406    }
407
408    /** Log instance for this class. */
409    static final Log LOG = CmsLog.getLog(CmsOUTable.class);
410
411    /**vaadin serial id. */
412    private static final long serialVersionUID = -1080519790145391678L;
413
414    /**Calling app. */
415    protected CmsAccountsApp m_app;
416
417    /**Parent ou. */
418    protected String m_parentOu;
419
420    /**CmsObject. */
421    CmsObject m_cms;
422
423    /** The context menu. */
424    CmsContextMenu m_menu;
425
426    /**Indexed container. */
427    private IndexedContainer m_container;
428
429    /** The available menu entries. */
430    private List<I_CmsSimpleContextMenuEntry<Set<String>>> m_menuEntries;
431
432    /**
433     * public constructor.<p>
434     *
435     * @param ou ou
436     * @param app calling app
437     */
438    public CmsOUTable(String ou, CmsAccountsApp app) {
439
440        m_app = app;
441        init(ou);
442    }
443
444    /**
445     * @see org.opencms.ui.apps.user.I_CmsFilterableTable#filter(java.lang.String)
446     */
447    public void filter(String data) {
448
449        m_container.removeAllContainerFilters();
450        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(data)) {
451            m_container.addContainerFilter(
452                new Or(
453                    new SimpleStringFilter(TableProperty.Name, data, true, false),
454                    new SimpleStringFilter(TableProperty.Description, data, true, false)));
455        }
456
457    }
458
459    /**
460     * @see org.opencms.ui.apps.user.I_CmsFilterableTable#getEmptyLayout()
461     */
462    public VerticalLayout getEmptyLayout() {
463
464        VerticalLayout layout = new VerticalLayout();
465        layout.setVisible(false);
466        return layout;
467    }
468
469    /**
470     * Checks if user has role to edit ou.<p>
471     *
472     * @return true if admin
473     */
474    protected boolean isAdmin() {
475
476        return OpenCms.getRoleManager().hasRole(m_cms, CmsRole.ADMINISTRATOR.forOrgUnit(m_parentOu));
477    }
478
479    /**
480     * Updates app.<p>
481     *
482     * @param itemId of current item
483     */
484    protected void updateApp(String itemId) {
485
486        I_CmsOuTreeType foundType = null;
487        for (I_CmsOuTreeType type : m_app.getTreeTypeProvider().getTreeTypes()) {
488            if (itemId.equals(type.getId())) {
489                foundType = type;
490                break;
491            }
492        }
493        if (foundType != null) {
494            m_app.update(m_parentOu, foundType, null);
495            return;
496        }
497        m_app.update(itemId, CmsOuTreeType.OU, null, "");
498    }
499
500    /**
501     * Returns the available menu entries.<p>
502     *
503     * @return the menu entries
504     */
505    List<I_CmsSimpleContextMenuEntry<Set<String>>> getMenuEntries() {
506
507        if (m_menuEntries == null) {
508            m_menuEntries = new ArrayList<I_CmsSimpleContextMenuEntry<Set<String>>>();
509            m_menuEntries.add(new EntryOpen());
510            m_menuEntries.add(new EntryEdit());
511            m_menuEntries.add(new EntryNewGroup());
512            m_menuEntries.add(new EntryNewUser());
513            m_menuEntries.add(new EntryImportExportUser());
514            m_menuEntries.add(new EntryDelete());
515        }
516        return m_menuEntries;
517    }
518
519    /**
520     * Adds ou to table.<p>
521     *
522     * @param ou to be added
523     */
524    private void addOuToTable(CmsOrganizationalUnit ou) {
525
526        if (m_app.isParentOfManagableOU(ou.getName())) {
527            Item item = m_container.addItem(ou.getName());
528            if (item != null) {
529                item.getItemProperty(TableProperty.Name).setValue(ou.getName());
530                item.getItemProperty(TableProperty.Description).setValue(ou.getDisplayName(A_CmsUI.get().getLocale()));
531                if (ou.hasFlagWebuser()) {
532                    item.getItemProperty(TableProperty.Icon).setValue(new CmsCssIcon(OpenCmsTheme.ICON_OU_WEB));
533                }
534            }
535        }
536    }
537
538    /**
539     * initializes table.<p>
540     *
541     * @param parentOu ou name
542     */
543    private void init(String parentOu) {
544
545        m_parentOu = parentOu;
546        m_menu = new CmsContextMenu();
547        m_menu.setAsTableContextMenu(this);
548
549        m_container = new IndexedContainer();
550
551        setContainerDataSource(m_container);
552
553        for (TableProperty prop : TableProperty.values()) {
554            m_container.addContainerProperty(prop, prop.getType(), prop.getDefault());
555            setColumnHeader(prop, prop.getName());
556        }
557        setContainerDataSource(m_container);
558        setItemIconPropertyId(TableProperty.Icon);
559        setRowHeaderMode(RowHeaderMode.ICON_ONLY);
560
561        setColumnWidth(null, 40);
562        setSelectable(true);
563
564        addGeneratedColumn(TableProperty.Ressources, new ColumnGenerator() {
565
566            private static final long serialVersionUID = 4624734503799549261L;
567
568            public Object generateCell(Table source, Object itemId, Object columnId) {
569
570                String out = "";
571                try {
572                    boolean isOu = true;
573                    for (I_CmsOuTreeType type : m_app.getTreeTypeProvider().getTreeTypes()) {
574                        if (type.getId().equals(itemId)) {
575                            isOu = false;
576                        }
577                    }
578                    if (isOu) {
579                        List<CmsResource> resources = OpenCms.getOrgUnitManager().getResourcesForOrganizationalUnit(
580                            m_cms,
581                            (String)itemId);
582                        if (!resources.isEmpty()) {
583                            out = resources.get(0).getRootPath();
584                            int i = 1;
585                            while ((resources.size() > i) & (out.length() < 50)) {
586                                out += ", " + resources.get(i).getRootPath();
587                            }
588                            if (resources.size() > i) {
589                                out += " ...";
590                            }
591                        }
592                    }
593                } catch (CmsException e) {
594                    LOG.error("unable to read resources.", e);
595                }
596                return out;
597            }
598        });
599
600        setVisibleColumns(TableProperty.Name, TableProperty.Description, TableProperty.Ressources);
601
602        try {
603            m_cms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
604            m_cms.getRequestContext().setSiteRoot("");
605        } catch (CmsException e) {
606            m_cms = A_CmsUI.getCmsObject();
607        }
608        try {
609            if (m_app.isOUManagable(m_parentOu)) {
610
611                for (I_CmsOuTreeType treeType : m_app.getTreeTypeProvider().getTreeTypes()) {
612                    if (treeType.showInOuTable() && treeType.isValidForOu(m_cms, m_parentOu)) {
613                        Item item = m_container.addItem(treeType.getId());
614                        item.getItemProperty(TableProperty.Name).setValue(treeType.getName());
615                        item.getItemProperty(TableProperty.Icon).setValue(treeType.getIcon());
616                        item.getItemProperty(TableProperty.Type).setValue(treeType);
617                    }
618                }
619            }
620            List<CmsOrganizationalUnit> webOus = new ArrayList<CmsOrganizationalUnit>();
621            for (CmsOrganizationalUnit ou : OpenCms.getOrgUnitManager().getOrganizationalUnits(
622                m_cms,
623                parentOu,
624                false)) {
625
626                if (ou.hasFlagWebuser()) {
627                    webOus.add(ou);
628                } else {
629                    addOuToTable(ou);
630                }
631            }
632            for (CmsOrganizationalUnit ou : webOus) {
633                addOuToTable(ou);
634            }
635        } catch (CmsException e) {
636            LOG.error("Unable to read ous", e);
637        }
638
639        addItemClickListener(new ItemClickListener() {
640
641            private static final long serialVersionUID = 4807195510202231174L;
642
643            public void itemClick(ItemClickEvent event) {
644
645                setValue(null);
646                select(event.getItemId());
647                if (event.getButton().equals(MouseButton.RIGHT) || (event.getPropertyId() == null)) {
648                    m_menu.setEntries(getMenuEntries(), Collections.singleton((String)getValue()));
649                    m_menu.openForTable(event, event.getItemId(), event.getPropertyId(), CmsOUTable.this);
650                    return;
651                }
652                if (event.getButton().equals(MouseButton.LEFT) && event.getPropertyId().equals(TableProperty.Name)) {
653                    updateApp((String)getValue());
654                }
655
656            }
657
658        });
659        setCellStyleGenerator(new CellStyleGenerator() {
660
661            private static final long serialVersionUID = 1L;
662
663            public String getStyle(Table source, Object itemId, Object propertyId) {
664
665                if (TableProperty.Name.equals(propertyId)) {
666                    return " " + OpenCmsTheme.HOVER_COLUMN;
667                }
668
669                return "";
670            }
671        });
672    }
673}