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.CmsUserSettings;
031import org.opencms.file.CmsResource;
032import org.opencms.jsp.CmsJspActionElement;
033import org.opencms.main.CmsException;
034import org.opencms.main.OpenCms;
035import org.opencms.relations.CmsRelation;
036import org.opencms.relations.CmsRelationDeleteValidator;
037import org.opencms.relations.CmsRelationValidatorInfoEntry;
038import org.opencms.util.CmsStringUtil;
039import org.opencms.workplace.CmsWorkplace;
040import org.opencms.workplace.explorer.CmsResourceUtil;
041import org.opencms.workplace.list.A_CmsListDialog;
042import org.opencms.workplace.list.A_CmsListExplorerDialog;
043import org.opencms.workplace.list.A_CmsListIndependentJsAction;
044import org.opencms.workplace.list.CmsListColumnDefinition;
045import org.opencms.workplace.list.CmsListIndependentAction;
046import org.opencms.workplace.list.CmsListItem;
047import org.opencms.workplace.list.CmsListItemDetails;
048import org.opencms.workplace.list.CmsListItemDetailsFormatter;
049import org.opencms.workplace.list.CmsListMetadata;
050import org.opencms.workplace.list.I_CmsListAction;
051import org.opencms.workplace.list.I_CmsListResourceCollector;
052
053import java.util.ArrayList;
054import java.util.Collections;
055import java.util.Iterator;
056import java.util.List;
057
058/**
059 * List for resources with links that could get broken after deletion.<p>
060 *
061 * @since 6.5.4
062 */
063public class CmsDeleteBrokenRelationsList extends A_CmsListExplorerDialog {
064
065    /** list action id constant. */
066    public static final String LIST_DETAIL_RELATIONS = "dr";
067
068    /** list action id constant. */
069    public static final String LIST_DETAIL_RELATIONS_PRINT = "drp";
070
071    /** list action id constant. */
072    public static final String LIST_DETAIL_RELATIONS_HIDE = "drh";
073
074    /** list action id constant. */
075    public static final String LIST_DETAIL_RELATIONS_SHOW = "drs";
076
077    /** list id constant. */
078    public static final String LIST_ID = "dbr";
079
080    /** The internal collector instance. */
081    private I_CmsListResourceCollector m_collector;
082
083    /** The broken relations validator object. */
084    private CmsRelationDeleteValidator m_validator;
085
086    /**
087     * Public constructor.<p>
088     *
089     * @param jsp an initialized JSP action element
090     * @param resources the list of resources to check
091     * @param includeSiblings if siblings should included
092     */
093    public CmsDeleteBrokenRelationsList(CmsJspActionElement jsp, List<String> resources, boolean includeSiblings) {
094
095        super(jsp, LIST_ID, Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_LIST_NAME_0));
096        String relativeTo = CmsResource.getParentFolder(resources.get(0));
097
098        m_validator = new CmsRelationDeleteValidator(getCms(), resources, includeSiblings);
099        List<String> resourceList = new ArrayList<String>(m_validator.keySet());
100        Collections.sort(resourceList);
101
102        m_collector = new CmsDeleteBrokenRelationsCollector(this, resourceList);
103
104        // prevent paging
105        getList().setMaxItemsPerPage(Integer.MAX_VALUE);
106
107        // set the right resource util parameters
108        CmsResourceUtil resUtil = getResourceUtil();
109        resUtil.setAbbrevLength(50);
110        resUtil.setRelativeTo(getCms().getRequestContext().addSiteRoot(relativeTo));
111        resUtil.setSiteMode(CmsResourceUtil.SITE_MODE_MATCHING);
112    }
113
114    /**
115     * @see org.opencms.workplace.list.A_CmsListDialog#executeListMultiActions()
116     */
117    @Override
118    public void executeListMultiActions() {
119
120        throwListUnsupportedActionException();
121    }
122
123    /**
124     * @see org.opencms.workplace.list.A_CmsListDialog#executeListSingleActions()
125     */
126    @Override
127    public void executeListSingleActions() {
128
129        throwListUnsupportedActionException();
130    }
131
132    /**
133     * @see org.opencms.workplace.list.A_CmsListExplorerDialog#getCollector()
134     */
135    @Override
136    public I_CmsListResourceCollector getCollector() {
137
138        return m_collector;
139    }
140
141    /**
142     * Returns the validator.<p>
143     *
144     * @return the validator
145     */
146    public CmsRelationDeleteValidator getValidator() {
147
148        return m_validator;
149    }
150
151    /**
152     * @see org.opencms.workplace.list.A_CmsListDialog#fillDetails(java.lang.String)
153     */
154    @Override
155    protected void fillDetails(String detailId) {
156
157        // get content
158        Iterator<CmsListItem> itResourceNames = getList().getAllContent().iterator();
159        while (itResourceNames.hasNext()) {
160            CmsListItem item = itResourceNames.next();
161            String resourceName = getResourceUtil(item).getResource().getRootPath();
162
163            StringBuffer html = new StringBuffer(128);
164            if (detailId.equals(LIST_DETAIL_RELATIONS) || detailId.equals(LIST_DETAIL_RELATIONS_PRINT)) {
165                // relations
166                CmsRelationValidatorInfoEntry infoEntry = m_validator.getInfoEntry(resourceName);
167                Iterator<CmsRelation> itRelations = infoEntry.getRelations().iterator();
168
169                // show all links that will get broken
170                while (itRelations.hasNext()) {
171                    CmsRelation relation = itRelations.next();
172                    String relationName = relation.getSourcePath();
173                    if (relationName.startsWith(infoEntry.getSiteRoot())) {
174                        // same site
175                        relationName = relationName.substring(infoEntry.getSiteRoot().length());
176                        if (detailId.equals(LIST_DETAIL_RELATIONS)) {
177                            relationName = CmsStringUtil.formatResourceName(relationName, 50);
178                        }
179                    } else {
180                        // other site
181                        String site = OpenCms.getSiteManager().getSiteRoot(relationName);
182                        String siteName = site;
183                        if (site != null) {
184                            relationName = relationName.substring(site.length());
185                            siteName = OpenCms.getSiteManager().getSiteForSiteRoot(site).getTitle();
186                        } else {
187                            siteName = "/";
188                        }
189                        if (detailId.equals(LIST_DETAIL_RELATIONS)) {
190                            relationName = CmsStringUtil.formatResourceName(relationName, 50);
191                        }
192                        relationName = key(Messages.GUI_DELETE_SITE_RELATION_2, new Object[] {siteName, relationName});
193                    }
194                    html.append(relationName);
195                    html.append("&nbsp;<span style='color: #666666;'>(");
196                    html.append(relation.getType().getLocalizedName(getMessages()));
197                    html.append(")</span>");
198                    if (itRelations.hasNext()) {
199                        html.append("<br>");
200                    }
201                    html.append("\n");
202                }
203            } else {
204                continue;
205            }
206            item.set(detailId, html.toString());
207        }
208    }
209
210    /**
211     * @see org.opencms.workplace.list.A_CmsListExplorerDialog#getListItems()
212     */
213    @Override
214    protected List<CmsListItem> getListItems() throws CmsException {
215
216        String storedSiteRoot = getCms().getRequestContext().getSiteRoot();
217        try {
218            getCms().getRequestContext().setSiteRoot("");
219            return super.getListItems();
220        } finally {
221            getCms().getRequestContext().setSiteRoot(storedSiteRoot);
222        }
223    }
224
225    /**
226     * @see org.opencms.workplace.list.A_CmsListExplorerDialog#isColumnVisible(int)
227     */
228    @Override
229    protected boolean isColumnVisible(int colFlag) {
230
231        boolean isVisible = (colFlag == CmsUserSettings.FILELIST_TITLE);
232        isVisible = isVisible || (colFlag == LIST_COLUMN_TYPEICON.hashCode());
233        isVisible = isVisible || (colFlag == LIST_COLUMN_LOCKICON.hashCode());
234        isVisible = isVisible || (colFlag == LIST_COLUMN_PROJSTATEICON.hashCode());
235        isVisible = isVisible || (colFlag == LIST_COLUMN_NAME.hashCode());
236        isVisible = isVisible
237            || ((colFlag == LIST_COLUMN_SITE.hashCode()) && (OpenCms.getSiteManager().getSites().size() > 1));
238        return isVisible;
239    }
240
241    /**
242     * @see org.opencms.workplace.list.A_CmsListDialog#setColumns(org.opencms.workplace.list.CmsListMetadata)
243     */
244    @Override
245    protected void setColumns(CmsListMetadata metadata) {
246
247        super.setColumns(metadata);
248
249        Iterator<CmsListColumnDefinition> it = metadata.getColumnDefinitions().iterator();
250        while (it.hasNext()) {
251            CmsListColumnDefinition colDefinition = it.next();
252            colDefinition.setSorteable(false);
253            if (colDefinition.getId().equals(LIST_COLUMN_NAME)) {
254                colDefinition.removeDefaultAction(LIST_DEFACTION_OPEN);
255                colDefinition.setWidth("60%");
256            }
257        }
258    }
259
260    /**
261     * @see org.opencms.workplace.list.A_CmsListDialog#setIndependentActions(org.opencms.workplace.list.CmsListMetadata)
262     */
263    @Override
264    protected void setIndependentActions(CmsListMetadata metadata) {
265
266        /**
267         * Class to render a javascript driven detail action button.<p>
268         */
269        abstract class DetailsJsAction extends A_CmsListIndependentJsAction {
270
271            /**
272             * Default constructor.<p>
273             *
274             * @param id the action id
275             */
276            public DetailsJsAction(String id) {
277
278                super(id);
279            }
280
281            /**
282             * @see org.opencms.workplace.list.CmsListIndependentAction#buttonHtml(org.opencms.workplace.CmsWorkplace)
283             */
284            @Override
285            public String buttonHtml(CmsWorkplace wp) {
286
287                StringBuffer html = new StringBuffer(1024);
288                html.append("\t<span id='");
289                html.append(getId());
290                html.append("' class=\"link");
291                html.append("\"");
292                html.append(" onClick=\"");
293                html.append(resolveOnClic(wp));
294                html.append("\"");
295                html.append(">");
296                html.append("<img src='");
297                html.append(CmsWorkplace.getSkinUri());
298                html.append(getIconPath());
299                html.append("'");
300                html.append(" alt='");
301                html.append(getName().key(wp.getLocale()));
302                html.append("'");
303                html.append(" title='");
304                html.append(getName().key(wp.getLocale()));
305                html.append("'");
306                html.append(">");
307                html.append("&nbsp;");
308                html.append("<a href='#'>");
309                html.append(getName().key(wp.getLocale()));
310                html.append("</a>");
311                html.append("</span>");
312                return html.toString();
313            }
314        }
315
316        I_CmsListAction hideAction = new DetailsJsAction(LIST_DETAIL_RELATIONS_HIDE) {
317
318            /**
319             * @see org.opencms.workplace.list.A_CmsListIndependentJsAction#jsCode(CmsWorkplace)
320             */
321            @Override
322            public String jsCode(CmsWorkplace wp) {
323
324                return "javascript:showBrokenLinks(false);";
325            }
326        };
327        hideAction.setIconPath(A_CmsListDialog.ICON_DETAILS_HIDE);
328        hideAction.setName(Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_HIDE_RELATIONS_NAME_0));
329        hideAction.setHelpText(
330            Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_HIDE_RELATIONS_HELP_0));
331        metadata.addIndependentAction(hideAction);
332
333        I_CmsListAction showAction = new DetailsJsAction(LIST_DETAIL_RELATIONS_SHOW) {
334
335            /**
336             * @see org.opencms.workplace.list.A_CmsListIndependentJsAction#jsCode(CmsWorkplace)
337             */
338            @Override
339            public String jsCode(CmsWorkplace wp) {
340
341                return "javascript:showBrokenLinks(true);";
342            }
343        };
344        showAction.setIconPath(A_CmsListDialog.ICON_DETAILS_SHOW);
345        showAction.setName(Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_SHOW_RELATIONS_NAME_0));
346        showAction.setHelpText(
347            Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_SHOW_RELATIONS_HELP_0));
348        metadata.addIndependentAction(showAction);
349
350        // create list item detail
351        CmsListItemDetails relationsDetails = new CmsListItemDetails(LIST_DETAIL_RELATIONS) {
352
353            /**
354             * @see org.opencms.workplace.list.CmsListItemDetails#getAction()
355             */
356            @Override
357            public I_CmsListAction getAction() {
358
359                return new CmsListIndependentAction("hide") {
360
361                    /**
362                     * @see org.opencms.workplace.list.CmsListIndependentAction#buttonHtml(org.opencms.workplace.CmsWorkplace)
363                     */
364                    @Override
365                    public String buttonHtml(CmsWorkplace wp) {
366
367                        return "";
368                    }
369                };
370            }
371        };
372        relationsDetails.setAtColumn(LIST_COLUMN_NAME);
373        relationsDetails.setVisible(true);
374        relationsDetails.setPrintable(false);
375        relationsDetails.setFormatter(
376            new CmsListItemDetailsFormatter(
377                Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_LABEL_RELATIONS_0)));
378        relationsDetails.setShowActionName(
379            Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_SHOW_RELATIONS_NAME_0));
380        relationsDetails.setShowActionHelpText(
381            Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_SHOW_RELATIONS_HELP_0));
382        relationsDetails.setHideActionName(
383            Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_HIDE_RELATIONS_NAME_0));
384        relationsDetails.setHideActionHelpText(
385            Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_DETAIL_HIDE_RELATIONS_HELP_0));
386
387        // add resources info item detail to meta data
388        metadata.addItemDetails(relationsDetails);
389
390        // create list item detail for print view
391        CmsListItemDetails relationsDetailsPrint = new CmsListItemDetails(LIST_DETAIL_RELATIONS_PRINT) {
392
393            /**
394             * @see org.opencms.workplace.list.CmsListItemDetails#getAction()
395             */
396            @Override
397            public I_CmsListAction getAction() {
398
399                return new CmsListIndependentAction("hide") {
400
401                    /**
402                     * @see org.opencms.workplace.list.CmsListIndependentAction#buttonHtml(org.opencms.workplace.CmsWorkplace)
403                     */
404                    @Override
405                    public String buttonHtml(CmsWorkplace wp) {
406
407                        return "";
408                    }
409                };
410            }
411        };
412        relationsDetailsPrint.setAtColumn(LIST_COLUMN_ROOT_PATH);
413        relationsDetailsPrint.setVisible(false);
414        relationsDetailsPrint.setPrintable(true);
415        relationsDetailsPrint.setFormatter(
416            new CmsListItemDetailsFormatter(
417                Messages.get().container(Messages.GUI_DELETE_BROKENRELATIONS_LABEL_RELATIONS_0)));
418
419        // add resources info item detail to meta data
420        metadata.addItemDetails(relationsDetailsPrint);
421    }
422
423    /**
424     * @see org.opencms.workplace.list.A_CmsListDialog#setMultiActions(org.opencms.workplace.list.CmsListMetadata)
425     */
426    @Override
427    protected void setMultiActions(CmsListMetadata metadata) {
428
429        // no LMAs, and remove default search action
430        metadata.setSearchAction(null);
431    }
432}