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.components.categoryselect;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsResource;
032import org.opencms.main.CmsException;
033import org.opencms.main.OpenCms;
034import org.opencms.relations.CmsCategory;
035import org.opencms.relations.CmsCategoryService;
036import org.opencms.util.CmsStringUtil;
037
038import java.util.Collection;
039import java.util.HashMap;
040import java.util.HashSet;
041import java.util.List;
042import java.util.Locale;
043import java.util.Map;
044import java.util.Map.Entry;
045import java.util.Set;
046
047import com.vaadin.v7.data.util.HierarchicalContainer;
048import com.vaadin.v7.ui.CheckBox;
049import com.vaadin.v7.ui.Table;
050import com.vaadin.v7.ui.TreeTable;
051
052/**
053 * The category tree.<p>
054 */
055public class CmsCategoryTree extends TreeTable {
056
057    /** The checkbox column. */
058    private static final String CHECKBOX = "checkbox";
059
060    /** The path column. */
061    private static final String PATH = "path";
062
063    /** The serial version id. */
064    private static final long serialVersionUID = 8046665824980274707L;
065
066    /** The title column. */
067    private static final String TITLE = "title";
068
069    /** The check box map by category. */
070    Map<CmsCategory, CheckBox> m_checkboxes;
071
072    /** The data source container. */
073    private HierarchicalContainer m_container;
074
075    /** In case the display mode is set. */
076    private boolean m_isDiplayOny;
077
078    /**
079     * Constructor.<p>
080     */
081    public CmsCategoryTree() {
082        m_checkboxes = new HashMap<CmsCategory, CheckBox>();
083        m_container = new HierarchicalContainer();
084        setContainerDataSource(m_container);
085        ColumnGenerator captionGenerator = new ColumnGenerator() {
086
087            private static final long serialVersionUID = 1L;
088
089            public Object generateCell(Table source, Object itemId, Object columnId) {
090
091                Object result = null;
092                if (TITLE.equals(columnId)) {
093                    result = ((CmsCategory)itemId).getTitle();
094                    if (CmsStringUtil.isEmptyOrWhitespaceOnly((String)result)) {
095                        result = ((CmsCategory)itemId).getName();
096                    }
097                } else if (PATH.equals(columnId)) {
098                    result = ((CmsCategory)itemId).getPath();
099                } else if (CHECKBOX.equals(columnId)) {
100                    result = m_checkboxes.get(itemId);
101                }
102                return result;
103            }
104        };
105        addGeneratedColumn(TITLE, captionGenerator);
106        addGeneratedColumn(PATH, captionGenerator);
107        addGeneratedColumn(CHECKBOX, captionGenerator);
108        setVisibleColumns(CHECKBOX, TITLE, PATH);
109        setColumnWidth(CHECKBOX, 40);
110        setColumnHeaderMode(ColumnHeaderMode.HIDDEN);
111        setItemCaptionPropertyId(TITLE);
112    }
113
114    /**
115     * Constructor.<p>
116     *
117     * @param cms the cms context
118     * @param contextPath the context path
119     */
120    public CmsCategoryTree(CmsObject cms, String contextPath) {
121        this();
122        loadCategories(cms, contextPath);
123    }
124
125    /**
126     * Returns the selected categories.<p>
127     *
128     * @return the selected categories
129     */
130    @SuppressWarnings("unchecked")
131    public Collection<CmsCategory> getSelectedCategories() {
132
133        Set<CmsCategory> result = new HashSet<CmsCategory>();
134        if (m_isDiplayOny) {
135            // in case of display only, all displayed categories are assume selected
136            result.addAll((Collection<? extends CmsCategory>)getItemIds());
137        } else {
138            for (Entry<CmsCategory, CheckBox> entry : m_checkboxes.entrySet()) {
139                if (entry.getValue().getValue().booleanValue()) {
140                    result.add(entry.getKey());
141                }
142            }
143        }
144        return result;
145    }
146
147    /**
148     * Fills the category tree.<p>
149     *
150     * @param categories the categories
151     */
152    public void setCategories(List<CmsCategory> categories) {
153
154        for (int i = 0; i < categories.size(); i++) {
155            CmsCategory cat = categories.get(i);
156            m_container.addItem(cat);
157            m_checkboxes.put(cat, new CheckBox());
158            String parentPath = CmsResource.getParentFolder(cat.getPath());
159            if (parentPath.length() > 1) {
160                for (int j = i - 1; j >= 0; j--) {
161                    if (categories.get(j).getPath().equals(parentPath)) {
162                        m_container.setParent(cat, categories.get(j));
163                        break;
164                    }
165                }
166            }
167        }
168        // hide openers
169        for (CmsCategory cat : categories) {
170            if ((m_container.getChildren(cat) == null) || (m_container.getChildren(cat).size() == 0)) {
171                m_container.setChildrenAllowed(cat, false);
172            }
173        }
174    }
175
176    /**
177     * Sets the display mode.<p>
178     *
179     * @param displayOnly <code>true</code> to display categories only, not selectable with a hidden check box
180     */
181    public void setDisplayOnly(boolean displayOnly) {
182
183        m_isDiplayOny = displayOnly;
184        if (displayOnly) {
185            setVisibleColumns(TITLE, PATH);
186        } else {
187            setVisibleColumns(CHECKBOX, TITLE, PATH);
188        }
189    }
190
191    /**
192     * Sets the selected categories.<p>
193     *
194     * @param categories the categories to select
195     */
196    public void setSelectedCategories(Collection<CmsCategory> categories) {
197
198        for (Entry<CmsCategory, CheckBox> entry : m_checkboxes.entrySet()) {
199            entry.getValue().setValue(Boolean.valueOf(categories.contains(entry.getKey())));
200            CmsCategory parentCat = (CmsCategory)getParent(entry.getKey());
201            if (parentCat != null) {
202                setCollapsed(parentCat, false);
203            }
204        }
205    }
206
207    /**
208     * Loads the categories for the given context path.<p>
209     *
210     * @param cms the cms context
211     * @param contextPath the context path
212     */
213    void loadCategories(CmsObject cms, String contextPath) {
214
215        m_checkboxes.clear();
216        m_container.removeAllItems();
217
218        List<CmsCategory> categories;
219        Locale wpLocale = OpenCms.getWorkplaceManager().getWorkplaceLocale(cms);
220        CmsCategoryService catService = CmsCategoryService.getInstance();
221        // get the categories
222        try {
223            categories = catService.readCategories(cms, "", true, contextPath);
224
225            categories = catService.localizeCategories(cms, categories, wpLocale);
226            setCategories(categories);
227        } catch (CmsException e) {
228            // TODO Auto-generated catch block
229            e.printStackTrace();
230        }
231    }
232}