KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > opencms > validation > CmsXmlDocumentLinkValidator


1 /*
2  * File : $Source: /usr/local/cvs/opencms/src/org/opencms/validation/CmsXmlDocumentLinkValidator.java,v $
3  * Date : $Date: 2006/10/04 07:35:21 $
4  * Version: $Revision: 1.10 $
5  *
6  * This library is part of OpenCms -
7  * the Open Source Content Mananagement System
8  *
9  * Copyright (c) 2005 Alkacon Software GmbH (http://www.alkacon.com)
10  *
11  * This library is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU Lesser General Public
13  * License as published by the Free Software Foundation; either
14  * version 2.1 of the License, or (at your option) any later version.
15  *
16  * This library is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * Lesser General Public License for more details.
20  *
21  * For further information about Alkacon Software GmbH, please see the
22  * company website: http://www.alkacon.com
23  *
24  * For further information about OpenCms, please see the
25  * project website: http://www.opencms.org
26  *
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30  */

31
32 package org.opencms.validation;
33
34 import org.opencms.db.CmsDbContext;
35 import org.opencms.db.CmsDbUtil;
36 import org.opencms.db.CmsDriverManager;
37 import org.opencms.file.CmsObject;
38 import org.opencms.file.CmsProject;
39 import org.opencms.file.CmsResource;
40 import org.opencms.file.types.I_CmsResourceType;
41 import org.opencms.main.CmsException;
42 import org.opencms.main.CmsLog;
43 import org.opencms.main.OpenCms;
44 import org.opencms.report.CmsShellReport;
45 import org.opencms.report.I_CmsReport;
46
47 import java.util.ArrayList JavaDoc;
48 import java.util.HashMap JavaDoc;
49 import java.util.Iterator JavaDoc;
50 import java.util.List JavaDoc;
51 import java.util.Map JavaDoc;
52
53 import org.apache.commons.logging.Log;
54
55 /**
56  * Validates HTML links in the (body) content of Cms resources in the OpenCms VFS. HTML links are
57  * considered as href attribs in anchor tags and src attribs in image tags.<p>
58  *
59  * Validating links means to answer the question, whether we would have broken links in the
60  * online project if a file or a list of files would get published. External links to targets
61  * outside the OpenCms VFS don't get validated.<p>
62  *
63  * Objects using the CmsHtmlLinkValidator are responsible to handle detected broken links.<p>
64  *
65  * @author Thomas Weckert
66  *
67  * @version $Revision: 1.10 $
68  *
69  * @since 6.0.0
70  */

