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.apps.linkvalidation;
029
030import org.opencms.file.CmsObject;
031import org.opencms.file.CmsPropertyDefinition;
032import org.opencms.file.CmsResource;
033import org.opencms.main.CmsException;
034import org.opencms.main.CmsLog;
035import org.opencms.main.OpenCms;
036import org.opencms.relations.CmsInternalLinksValidator;
037import org.opencms.relations.CmsRelation;
038import org.opencms.ui.A_CmsUI;
039import org.opencms.ui.CmsVaadinUtils;
040import org.opencms.ui.apps.A_CmsWorkplaceApp;
041import org.opencms.ui.apps.CmsFileExplorer;
042import org.opencms.ui.apps.Messages;
043import org.opencms.ui.components.CmsBasicDialog;
044import org.opencms.ui.components.CmsBasicDialog.DialogWidth;
045import org.opencms.ui.components.CmsFileTable;
046import org.opencms.ui.components.CmsResourceTableProperty;
047import org.opencms.util.CmsStringUtil;
048import org.opencms.util.CmsUUID;
049
050import java.util.ArrayList;
051import java.util.Iterator;
052import java.util.LinkedHashMap;
053import java.util.List;
054import java.util.Map;
055
056import org.apache.commons.logging.Log;
057
058import com.vaadin.server.Sizeable.Unit;
059import com.vaadin.shared.MouseEventDetails.MouseButton;
060import com.vaadin.ui.Component;
061import com.vaadin.ui.HorizontalSplitPanel;
062import com.vaadin.ui.Window;
063import com.vaadin.v7.event.ItemClickEvent;
064import com.vaadin.v7.event.ItemClickEvent.ItemClickListener;
065import com.vaadin.v7.ui.VerticalLayout;
066
067/**
068 * Class for the Link validation app.<p>
069 */
070public class CmsLinkValidationApp extends A_CmsWorkplaceApp {
071
072    /**
073     * Validator.<p>
074     */
075    public class InternalValidator extends A_CmsLinkValidator {
076
077        /**Link validator. */
078        CmsInternalLinksValidator validator;
079
080        /**
081         * @see org.opencms.ui.apps.linkvalidation.A_CmsLinkValidator#failedResources(java.util.List)
082         */
083        @Override
084        public List<CmsResource> failedResources(List<String> resources) {
085
086            validator = new CmsInternalLinksValidator(A_CmsUI.getCmsObject(), resources);
087            return validator.getResourcesWithBrokenLinks();
088        }
089
090        /**
091         * @see org.opencms.ui.apps.linkvalidation.A_CmsLinkValidator#failMessage(org.opencms.file.CmsResource)
092         */
093        @Override
094        public String failMessage(CmsResource resource) {
095
096            String res = "";
097            List<CmsRelation> brokenLinks = validator.getBrokenLinksForResource(resource.getRootPath());
098            if (brokenLinks != null) {
099                Iterator<CmsRelation> j = brokenLinks.iterator();
100                while (j.hasNext()) {
101                    res += j.next().getTargetPath() + ", ";
102                }
103            }
104            return res.substring(0, res.length() - 2);
105        }
106
107        /**
108         * @see org.opencms.ui.apps.linkvalidation.A_CmsLinkValidator#getClickListener()
109         */
110        @Override
111        public ItemClickListener getClickListener() {
112
113            return new ItemClickListener() {
114
115                private static final long serialVersionUID = -7729459896374968941L;
116
117                public void itemClick(ItemClickEvent event) {
118
119                    if (event.getButton().equals(MouseButton.RIGHT)) {
120                        return;
121                    }
122                    if (!property.equals(event.getPropertyId())) {
123                        return;
124                    }
125                    try {
126                        CmsObject cms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
127                        cms.getRequestContext().setSiteRoot("");
128                        CmsResource resource = cms.readResource(new CmsUUID((String)event.getItemId()));
129                        Window window = CmsBasicDialog.prepareWindow(DialogWidth.wide);
130                        window.setCaption(CmsVaadinUtils.getMessageText(getCaptionKey()));
131                        window.setContent(
132                            CmsResourceListDialog.forNonExistingPaths(getBrokenLinkedResources(resource)));
133                        A_CmsUI.get().addWindow(window);
134                    } catch (CmsException e) {
135                        LOG.error("Unable to show detail resources", e);
136                    }
137                }
138
139            };
140        }
141
142        /**
143         * @see org.opencms.ui.apps.linkvalidation.A_CmsLinkValidator#getPropertyName()
144         */
145        @Override
146        public String getPropertyName() {
147
148            return "BrokenLinks";
149        }
150
151        /**
152         * @see org.opencms.ui.apps.linkvalidation.A_CmsLinkValidator#getTableProperties()
153         */
154        @Override
155        public Map<CmsResourceTableProperty, Integer> getTableProperties() {
156
157            property = new CmsResourceTableProperty(
158                getPropertyName(),
159                String.class,
160                "",
161                org.opencms.ui.apps.Messages.GUI_LINKVALIDATION_BROKENLINKS_DETAIL_LINKS_NAME_0,
162                true,
163                0,
164                200);
165            Map<CmsResourceTableProperty, Integer> res = new LinkedHashMap<CmsResourceTableProperty, Integer>(
166                CmsFileTable.DEFAULT_TABLE_PROPERTIES);
167            res.put(property, Integer.valueOf(0));
168            return res;
169        }
170
171        /**
172         * Returns the caption key.<p>
173         *
174         * @return key for caption
175         */
176        String getCaptionKey() {
177
178            return org.opencms.ui.apps.Messages.GUI_LINKVALIDATION_BROKENLINKS_DETAIL_LINKS_NAME_0;
179        }
180
181        private List<String> getBrokenLinkedResources(CmsResource resource) {
182
183            List<String> res = new ArrayList<String>();
184            List<CmsRelation> brokenLinks = validator.getBrokenLinksForResource(resource.getRootPath());
185            if (brokenLinks != null) {
186                Iterator<CmsRelation> j = brokenLinks.iterator();
187                while (j.hasNext()) {
188
189                    res.add(j.next().getTargetPath());
190
191                }
192            }
193            return res;
194        }
195
196        /**
197         * get string to show for broken link.<p>
198         *
199         * 1:1 the same like old workplace app<p>
200         *
201         * @param rootPath to get Broken links for.
202         * @return broken link string
203         */
204        private String getBrokenLinkString(String rootPath) {
205
206            String ret = "";
207
208            CmsObject rootCms;
209            try {
210                rootCms = OpenCms.initCmsObject(A_CmsUI.getCmsObject());
211
212                rootCms.getRequestContext().setSiteRoot("");
213
214                String siteRoot = OpenCms.getSiteManager().getSiteRoot(rootPath);
215                String siteName = siteRoot;
216                if (siteRoot != null) {
217                    try {
218
219                        siteName = rootCms.readPropertyObject(
220                            siteRoot,
221                            CmsPropertyDefinition.PROPERTY_TITLE,
222                            false).getValue(siteRoot);
223                    } catch (CmsException e) {
224                        siteName = siteRoot;
225                    }
226                    ret = rootPath.substring(siteRoot.length());
227                } else {
228                    siteName = "/";
229                }
230                if (!A_CmsUI.getCmsObject().getRequestContext().getSiteRoot().equals(siteRoot)) {
231                    ret = CmsVaadinUtils.getMessageText(
232                        org.opencms.workplace.commons.Messages.GUI_DELETE_SITE_RELATION_2,
233                        new Object[] {siteName, rootPath});
234                }
235            } catch (CmsException e1) {
236                //
237            }
238            return ret;
239        }
240
241    }
242
243    /** The log object for this class. */
244    static final Log LOG = CmsLog.getLog(CmsLinkValidationApp.class);
245
246    /**
247     * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getBreadCrumbForState(java.lang.String)
248     */
249    @Override
250    protected LinkedHashMap<String, String> getBreadCrumbForState(String state) {
251
252        LinkedHashMap<String, String> crumbs = new LinkedHashMap<String, String>();
253
254        //Main page.
255        if (CmsStringUtil.isEmptyOrWhitespaceOnly(state)) {
256            crumbs.put("", CmsVaadinUtils.getMessageText(Messages.GUI_LINKVALIDATION_ADMIN_TOOL_NAME_SHORT_0));
257            return crumbs;
258        }
259        return new LinkedHashMap<String, String>(); //size==1 & state was not empty -> state doesn't match to known path
260    }
261
262    /**
263     * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getComponentForState(java.lang.String)
264     */
265    @Override
266    protected Component getComponentForState(String state) {
267
268        if (state.isEmpty()) {
269            m_rootLayout.setMainHeightFull(true);
270            return getInternalComponent();
271        }
272        return null;
273    }
274
275    /**
276     * @see org.opencms.ui.apps.A_CmsWorkplaceApp#getSubNavEntries(java.lang.String)
277     */
278    @Override
279    protected List<NavEntry> getSubNavEntries(String state) {
280
281        return null;
282    }
283
284    /**
285     * Returns the component for the internal link validation.<p>
286     *
287     * @return vaadin component
288     */
289    private HorizontalSplitPanel getInternalComponent() {
290
291        m_rootLayout.setMainHeightFull(true);
292        HorizontalSplitPanel sp = new HorizontalSplitPanel();
293        sp.setSizeFull();
294        VerticalLayout result = new VerticalLayout();
295        result.setSizeFull();
296        VerticalLayout intro = CmsVaadinUtils.getInfoLayout(Messages.GUI_LINKVALIDATION_INTRODUCTION_0);
297        VerticalLayout nullResult = CmsVaadinUtils.getInfoLayout(Messages.GUI_LINKVALIDATION_NO_BROKEN_LINKS_0);
298
299        nullResult.setVisible(false);
300        CmsLinkValidationInternalTable table = new CmsLinkValidationInternalTable(
301            intro,
302            nullResult,
303            new InternalValidator());
304        table.setVisible(false);
305        table.setSizeFull();
306        table.setWidth("100%");
307
308        result.addComponent(table);
309        result.addComponent(intro);
310        result.addComponent(nullResult);
311
312        VerticalLayout leftCol = new VerticalLayout();
313        leftCol.setSizeFull();
314        CmsInternalResources resources = new CmsInternalResources(table);
315        leftCol.addComponent(resources);
316
317        leftCol.setExpandRatio(resources, 1);
318        sp.setFirstComponent(leftCol);
319        sp.setSecondComponent(result);
320        sp.setSplitPosition(CmsFileExplorer.LAYOUT_SPLIT_POSITION, Unit.PIXELS);
321        return sp;
322    }
323}