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.db.CmsPublishList;
031import org.opencms.db.CmsUserSettings;
032import org.opencms.file.CmsObject;
033import org.opencms.file.CmsResource;
034import org.opencms.file.CmsResourceFilter;
035import org.opencms.file.CmsVfsResourceNotFoundException;
036import org.opencms.i18n.CmsMessageContainer;
037import org.opencms.jsp.CmsJspActionElement;
038import org.opencms.main.CmsException;
039import org.opencms.main.CmsIllegalStateException;
040import org.opencms.main.CmsLog;
041import org.opencms.main.OpenCms;
042import org.opencms.relations.CmsRelation;
043import org.opencms.relations.CmsRelationFilter;
044import org.opencms.util.CmsStringUtil;
045import org.opencms.workplace.CmsWorkplace;
046import org.opencms.workplace.explorer.CmsResourceUtil;
047import org.opencms.workplace.list.A_CmsListDialog;
048import org.opencms.workplace.list.A_CmsListExplorerDialog;
049import org.opencms.workplace.list.A_CmsListIndependentJsAction;
050import org.opencms.workplace.list.A_CmsListResourceCollector;
051import org.opencms.workplace.list.CmsListColumnDefinition;
052import org.opencms.workplace.list.CmsListDirectAction;
053import org.opencms.workplace.list.CmsListExplorerColumn;
054import org.opencms.workplace.list.CmsListIndependentAction;
055import org.opencms.workplace.list.CmsListItem;
056import org.opencms.workplace.list.CmsListItemDetails;
057import org.opencms.workplace.list.CmsListMetadata;
058import org.opencms.workplace.list.CmsListResourceProjStateAction;
059import org.opencms.workplace.list.I_CmsListAction;
060import org.opencms.workplace.list.I_CmsListFormatter;
061import org.opencms.workplace.list.I_CmsListResourceCollector;
062
063import java.util.ArrayList;
064import java.util.Iterator;
065import java.util.List;
066import java.util.Locale;
067import java.util.Map;
068import java.util.zip.DataFormatException;
069
070import org.apache.commons.logging.Log;
071
072/**
073 * List for resources that can be published.<p>
074 *
075 * @since 6.5.5
076 */
077public class CmsPublishResourcesList extends A_CmsListExplorerDialog {
078
079    /** list action id constant. */
080    public static final String LIST_DETAIL_RELATIONS = "dr";
081
082    /** list action id constant. */
083    public static final String LIST_DETAIL_RELATIONS_HIDE = "drh";
084
085    /** list action id constant. */
086    public static final String LIST_DETAIL_RELATIONS_SHOW = "drs";
087
088    /** list id constant. */
089    public static final String LIST_ID = "pr";
090
091    /** List column id constant. */
092    protected static final String LIST_COLUMN_IS_RELATED = "ecir";
093
094    /** The log object for this class. */
095    protected static final Log LOG = CmsLog.getLog(CmsPublishResourcesList.class);
096
097    /** The publish list created for that list. */
098    protected CmsPublishList m_publishList;
099
100    /** Indicates if the related resources should be included. */
101    protected boolean m_publishRelated;
102
103    /** The internal collector instance. */
104    private I_CmsListResourceCollector m_collector;
105
106    /**
107     * Public constructor.<p>
108     *
109     * @param jsp an initialized JSP action element
110     * @param relativeTo the 'relative to' path, this only affects the generation of the path for the resource
111     * @param publishRelated indicates if the related resources should be included
112     */
113    public CmsPublishResourcesList(CmsJspActionElement jsp, String relativeTo, boolean publishRelated) {
114
115        super(jsp, LIST_ID, Messages.get().container(Messages.GUI_PUBLISH_RESOURCES_LIST_NAME_0));
116
117        // prevent paging
118        getList().setMaxItemsPerPage(Integer.MAX_VALUE);
119
120        // set the right resource util parameters
121        CmsResourceUtil resUtil = getResourceUtil();
122        resUtil.setAbbrevLength(50);
123        resUtil.setRelativeTo(getCms().getRequestContext().addSiteRoot(relativeTo));
124        resUtil.setSiteMode(CmsResourceUtil.SITE_MODE_MATCHING);
125
126        m_publishRelated = publishRelated;
127    }
128
129    /**
130     * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions()
131     */
132    @Override
133    public void executeListMultiActions() {
134
135        throwListUnsupportedActionException();
136    }
137
138    /**
139     * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions()
140     */
141    @Override
142    public void executeListSingleActions() {
143
144        throwListUnsupportedActionException();
145    }
146
147    /**
148     * @see org.opencms.workplace.list.A_CmsListExplorerDialog#getCollector()
149     */
150    @Override
151    public I_CmsListResourceCollector getCollector() {
152
153        if (m_collector == null) {
154            m_collector = new A_CmsListResourceCollector(this) {
155
156                /** Parameter of the default collector name. */
157                private static final String COLLECTOR_NAME = "publishResources";
158
159                /**
160                 * @see org.opencms.file.collectors.I_CmsResourceCollector#getCollectorNames()
161                 */
162                public List<String> getCollectorNames() {
163
164                    List<String> names = new ArrayList<String>();
165                    names.add(COLLECTOR_NAME);
166                    return names;
167                }
168
169                /**
170                 * @see org.opencms.workplace.list.A_CmsListResourceCollector#getResources(org.opencms.file.CmsObject, java.util.Map)
171                 */
172                @Override
173                public List<CmsResource> getResources(CmsObject cms, Map<String, String> params) {
174
175                    if (m_publishRelated && getSettings().getPublishList().isDirectPublish()) {
176                        try {
177                            CmsPublishList relatedPL = OpenCms.getPublishManager().getRelatedResourcesToPublish(
178                                cms,
179                                getSettings().getPublishList());
180                            CmsPublishList mergedPL = OpenCms.getPublishManager().mergePublishLists(
181                                cms,
182                                getSettings().getPublishList(),
183                                relatedPL);
184                            m_publishList = mergedPL;
185                        } catch (CmsException e) {
186                            if (LOG.isErrorEnabled()) {
187                                LOG.error(e.getLocalizedMessage(getLocale()), e);
188                            }
189                        }
190                    } else {
191                        m_publishList = getSettings().getPublishList();
192                    }
193                    return m_publishList.getAllResources();
194                }
195
196                /**
197                 * @see org.opencms.workplace.list.A_CmsListResourceCollector#setAdditionalColumns(org.opencms.workplace.list.CmsListItem, org.opencms.workplace.explorer.CmsResourceUtil)
198                 */
199                @Override
200                protected void setAdditionalColumns(CmsListItem item, CmsResourceUtil resUtil) {
201
202                    item.set(
203                        LIST_COLUMN_IS_RELATED,
204                        Boolean.valueOf(
205                            !getSettings().getPublishList().getAllResources().contains(resUtil.getResource())));
206                }
207            };
208        }
209        return m_collector;
210    }
211
212    /**
213     * Returns the publish list created for that list.<p>
214     *
215     * @return the publish list created for that list
216     */
217    public CmsPublishList getPublishList() {
218
219        return m_publishList;
220    }
221
222    /**
223     * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String)
224     */
225    @Override
226    protected void fillDetails(String detailId) {
227
228        CmsObject cms;
229        try {
230            cms = OpenCms.initCmsObject(getCms());
231        } catch (CmsException e) {
232            cms = getCms();
233        }
234
235        // check if progress should be set in the thread
236        CmsProgressThread thread = null;
237        int progressOffset = 0;
238        if (Thread.currentThread() instanceof CmsProgressThread) {
239            thread = (CmsProgressThread)Thread.currentThread();
240            progressOffset = thread.getProgress();
241        }
242
243        List<CmsResource> publishResources = getSettings().getPublishList().getAllResources();
244
245        // get content
246        List<CmsListItem> resourceNames = new ArrayList<CmsListItem>(getList().getAllContent());
247        Iterator<CmsListItem> itResourceNames = resourceNames.iterator();
248        int count = 0;
249        while (itResourceNames.hasNext()) {
250            // set progress in thread
251            count++;
252            if (thread != null) {
253                if (thread.isInterrupted()) {
254                    throw new CmsIllegalStateException(
255                        org.opencms.workplace.commons.Messages.get().container(
256                            org.opencms.workplace.commons.Messages.ERR_PROGRESS_INTERRUPTED_0));
257                }
258                thread.setProgress(((count * 10) / resourceNames.size()) + progressOffset);
259                thread.setDescription(
260                    org.opencms.workplace.commons.Messages.get().getBundle(thread.getLocale()).key(
261                        org.opencms.workplace.commons.Messages.GUI_PROGRESS_PUBLISH_STEP3_2,
262                        Integer.valueOf(count),
263                        Integer.valueOf(resourceNames.size())));
264            }
265
266            CmsListItem item = itResourceNames.next();
267            try {
268                if (detailId.equals(LIST_DETAIL_RELATIONS)) {
269                    List<String> relatedResources = new ArrayList<String>();
270                    CmsResource resource = getResourceUtil(item).getResource();
271
272                    String rightSite = OpenCms.getSiteManager().getSiteRoot(resource.getRootPath());
273                    if (rightSite == null) {
274                        rightSite = "";
275                    }
276                    String oldSite = cms.getRequestContext().getSiteRoot();
277                    try {
278                        cms.getRequestContext().setSiteRoot(rightSite);
279                        // get and iterate over all related resources
280                        Iterator<CmsRelation> itRelations = cms.getRelationsForResource(
281                            resource,
282                            CmsRelationFilter.TARGETS.filterStrong()).iterator();
283                        while (itRelations.hasNext()) {
284                            CmsRelation relation = itRelations.next();
285                            CmsResource target = null;
286                            try {
287                                target = relation.getTarget(cms, CmsResourceFilter.ALL);
288                            } catch (CmsVfsResourceNotFoundException e) {
289                                // target not found, ignore, will come later in the link check dialog
290                            }
291                            // just add resources that may come in question
292                            if ((target != null)
293                                && !publishResources.contains(target)
294                                && !target.getState().isUnchanged()) {
295                                String relationName = target.getRootPath();
296                                if (relationName.startsWith(cms.getRequestContext().getSiteRoot())) {
297                                    // same site
298                                    relationName = cms.getSitePath(target);
299                                    relationName = CmsStringUtil.formatResourceName(relationName, 50);
300                                } else {
301                                    // other site
302                                    String site = OpenCms.getSiteManager().getSiteRoot(relationName);
303                                    String siteName = site;
304                                    if (site != null) {
305                                        relationName = relationName.substring(site.length());
306                                        siteName = OpenCms.getSiteManager().getSiteForSiteRoot(site).getTitle();
307                                    } else {
308                                        siteName = "/";
309                                    }
310                                    relationName = CmsStringUtil.formatResourceName(relationName, 50);
311                                    relationName = key(
312                                        Messages.GUI_DELETE_SITE_RELATION_2,
313                                        new Object[] {siteName, relationName});
314                                }
315                                if (!cms.getLock(target).isLockableBy(cms.getRequestContext().getCurrentUser())) {
316                                    // mark not lockable resources
317                                    relationName = relationName + "*";
318                                } else if (m_publishRelated) {
319                                    // mark related resources to be published
320                                    relationName = relationName + "!";
321                                }
322                                if (!resourceNames.contains(relationName)) {
323                                    relatedResources.add(relationName);
324                                }
325                            }
326                        }
327                        if (((Boolean)item.get(LIST_COLUMN_IS_RELATED)).booleanValue()) {
328                            // mark the reverse references
329                            itRelations = cms.getRelationsForResource(
330                                resource,
331                                CmsRelationFilter.SOURCES.filterStrong()).iterator();
332                            while (itRelations.hasNext()) {
333                                CmsRelation relation = itRelations.next();
334                                CmsResource source = null;
335                                try {
336                                    source = relation.getSource(cms, CmsResourceFilter.ALL);
337                                } catch (CmsVfsResourceNotFoundException e) {
338                                    // source not found, ignore, will come later in the link check dialog
339                                }
340                                // just add resources that may come in question
341                                if ((source != null) && publishResources.contains(source)) {
342                                    String relationName = source.getRootPath();
343                                    if (relationName.startsWith(cms.getRequestContext().getSiteRoot())) {
344                                        // same site
345                                        relationName = cms.getSitePath(source);
346                                        relationName = CmsStringUtil.formatResourceName(relationName, 50);
347                                    } else {
348                                        // other site
349                                        String site = OpenCms.getSiteManager().getSiteRoot(relationName);
350                                        String siteName = site;
351                                        if (site != null) {
352                                            relationName = relationName.substring(site.length());
353                                            siteName = OpenCms.getSiteManager().getSiteForSiteRoot(site).getTitle();
354                                        } else {
355                                            siteName = "/";
356                                        }
357                                        relationName = CmsStringUtil.formatResourceName(relationName, 50);
358                                        relationName = key(
359                                            Messages.GUI_DELETE_SITE_RELATION_2,
360                                            new Object[] {siteName, relationName});
361                                    }
362                                    // mark as reverse reference
363                                    relationName = relationName + "$";
364                                    if (!resourceNames.contains(relationName)) {
365                                        relatedResources.add(relationName);
366                                    }
367                                }
368                            }
369                        }
370                    } finally {
371                        cms.getRequestContext().setSiteRoot(oldSite);
372                    }
373                    if (!relatedResources.isEmpty()) {
374                        item.set(detailId, relatedResources);
375                    }
376                } else {
377                    continue;
378                }
379            } catch (CmsException e) {
380                // should never happen, log exception
381                if (LOG.isErrorEnabled()) {
382                    LOG.error(e.getLocalizedMessage(), e);
383                }
384                item.set(detailId, e.getLocalizedMessage());
385            }
386        }
387    }
388
389    /**
390     * @see org.opencms.workplace.list.A_CmsListExplorerDialog#isColumnVisible(int)
391     */
392    @Override
393    protected boolean isColumnVisible(int colFlag) {
394
395        boolean isVisible = (colFlag == CmsUserSettings.FILELIST_TITLE);
396        isVisible = isVisible || (colFlag == LIST_COLUMN_TYPEICON.hashCode());
397        isVisible = isVisible || (colFlag == LIST_COLUMN_LOCKICON.hashCode());
398        isVisible = isVisible || (colFlag == LIST_COLUMN_PROJSTATEICON.hashCode());
399        isVisible = isVisible || (colFlag == LIST_COLUMN_NAME.hashCode());
400        isVisible = isVisible
401            || ((colFlag == LIST_COLUMN_SITE.hashCode()) && (OpenCms.getSiteManager().getSites().size() > 1));
402        return isVisible;
403    }
404
405    /**
406     * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata)
407     */
408    @Override
409    protected void setColumns(CmsListMetadata metadata) {
410
411        super.setColumns(metadata);
412
413        Iterator<CmsListColumnDefinition> it = metadata.getColumnDefinitions().iterator();
414        while (it.hasNext()) {
415            CmsListColumnDefinition colDefinition = it.next();
416            colDefinition.setSorteable(false);
417            if (colDefinition.getId().equals(LIST_COLUMN_NAME)) {
418                colDefinition.removeDefaultAction(LIST_DEFACTION_OPEN);
419                colDefinition.setWidth("60%");
420            } else if (colDefinition.getId().equals(LIST_COLUMN_PROJSTATEICON)) {
421                colDefinition.removeDirectAction(LIST_ACTION_PROJSTATEICON);
422                // add resource state icon action
423                CmsListDirectAction resourceProjStateAction = new CmsListResourceProjStateAction(
424                    LIST_ACTION_PROJSTATEICON) {
425
426                    /**
427                     * @see org.opencms.workplace.list.CmsListResourceProjStateAction#getIconPath()
428                     */
429                    @Override
430                    public String getIconPath() {
431
432                        if (((Boolean)getItem().get(LIST_COLUMN_IS_RELATED)).booleanValue()) {
433                            return "explorer/related_resource.png";
434                        }
435                        return super.getIconPath();
436                    }
437
438                    /**
439                     * @see org.opencms.workplace.list.CmsListResourceProjStateAction#getName()
440                     */
441                    @Override
442                    public CmsMessageContainer getName() {
443
444                        if (((Boolean)getItem().get(LIST_COLUMN_IS_RELATED)).booleanValue()) {
445                            return Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCE_0);
446                        }
447                        return super.getName();
448                    }
449                };
450                resourceProjStateAction.setEnabled(false);
451                colDefinition.addDirectAction(resourceProjStateAction);
452            }
453        }
454
455        CmsListColumnDefinition relatedCol = new CmsListExplorerColumn(LIST_COLUMN_IS_RELATED);
456        relatedCol.setName(
457            org.opencms.workplace.explorer.Messages.get().container(
458                org.opencms.workplace.explorer.Messages.GUI_INPUT_NAME_0));
459        relatedCol.setVisible(false);
460        relatedCol.setPrintable(false);
461        metadata.addColumn(relatedCol);
462    }
463
464    /**
465     * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata)
466     */
467    @Override
468    protected void setIndependentActions(CmsListMetadata metadata) {
469
470        /**
471         * Class to render a javascript driven detail action button.<p>
472         */
473        abstract class DetailsJsAction extends A_CmsListIndependentJsAction {
474
475            /**
476             * Default constructor.<p>
477             *
478             * @param id the action id
479             */
480            public DetailsJsAction(String id) {
481
482                super(id);
483            }
484
485            /**
486             * @see org.opencms.workplace.list.CmsListIndependentAction#buttonHtml(org.opencms.workplace.CmsWorkplace)
487             */
488            @Override
489            public String buttonHtml(CmsWorkplace wp) {
490
491                StringBuffer html = new StringBuffer(1024);
492                html.append("\t<span id='");
493                html.append(getId());
494                html.append("' class=\"link");
495                html.append("\"");
496                html.append(" onClick=\"");
497                html.append(resolveOnClic(wp));
498                html.append("\"");
499                html.append(">");
500                html.append("<img src='");
501                html.append(CmsWorkplace.getSkinUri());
502                html.append(getIconPath());
503                html.append("'");
504                html.append(" alt='");
505                html.append(getName().key(wp.getLocale()));
506                html.append("'");
507                html.append(" title='");
508                html.append(getName().key(wp.getLocale()));
509                html.append("'");
510                html.append(">");
511                html.append("&nbsp;");
512                html.append("<a href='#'>");
513                html.append(getName().key(wp.getLocale()));
514                html.append("</a>");
515                html.append("</span>");
516                return html.toString();
517            }
518        }
519
520        I_CmsListAction hideAction = new DetailsJsAction(LIST_DETAIL_RELATIONS_HIDE) {
521
522            /**
523             * @see org.opencms.workplace.list.A_CmsListIndependentJsAction#jsCode(CmsWorkplace)
524             */
525            @Override
526            public String jsCode(CmsWorkplace wp) {
527
528                return "javascript:showRelatedResources(false);";
529            }
530        };
531        hideAction.setIconPath(A_CmsListDialog.ICON_DETAILS_HIDE);
532        hideAction.setName(Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_HIDE_NAME_0));
533        hideAction.setHelpText(Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_HIDE_HELP_0));
534        metadata.addIndependentAction(hideAction);
535
536        I_CmsListAction showAction = new DetailsJsAction(LIST_DETAIL_RELATIONS_SHOW) {
537
538            /**
539             * @see org.opencms.workplace.list.A_CmsListIndependentJsAction#jsCode(CmsWorkplace)
540             */
541            @Override
542            public String jsCode(CmsWorkplace wp) {
543
544                return "javascript:showRelatedResources(true);";
545            }
546        };
547        showAction.setIconPath(A_CmsListDialog.ICON_DETAILS_SHOW);
548        showAction.setName(Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_SHOW_NAME_0));
549        showAction.setHelpText(Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_SHOW_HELP_0));
550        metadata.addIndependentAction(showAction);
551
552        // create list item detail
553        CmsListItemDetails relationsDetails = new CmsListItemDetails(LIST_DETAIL_RELATIONS) {
554
555            /**
556             * @see org.opencms.workplace.list.CmsListItemDetails#getAction()
557             */
558            @Override
559            public I_CmsListAction getAction() {
560
561                return new CmsListIndependentAction("hide") {
562
563                    /**
564                     * @see org.opencms.workplace.list.CmsListIndependentAction#buttonHtml(org.opencms.workplace.CmsWorkplace)
565                     */
566                    @Override
567                    public String buttonHtml(CmsWorkplace wp) {
568
569                        return "";
570                    }
571                };
572            }
573        };
574        relationsDetails.setAtColumn(LIST_COLUMN_NAME);
575        relationsDetails.setVisible(true);
576        relationsDetails.setFormatter(new I_CmsListFormatter() {
577
578            public String format(Object data, Locale locale) {
579
580                if (!(data instanceof List)) {
581                    return new DataFormatException().getLocalizedMessage();
582                }
583                StringBuffer html = new StringBuffer(512);
584                @SuppressWarnings("unchecked")
585                Iterator<String> itResourceNames = ((List<String>)data).iterator();
586                if (itResourceNames.hasNext()) {
587                    html.append("<table border='0' cellspacing='0' cellpadding='0'>\n");
588                }
589                while (itResourceNames.hasNext()) {
590                    String resName = itResourceNames.next();
591                    html.append("\t<tr>\n");
592                    html.append("\t\t<td width='150' align='right' class='listdetailhead'>\n");
593                    html.append("\t\t\t");
594                    if (resName.endsWith("*")) {
595                        // resource is not lockable, and will not be published
596                        resName = resName.substring(0, resName.length() - 1);
597                        html.append("<font color='red' />");
598                        html.append(
599                            Messages.get().getBundle(locale).key(
600                                Messages.GUI_PUBLISH_DETAIL_RELATED_LOCKED_RESOURCE_0));
601                        html.append("</font/>");
602                    } else if (resName.endsWith("!")) {
603                        // resource will be published
604                        resName = resName.substring(0, resName.length() - 1);
605                        html.append(
606                            Messages.get().getBundle(locale).key(Messages.GUI_PUBLISH_DETAIL_RELATED_RESOURCE_0));
607                    } else if (resName.endsWith("$")) {
608                        // reverse reference
609                        resName = resName.substring(0, resName.length() - 1);
610                        html.append(
611                            Messages.get().getBundle(locale).key(Messages.GUI_PUBLISH_DETAIL_REVERSE_REFERENCE_0));
612                    } else {
613                        // resource will not be published
614                        html.append("<font color='red' />");
615                        html.append(
616                            Messages.get().getBundle(locale).key(Messages.GUI_PUBLISH_DETAIL_RELATED_RESOURCE_NO_0));
617                        html.append("</font/>");
618                    }
619                    html.append("&nbsp;:&nbsp;\n");
620                    html.append("\t\t</td>\n");
621                    html.append("\t\t<td class='listdetailitem' style='white-space:normal;'>\n");
622                    html.append("\t\t\t");
623                    html.append(resName);
624                    html.append("\n");
625                    html.append("\t\t</td>\n");
626                    html.append("\t</tr>\n");
627                }
628                if (html.length() > 0) {
629                    html.append("</table>\n");
630                }
631                return html.toString();
632            }
633
634        });
635        relationsDetails.setShowActionName(
636            Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_SHOW_NAME_0));
637        relationsDetails.setShowActionHelpText(
638            Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_SHOW_HELP_0));
639        relationsDetails.setHideActionName(
640            Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_HIDE_NAME_0));
641        relationsDetails.setHideActionHelpText(
642            Messages.get().container(Messages.GUI_PUBLISH_RELATED_RESOURCES_DETAIL_HIDE_HELP_0));
643
644        // add resources info item detail to meta data
645        metadata.addItemDetails(relationsDetails);
646    }
647
648    /**
649     * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata)
650     */
651    @Override
652    protected void setMultiActions(CmsListMetadata metadata) {
653
654        // no LMAs, and remove default search action
655        metadata.setSearchAction(null);
656    }
657}