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.tools.searchindex;
029
030import org.opencms.configuration.CmsSearchConfiguration;
031import org.opencms.i18n.CmsMessageContainer;
032import org.opencms.jsp.CmsJspActionElement;
033import org.opencms.main.CmsIllegalStateException;
034import org.opencms.main.CmsLog;
035import org.opencms.main.OpenCms;
036import org.opencms.search.CmsSearchDocumentType;
037import org.opencms.search.CmsSearchIndexSource;
038import org.opencms.search.CmsSearchManager;
039import org.opencms.workplace.CmsWorkplaceSettings;
040import org.opencms.workplace.list.CmsListColumnAlignEnum;
041import org.opencms.workplace.list.CmsListColumnDefinition;
042import org.opencms.workplace.list.CmsListDefaultAction;
043import org.opencms.workplace.list.CmsListDirectAction;
044import org.opencms.workplace.list.CmsListItem;
045import org.opencms.workplace.list.CmsListItemDetails;
046import org.opencms.workplace.list.CmsListItemDetailsFormatter;
047import org.opencms.workplace.list.CmsListMetadata;
048import org.opencms.workplace.list.CmsListMultiAction;
049import org.opencms.workplace.list.CmsListOrderEnum;
050
051import java.util.ArrayList;
052import java.util.Collections;
053import java.util.Iterator;
054import java.util.List;
055
056import javax.servlet.http.HttpServletRequest;
057import javax.servlet.http.HttpServletResponse;
058import javax.servlet.jsp.PageContext;
059
060import org.apache.commons.logging.Log;
061
062/**
063 * A list that displays the document types of the system that are assigned to
064 * a request parameter given
065 * <code>{@link org.opencms.search.CmsSearchIndexSource}</code> ("indexsource") and
066 * offers single- and multi-actions that remove those document types to the current
067 * indexsource.<p>
068 *
069 * This list is no stand-alone page but has to be embedded in another dialog
070 * (see <code> {@link org.opencms.workplace.tools.searchindex.A_CmsEmbeddedListDialog}</code>. <p>
071 *
072 * @since 6.0.0
073 */
074public class CmsDocumentTypeRemoveList extends A_CmsEmbeddedListDialog {
075
076    /** list action dummy id constant. */
077    public static final String LIST_ACTION_NONE = "an";
078
079    /** list action id constant. */
080    public static final String LIST_ACTION_REMOVE_DOCTYPE = "ard";
081
082    /** list action id constant. */
083    public static final String LIST_ACTION_REMOVE_DOCTYPE2 = LIST_ACTION_REMOVE_DOCTYPE + "2";
084
085    /** list column id constant. */
086    public static final String LIST_COLUMN_DOCCLASS = "cdc";
087
088    /** list column id constant. */
089    public static final String LIST_COLUMN_ICON = "ci";
090
091    /** list column id constant. */
092    public static final String LIST_COLUMN_NAME = "cn";
093
094    /** list column id constant. */
095    public static final String LIST_COLUMN_REMOVE_DOCTYPE = "crd";
096
097    /** list item detail id constant. */
098    public static final String LIST_DETAIL_MIMETYPES = "dmt";
099
100    /** list item detail id constant. */
101    public static final String LIST_DETAIL_RESOURCETYPES = "drt";
102
103    /** list id constant. */
104    public static final String LIST_ID = "lssisdtr";
105
106    /** list action id constant. */
107    public static final String LIST_MACTION_REMOVE_DOCTYPE = "mard";
108
109    /** The log object for this class. */
110    private static final Log LOG = CmsLog.getLog(CmsDocumentTypeRemoveList.class);
111
112    /** Stores the value of the request parameter for the search index source name. */
113    private String m_paramIndexsource;
114
115    /**
116     * Public constructor.<p>
117     *
118     * @param jsp an initialized JSP action element
119     */
120    public CmsDocumentTypeRemoveList(CmsJspActionElement jsp) {
121
122        this(jsp, LIST_ID, Messages.get().container(Messages.GUI_LIST_DOCUMENTTYPES_NAME_0));
123    }
124
125    /**
126     * Public constructor.<p>
127     *
128     * @param jsp an initialized JSP action element
129     * @param listId the id of the list
130     * @param listName the list name
131     */
132    public CmsDocumentTypeRemoveList(CmsJspActionElement jsp, String listId, CmsMessageContainer listName) {
133
134        this(jsp, listId, listName, LIST_COLUMN_NAME, CmsListOrderEnum.ORDER_ASCENDING, null);
135    }
136
137    /**
138     * Public constructor.<p>
139     *
140     * @param jsp an initialized JSP action element
141     * @param listId the id of the displayed list
142     * @param listName the name of the list
143     * @param sortedColId the a priory sorted column
144     * @param sortOrder the order of the sorted column
145     * @param searchableColId the column to search into
146     */
147    public CmsDocumentTypeRemoveList(
148        CmsJspActionElement jsp,
149        String listId,
150        CmsMessageContainer listName,
151        String sortedColId,
152        CmsListOrderEnum sortOrder,
153        String searchableColId) {
154
155        super(jsp, listId, listName, sortedColId, sortOrder, searchableColId);
156
157    }
158
159    /**
160     * Public constructor.<p>
161     *
162     * Public constructor with JSP variables.<p>
163     *
164     * @param context the JSP page context
165     * @param req the JSP request
166     * @param res the JSP response
167     */
168    public CmsDocumentTypeRemoveList(PageContext context, HttpServletRequest req, HttpServletResponse res) {
169
170        this(new CmsJspActionElement(context, req, res));
171    }
172
173    /**
174     * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions()
175     */
176    @Override
177    public void executeListMultiActions() {
178
179        CmsSearchManager searchManager = OpenCms.getSearchManager();
180        if (getParamListAction().equals(LIST_MACTION_REMOVE_DOCTYPE)) {
181            // execute the delete multiaction
182            Iterator<CmsListItem> itItems = getSelectedItems().iterator();
183            CmsListItem listItem;
184            String doctype;
185            CmsSearchIndexSource idxsrc = searchManager.getIndexSource(getParamIndexsource());
186            while (itItems.hasNext()) {
187                listItem = itItems.next();
188                doctype = (String)listItem.get(LIST_COLUMN_NAME);
189                idxsrc.removeDocumentType(doctype);
190            }
191            writeConfiguration(false);
192            refreshList();
193        }
194        listSave();
195    }
196
197    /**
198     * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions()
199     */
200    @Override
201    public void executeListSingleActions() {
202
203        CmsSearchManager searchManager = OpenCms.getSearchManager();
204        String action = getParamListAction();
205        if (action.equals(LIST_ACTION_REMOVE_DOCTYPE) || action.equals(LIST_ACTION_REMOVE_DOCTYPE2)) {
206            CmsSearchIndexSource idxsrc = searchManager.getIndexSource(getParamIndexsource());
207            CmsListItem item = getSelectedItem();
208            String doctypeName = (String)item.get(LIST_COLUMN_NAME);
209            idxsrc.removeDocumentType(doctypeName);
210            refreshList();
211            writeConfiguration(false);
212        }
213    }
214
215    /**
216     * Returns the request parameter "indexsource".<p>
217     *
218     * @return the request parameter "indexsource"
219     */
220    public String getParamIndexsource() {
221
222        return m_paramIndexsource;
223    }
224
225    /**
226     * Sets the request parameter "indexsource". <p>
227     *
228     * Method intended for workplace-properietary automatic filling of
229     * request parameter values to dialogs, not for manual invocation. <p>
230     *
231     * @param indexsource the request parameter "indexsource" to set
232     */
233    public void setParamIndexsource(String indexsource) {
234
235        m_paramIndexsource = indexsource;
236    }
237
238    /**
239     * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String)
240     */
241    @Override
242    protected void fillDetails(String detailId) {
243
244        // get content
245        List<CmsListItem> items = getList().getAllContent();
246        Iterator<CmsListItem> itItems = items.iterator();
247        CmsListItem item;
248        if (detailId.equals(LIST_DETAIL_MIMETYPES)) {
249            while (itItems.hasNext()) {
250                item = itItems.next();
251                fillDetailMimetypes(item, detailId);
252
253            }
254        }
255        if (detailId.equals(LIST_DETAIL_RESOURCETYPES)) {
256            while (itItems.hasNext()) {
257                item = itItems.next();
258                fillDetailResourceTypes(item, detailId);
259
260            }
261
262        }
263
264    }
265
266    /**
267     * @see org.opencms.workplace.list.A_CmsListDialog#getListItems()
268     */
269    @Override
270    protected List<CmsListItem> getListItems() {
271
272        List<CmsListItem> result = new ArrayList<CmsListItem>();
273        // get content
274        List<CmsSearchDocumentType> doctypes = documentTypes();
275        Iterator<CmsSearchDocumentType> itDoctypes = doctypes.iterator();
276        CmsSearchDocumentType doctype;
277        while (itDoctypes.hasNext()) {
278            doctype = itDoctypes.next();
279            CmsListItem item = getList().newItem(doctype.getName());
280            item.set(LIST_COLUMN_NAME, doctype.getName());
281            item.set(LIST_COLUMN_DOCCLASS, doctype.getClassName());
282            result.add(item);
283        }
284        return result;
285    }
286
287    /**
288     * @see org.opencms.workplace.CmsWorkplace#initMessages()
289     */
290    @Override
291    protected void initMessages() {
292
293        // add specific dialog resource bundle
294        addMessages(Messages.get().getBundleName());
295        // add default resource bundles
296        super.initMessages();
297    }
298
299    /**
300     * @see org.opencms.workplace.list.A_CmsListDialog#initWorkplaceRequestValues(org.opencms.workplace.CmsWorkplaceSettings, javax.servlet.http.HttpServletRequest)
301     */
302    @Override
303    protected void initWorkplaceRequestValues(CmsWorkplaceSettings settings, HttpServletRequest request) {
304
305        super.initWorkplaceRequestValues(settings, request);
306    }
307
308    /**
309     * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata)
310     */
311    @Override
312    protected void setColumns(CmsListMetadata metadata) {
313
314        // create dummy column for corporate design reasons
315        CmsListColumnDefinition dummyCol = new CmsListColumnDefinition(LIST_COLUMN_ICON);
316        dummyCol.setName(Messages.get().container(Messages.GUI_LIST_DOCUMENTTYPE_NAME_0));
317        dummyCol.setHelpText(Messages.get().container(Messages.GUI_LIST_DOCUMENTTYPE_NAME_HELP_0));
318        dummyCol.setWidth("20");
319        dummyCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT);
320        dummyCol.setSorteable(false);
321        // add dummy icon
322        CmsListDirectAction dummyAction = new CmsListDirectAction(LIST_ACTION_NONE);
323        dummyAction.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ICON_NAME_0));
324        dummyAction.setHelpText(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_ICON_NAME_HELP_0));
325        dummyAction.setIconPath(CmsDocumentTypeList.ICON_DOCTYPE);
326        // disable!
327        dummyAction.setEnabled(false);
328        dummyCol.addDirectAction(dummyAction);
329        // add it to the list definition
330        metadata.addColumn(dummyCol);
331
332        // add column for add single-action
333        CmsListColumnDefinition remCol = new CmsListColumnDefinition(LIST_COLUMN_REMOVE_DOCTYPE);
334        remCol.setName(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_REMOVE_DOCTYPE_NAME_0));
335        remCol.setHelpText(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_REMOVE_DOCTYPE_NAME_HELP_0));
336        remCol.setWidth("20");
337        remCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT);
338        remCol.setSorteable(false);
339        // add add action
340        CmsListDirectAction remAction = new CmsListDirectAction(LIST_ACTION_REMOVE_DOCTYPE);
341        remAction.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_ACTION_REMOVE_DOCTYPE_NAME_0));
342        remAction.setHelpText(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_REMOVE_DOCTYPE_NAME_HELP_0));
343        remAction.setIconPath(ICON_MINUS);
344        remCol.addDirectAction(remAction);
345        metadata.addColumn(remCol);
346
347        // add column for name
348        CmsListColumnDefinition nameCol = new CmsListColumnDefinition(LIST_COLUMN_NAME);
349        nameCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT);
350        nameCol.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_COL_NAME_0));
351        nameCol.setWidth("50%");
352
353        // add a duplicate action
354        CmsListDefaultAction remAction2 = new CmsListDefaultAction(LIST_ACTION_REMOVE_DOCTYPE2);
355        remAction2.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_ACTION_REMOVE_DOCTYPE_NAME_0));
356        remAction2.setHelpText(Messages.get().container(Messages.GUI_LIST_INDEXSOURCE_COL_REMOVE_DOCTYPE_NAME_HELP_0));
357        nameCol.addDefaultAction(remAction2);
358        metadata.addColumn(nameCol);
359
360        // add column for document implementation class
361        CmsListColumnDefinition docclassCol = new CmsListColumnDefinition(LIST_COLUMN_DOCCLASS);
362        docclassCol.setAlign(CmsListColumnAlignEnum.ALIGN_LEFT);
363        docclassCol.setName(Messages.get().container(Messages.GUI_LIST_DOCTYPE_COL_DOCCLASS_0));
364        docclassCol.setWidth("45%");
365        metadata.addColumn(docclassCol);
366
367    }
368
369    /**
370     * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata)
371     */
372    @Override
373    protected void setIndependentActions(CmsListMetadata metadata) {
374
375        // add document types of index source detail help
376        CmsListItemDetails mimetypeDetails = new CmsListItemDetails(LIST_DETAIL_MIMETYPES);
377        mimetypeDetails.setAtColumn(LIST_COLUMN_NAME);
378        mimetypeDetails.setVisible(false);
379        mimetypeDetails.setShowActionName(Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_MIMETYPES_SHOW_0));
380        mimetypeDetails.setShowActionHelpText(
381            Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_MIMETYPES_SHOW_HELP_0));
382        mimetypeDetails.setHideActionName(Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_MIMETYPES_HIDE_0));
383        mimetypeDetails.setHideActionHelpText(
384            Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_MIMETYPES_HIDE_HELP_0));
385        mimetypeDetails.setName(Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_MIMETYPES_NAME_0));
386        mimetypeDetails.setFormatter(
387            new CmsListItemDetailsFormatter(
388                Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_MIMETYPES_NAME_0)));
389        metadata.addItemDetails(mimetypeDetails);
390
391        // add resources of index source detail help
392        CmsListItemDetails resourceDetails = new CmsListItemDetails(LIST_DETAIL_RESOURCETYPES);
393        resourceDetails.setAtColumn(LIST_COLUMN_NAME);
394        resourceDetails.setVisible(false);
395        resourceDetails.setShowActionName(
396            Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_RESOURCETYPES_SHOW_0));
397        resourceDetails.setShowActionHelpText(
398            Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_RESOURCETYPES_SHOW_HELP_0));
399        resourceDetails.setHideActionName(
400            Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_RESOURCETYPES_HIDE_0));
401        resourceDetails.setHideActionHelpText(
402            Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_RESOURCETYPES_HIDE_HELP_0));
403        resourceDetails.setName(Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_RESOURCETYPES_NAME_0));
404        resourceDetails.setFormatter(
405            new CmsListItemDetailsFormatter(
406                Messages.get().container(Messages.GUI_LIST_DOCTYPE_DETAIL_RESOURCETYPES_NAME_0)));
407        metadata.addItemDetails(resourceDetails);
408
409    }
410
411    /**
412     * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata)
413     */
414    @Override
415    protected void setMultiActions(CmsListMetadata metadata) {
416
417        // add add multi action
418        CmsListMultiAction addMultiAction = new CmsListMultiAction(LIST_MACTION_REMOVE_DOCTYPE);
419        addMultiAction.setName(Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_MACTION_REMOVE_DOCTYPE_NAME_0));
420        addMultiAction.setHelpText(
421            Messages.get().container(Messages.GUI_LIST_SEARCHINDEX_MACTION_REMOVE_DOCTYPE_NAME_HELP_0));
422        addMultiAction.setIconPath(ICON_MULTI_MINUS);
423        metadata.addMultiAction(addMultiAction);
424    }
425
426    /**
427     * @see org.opencms.workplace.list.A_CmsListDialog#validateParamaters()
428     */
429    @Override
430    protected void validateParamaters() throws Exception {
431
432        // test the needed parameters
433        if (getParamIndexsource() == null) {
434            throw new CmsIllegalStateException(Messages.get().container(
435                Messages.ERR_SEARCHINDEX_EDIT_MISSING_PARAM_1,
436                A_CmsEditIndexSourceDialog.PARAM_INDEXSOURCE));
437        }
438    }
439
440    /**
441     * Writes the updated search configuration back to the XML
442     * configuration file and refreshes the complete list.<p>
443     *
444     * @param refresh if true, the list items are refreshed
445     */
446    protected void writeConfiguration(boolean refresh) {
447
448        // update the XML configuration
449        OpenCms.writeConfiguration(CmsSearchConfiguration.class);
450        if (refresh) {
451            refreshList();
452        }
453    }
454
455    /**
456     * Returns the systems configured document types that are assigned
457     * to the current indexsource (those that may be removed).<p>
458     *
459     * @return the systems configured document types that are assigned
460     *         to the current indexsource (those that may be removed)
461     */
462    private List<CmsSearchDocumentType> documentTypes() {
463
464        CmsSearchManager manager = OpenCms.getSearchManager();
465        CmsSearchIndexSource indexsource = manager.getIndexSource(getParamIndexsource());
466        List<CmsSearchDocumentType> result;
467        if (indexsource != null) {
468            List<String> doctypeNames = indexsource.getDocumentTypes();
469
470            // transform these mere names to real document types...
471            result = new ArrayList<CmsSearchDocumentType>(doctypeNames.size());
472            Iterator<String> it = doctypeNames.iterator();
473            String doctypename = "";
474            CmsSearchDocumentType doctype;
475            while (it.hasNext()) {
476                doctypename = it.next();
477                if (doctypename != null) {
478                    doctype = manager.getDocumentTypeConfig(doctypename);
479                    if (doctype != null) {
480                        result.add(doctype);
481                    }
482                }
483            }
484        } else {
485            result = Collections.emptyList();
486            if (LOG.isErrorEnabled()) {
487                LOG.error(Messages.get().getBundle().key(Messages.ERR_SEARCHINDEX_EDIT_MISSING_PARAM_1, "indexsource"));
488            }
489
490        }
491        return result;
492    }
493
494    /**
495     * Fills details about configured mime types of the document type into the given item. <p>
496     *
497     * @param item the list item to fill
498     * @param detailId the id for the detail to fill
499     *
500     */
501    private void fillDetailMimetypes(CmsListItem item, String detailId) {
502
503        CmsSearchManager searchManager = OpenCms.getSearchManager();
504        StringBuffer html = new StringBuffer();
505
506        String doctypeName = (String)item.get(LIST_COLUMN_NAME);
507        CmsSearchDocumentType docType = searchManager.getDocumentTypeConfig(doctypeName);
508
509        // output of mime types
510        Iterator<String> itMimetypes = docType.getMimeTypes().iterator();
511        html.append("<ul>\n");
512        while (itMimetypes.hasNext()) {
513            html.append("  <li>\n").append("  ").append(itMimetypes.next()).append("\n");
514            html.append("  </li>");
515        }
516
517        html.append("</ul>\n");
518        item.set(detailId, html.toString());
519    }
520
521    /**
522     * Fills details about resource types of the document type into the given item. <p>
523     *
524     * @param item the list item to fill
525     * @param detailId the id for the detail to fill
526     *
527     */
528    private void fillDetailResourceTypes(CmsListItem item, String detailId) {
529
530        CmsSearchManager searchManager = OpenCms.getSearchManager();
531        StringBuffer html = new StringBuffer();
532
533        String doctypeName = (String)item.get(LIST_COLUMN_NAME);
534        CmsSearchDocumentType docType = searchManager.getDocumentTypeConfig(doctypeName);
535
536        // output of resource types
537        Iterator<String> itResourcetypes = docType.getResourceTypes().iterator();
538        html.append("<ul>\n");
539        while (itResourcetypes.hasNext()) {
540            html.append("  <li>\n").append("  ").append(itResourcetypes.next()).append("\n");
541            html.append("  </li>");
542        }
543
544        html.append("</ul>\n");
545        item.set(detailId, html.toString());
546    }
547}