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 GmbH & Co. KG, 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.workplace.commons;
029
030import org.opencms.file.CmsResource;
031import org.opencms.i18n.CmsMessageContainer;
032import org.opencms.jsp.CmsJspActionElement;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsRuntimeException;
035import org.opencms.main.OpenCms;
036import org.opencms.relations.CmsCategory;
037import org.opencms.relations.CmsCategoryService;
038import org.opencms.util.CmsStringUtil;
039import org.opencms.workplace.CmsWorkplace;
040import org.opencms.workplace.list.A_CmsListDialog;
041import org.opencms.workplace.list.CmsListColumnDefinition;
042import org.opencms.workplace.list.CmsListItem;
043import org.opencms.workplace.list.CmsListItemDetails;
044import org.opencms.workplace.list.CmsListMetadata;
045import org.opencms.workplace.list.CmsListOrderEnum;
046import org.opencms.workplace.list.I_CmsListFormatter;
047
048import java.util.ArrayList;
049import java.util.HashMap;
050import java.util.Iterator;
051import java.util.List;
052import java.util.Locale;
053import java.util.Map;
054
055/**
056 * Generalized resource categories view.<p>
057 *
058 * @since 6.9.2
059 */
060public abstract class A_CmsResourceCategoriesList extends A_CmsListDialog {
061
062    /** list action id constant. */
063    public static final String LIST_ACTION_ICON = "ai";
064
065    /** list column id constant. */
066    public static final String LIST_COLUMN_ICON = "ci";
067
068    /** list column id constant. */
069    public static final String LIST_COLUMN_LEAFS = "cl";
070
071    /** list column id constant. */
072    public static final String LIST_COLUMN_NAME = "cn";
073
074    /** list column id constant. */
075    public static final String LIST_COLUMN_PATH = "cp";
076
077    /** list column id constant. */
078    public static final String LIST_COLUMN_STATE = "cs";
079
080    /** list item detail id constant. */
081    public static final String LIST_DETAIL_DESCRIPTION = "doo";
082
083    /** list item detail id constant. */
084    public static final String LIST_DETAIL_PATH = "dp";
085
086    /** The current category service. */
087    private CmsCategoryService m_categoryService;
088
089    /** The current resource categories. */
090    private List<CmsCategory> m_resCats;
091
092    /**
093     * Public constructor.<p>
094     *
095     * @param jsp an initialized JSP action element
096     * @param listId the id of the list
097     * @param listName the name of the list
098     * @param searchable searchable flag
099     */
100    protected A_CmsResourceCategoriesList(
101        CmsJspActionElement jsp,
102        String listId,
103        CmsMessageContainer listName,
104        boolean searchable) {
105
106        super(
107            jsp,
108            listId,
109            listName,
110            LIST_COLUMN_PATH,
111            CmsListOrderEnum.ORDER_ASCENDING,
112            searchable ? LIST_COLUMN_NAME : null);
113        m_categoryService = CmsCategoryService.getInstance();
114    }
115
116    /**
117     * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions()
118     */
119    @Override
120    public void executeListMultiActions() throws CmsRuntimeException {
121
122        throwListUnsupportedActionException();
123    }
124
125    /**
126     * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String)
127     */
128    @Override
129    protected void fillDetails(String detailId) {
130
131        // get content
132        List<CmsListItem> items = getList().getAllContent();
133        Iterator<CmsListItem> itCategories = items.iterator();
134        while (itCategories.hasNext()) {
135            CmsListItem item = itCategories.next();
136            String categoryPath = item.getId();
137            StringBuffer html = new StringBuffer(512);
138            try {
139                CmsCategory category = m_categoryService.readCategory(getCms(), categoryPath, getParamResource());
140                if (detailId.equals(LIST_DETAIL_PATH)) {
141                    html.append(category.getRootPath());
142                } else if (detailId.equals(LIST_DETAIL_DESCRIPTION)) {
143                    // Append the description if one is given
144                    if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(category.getDescription())) {
145                        html.append(category.getDescription());
146                    }
147                }
148            } catch (Exception e) {
149                // noop
150            }
151            item.set(detailId, html.toString());
152        }
153    }
154
155    /**
156     * Returns a list of categories to display.<p>
157     *
158     * @return a list of categories
159     *
160     * @throws CmsException if something goes wrong
161     */
162    protected abstract List<CmsCategory> getCategories() throws CmsException;
163
164    /**
165     * Returns the categoryService.<p>
166     *
167     * @return the categoryService
168     */
169    protected CmsCategoryService getCategoryService() {
170
171        return m_categoryService;
172    }
173
174    /**
175     * @see org.opencms.workplace.list.A_CmsListDialog#getListItems()
176     */
177    @Override
178    protected List<CmsListItem> getListItems() throws CmsException {
179
180        Map<String, CmsListItem> ret = new HashMap<String, CmsListItem>();
181        Map<String, Boolean> isLeaf = new HashMap<String, Boolean>();
182        List<CmsCategory> cats = getCategories();
183        cats = CmsCategoryService.getInstance().localizeCategories(
184            getCms(),
185            cats,
186            OpenCms.getWorkplaceManager().getWorkplaceLocale(getCms()));
187        Iterator<CmsCategory> itCategories = cats.iterator();
188        while (itCategories.hasNext()) {
189            CmsCategory category = itCategories.next();
190            isLeaf.put(category.getPath(), Boolean.TRUE);
191        }
192        itCategories = cats.iterator();
193        while (itCategories.hasNext()) {
194            CmsCategory category = itCategories.next();
195            String parentPath = CmsResource.getParentFolder(category.getPath());
196            if (parentPath == null) {
197                continue;
198            }
199            if (isLeaf.get(parentPath) != null) {
200                isLeaf.put(parentPath, Boolean.FALSE);
201            }
202        }
203        itCategories = cats.iterator();
204        while (itCategories.hasNext()) {
205            CmsCategory category = itCategories.next();
206            String categoryPath = category.getPath();
207            if (ret.get(categoryPath) != null) {
208                continue;
209            }
210            CmsListItem item = getList().newItem(categoryPath);
211            StringBuffer itemHtml = new StringBuffer(192);
212            int pathLevel = CmsStringUtil.splitAsList(categoryPath, '/').size();
213            if (pathLevel > 1) {
214                // append image for indentation
215                itemHtml.append("<img src=\"");
216                itemHtml.append(CmsWorkplace.getResourceUri("tree/empty.gif"));
217                itemHtml.append("\" width=\"");
218                itemHtml.append((pathLevel - 1) * 20);
219                itemHtml.append("px\" height=\"11px\"/>");
220            }
221            String name = category.getTitle();
222            if (CmsStringUtil.isEmptyOrWhitespaceOnly(name)) {
223                name = category.getName();
224            }
225            itemHtml.append(name);
226            item.set(LIST_COLUMN_NAME, itemHtml.toString());
227            item.set(LIST_COLUMN_PATH, categoryPath);
228            item.set(LIST_COLUMN_LEAFS, isLeaf.get(categoryPath));
229            ret.put(item.getId(), item);
230        }
231
232        return new ArrayList<CmsListItem>(ret.values());
233    }
234
235    /**
236     * Returns a list of a categories related to the current request resource.<p>
237     *
238     * @return a list of a categories related to the current request resource
239     *
240     * @throws CmsException if something goes wrong
241     */
242    protected List<CmsCategory> getResourceCategories() throws CmsException {
243
244        if (m_resCats == null) {
245            m_resCats = m_categoryService.readResourceCategories(getJsp().getCmsObject(), getParamResource());
246        }
247        return m_resCats;
248    }
249
250    /**
251     * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata)
252     */
253    @Override
254    protected void setColumns(CmsListMetadata metadata) {
255
256        setStateActionCol(metadata);
257
258        // create column for name
259        CmsListColumnDefinition nameCol = new CmsListColumnDefinition(LIST_COLUMN_NAME);
260        nameCol.setName(Messages.get().container(Messages.GUI_CATEGORIES_LIST_COLS_NAME_0));
261        nameCol.setWidth("100%");
262        nameCol.setSorteable(false);
263        // add it to the list definition
264        metadata.addColumn(nameCol);
265
266        // create column for path
267        CmsListColumnDefinition pathCol = new CmsListColumnDefinition(LIST_COLUMN_PATH);
268        pathCol.setName(Messages.get().container(Messages.GUI_CATEGORIES_LIST_COLS_PATH_0));
269        pathCol.setVisible(false);
270        // add it to the list definition
271        metadata.addColumn(pathCol);
272
273        // create column for leaf
274        CmsListColumnDefinition leafCol = new CmsListColumnDefinition(LIST_COLUMN_LEAFS);
275        leafCol.setName(Messages.get().container(Messages.GUI_CATEGORIES_LIST_COLS_PATH_0));
276        leafCol.setVisible(false);
277        // add it to the list definition
278        metadata.addColumn(leafCol);
279    }
280
281    /**
282     * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata)
283     */
284    @Override
285    protected void setIndependentActions(CmsListMetadata metadata) {
286
287        // show path
288        CmsListItemDetails pathDetails = new CmsListItemDetails(LIST_DETAIL_PATH);
289        pathDetails.setAtColumn(LIST_COLUMN_NAME);
290        pathDetails.setVisible(false);
291        pathDetails.setShowActionName(Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_SHOW_PATH_NAME_0));
292        pathDetails.setShowActionHelpText(Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_SHOW_PATH_HELP_0));
293        pathDetails.setHideActionName(Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_HIDE_PATH_NAME_0));
294        pathDetails.setHideActionHelpText(Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_HIDE_PATH_HELP_0));
295        pathDetails.setName(Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_PATH_NAME_0));
296        pathDetails.setFormatter(new I_CmsListFormatter() {
297
298            /**
299             * @see org.opencms.workplace.list.I_CmsListFormatter#format(java.lang.Object, java.util.Locale)
300             */
301            @Override
302            public String format(Object data, Locale locale) {
303
304                StringBuffer html = new StringBuffer(512);
305                html.append("<table border='0' cellspacing='0' cellpadding='0'>\n");
306                html.append("\t<tr>\n");
307                html.append("\t\t<td style='white-space:normal;' >\n");
308                html.append("\t\t\t");
309                html.append(data == null ? "" : data);
310                html.append("\n");
311                html.append("\t\t</td>\n");
312                html.append("\t</tr>\n");
313                html.append("</table>\n");
314                return html.toString();
315            }
316        });
317        metadata.addItemDetails(pathDetails);
318
319        // show description
320        CmsListItemDetails descriptionDetails = new CmsListItemDetails(LIST_DETAIL_DESCRIPTION);
321        descriptionDetails.setAtColumn(LIST_COLUMN_NAME);
322        descriptionDetails.setVisible(false);
323        descriptionDetails.setShowActionName(
324            Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_SHOW_DESCRIPTION_NAME_0));
325        descriptionDetails.setShowActionHelpText(
326            Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_SHOW_DESCRIPTION_HELP_0));
327        descriptionDetails.setHideActionName(
328            Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_HIDE_DESCRIPTION_NAME_0));
329        descriptionDetails.setHideActionHelpText(
330            Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_HIDE_DESCRIPTION_HELP_0));
331        descriptionDetails.setName(Messages.get().container(Messages.GUI_CATEGORIES_DETAIL_DESCRIPTION_NAME_0));
332        descriptionDetails.setFormatter(new I_CmsListFormatter() {
333
334            /**
335             * @see org.opencms.workplace.list.I_CmsListFormatter#format(java.lang.Object, java.util.Locale)
336             */
337            @Override
338            public String format(Object data, Locale locale) {
339
340                StringBuffer html = new StringBuffer(512);
341                html.append("<table border='0' cellspacing='0' cellpadding='0'>\n");
342                html.append("\t<tr>\n");
343                html.append("\t\t<td style='white-space:normal;' >\n");
344                html.append("\t\t\t");
345                html.append(data == null ? "" : data);
346                html.append("\n");
347                html.append("\t\t</td>\n");
348                html.append("\t</tr>\n");
349                html.append("</table>\n");
350                return html.toString();
351            }
352        });
353        metadata.addItemDetails(descriptionDetails);
354    }
355
356    /**
357     * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata)
358     */
359    @Override
360    protected void setMultiActions(CmsListMetadata metadata) {
361
362        // noop
363    }
364
365    /**
366     * Sets the optional state change action column.<p>
367     *
368     * @param metadata the list metadata object
369     */
370    protected abstract void setStateActionCol(CmsListMetadata metadata);
371}