71 public class CmsXmlDocumentLinkValidator {
72
73     /** The log object for this class. */
74     private static final Log LOG = CmsLog.getLog(CmsXmlDocumentLinkValidator.class);
75
76     /**
77      * The driver manager.<p>
78      */

79     protected CmsDriverManager m_driverManager;
80
81     /**
82      * Default constructor.<p>
83      *
84      * @param driverManager The Cms driver manager
85      */

86     public CmsXmlDocumentLinkValidator(CmsDriverManager driverManager) {
87
88         m_driverManager = driverManager;
89     }
90
91     /**
92      * Validates HTML links (hrefs and img tags) in the (body) content of the specified list of Cms resources.<p>
93      *
94      * The result is printed to a shell report.<p>
95      *
96      * @param cms the current user's Cms object the current request context
97      * @param offlineResources a list of offline Cms resources
98      * @return a Map with Lists of invalid hrefs keyed by resource names
99      */

100     public Map JavaDoc validateResources(CmsObject cms, List JavaDoc offlineResources) {
101
102         return validateResources(cms, offlineResources, new CmsShellReport(cms.getRequestContext().getLocale()));
103     }
104
105     /**
106      * Validates HTML links (hrefs and img tags) in the (body) content of the specified list of Cms resources.<p>
107      *
108      * The result is printed to the given report.<p>
109      *
110      * @param cms the current user's Cms object
111      * @param offlineResources a list of offline Cms resources
112      * @param report an instance of I_CmsReport to print messages
113      * @return a map with lists of invalid links keyed by resource names
114      */

115     public Map JavaDoc validateResources(CmsObject cms, List JavaDoc offlineResources, I_CmsReport report) {
116
117         CmsResource resource = null;
118         List JavaDoc brokenLinks = null;
119         Map JavaDoc offlineFilesLookup = null;
120         List JavaDoc links = null;
121         List JavaDoc validatableResources = null;
122         Map JavaDoc invalidResources = new HashMap JavaDoc();
123         String JavaDoc resourceName = null;
124         int i = CmsDbUtil.UNKNOWN_ID, j = CmsDbUtil.UNKNOWN_ID;
125         I_CmsResourceType resourceType = null;
126         boolean foundBrokenLinks = false;
127
128         report.println(Messages.get().container(Messages.RPT_HTMLLINK_VALIDATOR_BEGIN_0), I_CmsReport.FORMAT_HEADLINE);
129
130         // populate a lookup map with the offline resources that
131
// actually get published keyed by their resource names.
132
// second, resources that don't get validated are ignored.
133
offlineFilesLookup = new HashMap JavaDoc();
134         validatableResources = new ArrayList JavaDoc();
135         for (i = 0; i < offlineResources.size(); i++) {
136             resource = (CmsResource)offlineResources.get(i);
137             offlineFilesLookup.put(resource.getRootPath(), resource);
138
139             try {
140                 resourceType = OpenCms.getResourceManager().getResourceType(resource.getTypeId());
141                 if ((resourceType instanceof I_CmsXmlDocumentLinkValidatable)
142                     && (resource.getState() != CmsResource.STATE_DELETED)) {
143                     // don't validate links on deleted resources
144
validatableResources.add(resource);
145                 }
146             } catch (CmsException e) {
147                 LOG.error(Messages.get().getBundle().key(Messages.LOG_RETRIEVAL_RESOURCE_1, resourceName), e);
148             }
149         }
150
151         foundBrokenLinks = false;
152         for (i = 0, j = validatableResources.size(); i < j; i++) {
153             try {
154                 brokenLinks = null;
155                 resource = (CmsResource)validatableResources.get(i);
156                 resourceName = resource.getRootPath();
157                 resourceType = OpenCms.getResourceManager().getResourceType(resource.getTypeId());
158
159                 report.print(org.opencms.report.Messages.get().container(
160                     org.opencms.report.Messages.RPT_SUCCESSION_2,
161                     new Integer JavaDoc(i + 1),
162                     new Integer JavaDoc(j)), I_CmsReport.FORMAT_NOTE);
163                 report.print(Messages.get().container(Messages.RPT_HTMLLINK_VALIDATING_0), I_CmsReport.FORMAT_NOTE);
164                 report.print(org.opencms.report.Messages.get().container(
165                     org.opencms.report.Messages.RPT_ARGUMENT_1,
166                     cms.getRequestContext().removeSiteRoot(resourceName)));
167                 report.print(org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_DOTS_0));
168
169                 links = ((I_CmsXmlDocumentLinkValidatable)resourceType).findLinks(cms, resource);
170
171                 if (links.size() > 0) {
172                     brokenLinks = validateLinks(links, offlineFilesLookup);
173                 }
174
175                 if (brokenLinks != null && brokenLinks.size() > 0) {
176                     // the resource contains broken links
177
invalidResources.put(resourceName, brokenLinks);
178                     foundBrokenLinks = true;
179                     report.println(
180                         Messages.get().container(Messages.RPT_HTMLLINK_FOUND_BROKEN_LINKS_0),
181                         I_CmsReport.FORMAT_WARNING);
182                 } else {
183                     // the resource contains *NO* broken links
184
report.println(
185                         org.opencms.report.Messages.get().container(org.opencms.report.Messages.RPT_OK_0),
186                         I_CmsReport.FORMAT_OK);
187                 }
188             } catch (CmsException e) {
189                 LOG.error(Messages.get().getBundle().key(Messages.LOG_LINK_SEARCH_1, resourceName), e);
190             }
191         }
192
193         if (foundBrokenLinks) {
194             // print a summary if we found broken links in the validated resources
195
report.println(
196                 Messages.get().container(Messages.RPT_BROKEN_LINKS_SUMMARY_BEGIN_0),
197                 I_CmsReport.FORMAT_HEADLINE);
198
199             Iterator JavaDoc outer = invalidResources.keySet().iterator();
200             while (outer.hasNext()) {
201                 resourceName = (String JavaDoc)outer.next();
202                 brokenLinks = (List JavaDoc)invalidResources.get(resourceName);
203
204                 report.println(
205                     Messages.get().container(Messages.RPT_BROKEN_LINKS_IN_1, resourceName),
206                     I_CmsReport.FORMAT_WARNING);
207                 Iterator JavaDoc inner = brokenLinks.iterator();
208                 while (inner.hasNext()) {
209                     report.print(org.opencms.report.Messages.get().container(
210                         org.opencms.report.Messages.RPT_ARGUMENT_1,
211                         inner.next()), I_CmsReport.FORMAT_WARNING);
212                 }
213                 report.println();
214             }
215
216             report.println(
217                 Messages.get().container(Messages.RPT_BROKEN_LINKS_SUMMARY_END_0),
218                 I_CmsReport.FORMAT_HEADLINE);
219             report.println(Messages.get().container(Messages.RPT_HTMLLINK_VALIDATOR_ERROR_0), I_CmsReport.FORMAT_ERROR);
220         }
221
222         report.println(Messages.get().container(Messages.RPT_HTMLLINK_VALIDATOR_END_0), I_CmsReport.FORMAT_HEADLINE);
223
224         return invalidResources;
225     }
226
227     /**
228      * @see java.lang.Object#finalize()
229      */

