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