230     protected void finalize() throws Throwable JavaDoc {
231
232         try {
233             m_driverManager = null;
234         } catch (Throwable JavaDoc t) {
235             // ignore
236
}
237
238         super.finalize();
239     }
240
241     /**
242      * Validates the URIs in the specified link list.<p>
243      *
244      * @param links a list of URIs inside a CmsResource
245      * @param offlineFileLookup a map for faster lookup with all (offline) resources that get actually published keyed by their resource names (including the site root)
246      * @return a list with the broken links in the specified link list, or an empty list if no broken links were found
247      */

248     protected List JavaDoc validateLinks(List JavaDoc links, Map JavaDoc offlineFileLookup) {
249
250         List JavaDoc brokenLinks = new ArrayList JavaDoc();
251         String JavaDoc link = null;
252         boolean isValidLink = true;
253         CmsResource unpublishedResource = null;
254         List JavaDoc validatedLinks = new ArrayList JavaDoc();
255
256         Iterator JavaDoc i = links.iterator();
257         while (i.hasNext()) {
258             link = ((String JavaDoc)i.next()).trim();
259             isValidLink = true;
260
261             if (validatedLinks.contains(link) || "".equals(link)) {
262                 // skip links that are already validated or empty
263
continue;
264             }
265
266             // the link is valid...
267

268             try {
269                 // ... if the linked resource exists in the online project
270
m_driverManager.getVfsDriver().readResource(
271                     new CmsDbContext(),
272                     CmsProject.ONLINE_PROJECT_ID,
273                     link,
274                     true);
275
276                 // ... and if the linked resource in the online project won't get deleted if it gets actually published
277
if (offlineFileLookup.containsKey(link)) {
278                     unpublishedResource = (CmsResource)offlineFileLookup.get(link);
279
280                     if (unpublishedResource.getState() == CmsResource.STATE_DELETED) {
281                         isValidLink = false;
282                     }
283                 }
284             } catch (CmsException e) {
285                 // ... or if the linked resource is a resource that gets actually published
286
if (!offlineFileLookup.containsKey(link)) {
287                     isValidLink = false;
288                 }
289             }
290
291             if (!isValidLink) {
292                 brokenLinks.add(link);
293             }
294
295             validatedLinks.add(link);
296         }
297
298         return brokenLinks;
299     }
300 }
Popular Tags