KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > ws > jaxme > js > util > LinkChecker


1 /*
2  * Copyright 2003,2004 The Apache Software Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15
16  */

17 package org.apache.ws.jaxme.js.util;
18
19 import java.io.BufferedInputStream JavaDoc;
20 import java.io.File JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.io.InputStream JavaDoc;
24 import java.io.InputStreamReader JavaDoc;
25 import java.net.MalformedURLException JavaDoc;
26 import java.net.URL JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Enumeration JavaDoc;
29 import java.util.HashMap JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.List JavaDoc;
32 import java.util.Map JavaDoc;
33
34 import javax.swing.text.MutableAttributeSet JavaDoc;
35 import javax.swing.text.html.HTML JavaDoc;
36 import javax.swing.text.html.HTMLEditorKit JavaDoc;
37 import javax.swing.text.html.parser.ParserDelegator JavaDoc;
38
39 import org.apache.ws.jaxme.logging.Logger;
40 import org.apache.ws.jaxme.logging.LoggerAccess;
41
42
43 /** <p>Basic implementation of a link checker for the JaxMe
44  * HTML distribution.</p>
45  *
46  * @author <a HREF="mailto:joe@ispsoft.de">Jochen Wiedmann</a>
47  */

48 public class LinkChecker {
49   Logger logger = LoggerAccess.getLogger(LinkChecker.class);
50   private Map JavaDoc urls = new HashMap JavaDoc();
51   private Map JavaDoc checkedUrls = new HashMap JavaDoc();
52   private int severity = Event.ERROR;
53   private String JavaDoc proxyHost;
54   private String JavaDoc proxyPort;
55   private boolean haveErrors;
56
57   private class Event {
58     public static final int SUCCESS = 0;
59     public static final int WARNING = 1;
60     public static final int ERROR = 2;
61     int mySeverity;
62     private URL JavaDoc url;
63     private int pos = -1;
64     private String JavaDoc msg;
65     private Event(int pSeverity, URL JavaDoc pURL, int pPos, String JavaDoc pMsg) {
66       mySeverity = pSeverity;
67       url = pURL;
68       pos = pPos;
69       msg = pMsg;
70     }
71     public String JavaDoc getMsg() {
72       return msg;
73     }
74     public String JavaDoc toString() {
75       StringBuffer JavaDoc result = new StringBuffer JavaDoc();
76       if (mySeverity == SUCCESS) {
77         result.append("SUCCESS");
78       } else if (mySeverity == WARNING) {
79         result.append("WARNING");
80       } else {
81         result.append(" ERROR");
82       }
83       result.append(" at ").append(url);
84       if (pos != -1) {
85         result.append(", char ").append(pos);
86       }
87       result.append(": ").append(getMsg());
88       return result.toString();
89     }
90   }
91
92   private class RefEvent extends Event {
93     private URL JavaDoc referencedURL;
94     private RefEvent(int pSeverity, URL JavaDoc pURL, URL JavaDoc pRefURL, int pPos, String JavaDoc pMsg) {
95       super(pSeverity, pRefURL, pPos, pMsg);
96       referencedURL = pURL;
97     }
98     public String JavaDoc getMsg() {
99       return "Failed to reference " + referencedURL + ": " + super.getMsg();
100     }
101   }
102
103   private class CheckedURL {
104     URL JavaDoc url;
105     URL JavaDoc referencingURL;
106     int referencingPos;
107     InputStream JavaDoc stream;
108     boolean checkExistsOnly;
109     boolean isExtern;
110     private List JavaDoc anchors;
111     private List JavaDoc refAnchors;
112
113     private class AnchorReference {
114       String JavaDoc name;
115       URL JavaDoc ref;
116       int pos;
117     }
118
119     private CheckedURL(URL JavaDoc pURL, URL JavaDoc pRefURL, int pPos) {
120       referencingURL = pRefURL;
121       referencingPos = pPos;
122       String JavaDoc ref = pURL.getRef();
123       String JavaDoc anchor = null;
124       if (ref != null) {
125         String JavaDoc s = pURL.toString();
126         try {
127           if (s.endsWith("#" + ref)) {
128             pURL = new URL JavaDoc(s.substring(0, s.length()-ref.length()-1));
129             anchor = ref;
130           } else {
131             throw new MalformedURLException JavaDoc();
132           }
133         } catch (MalformedURLException JavaDoc e) {
134           handleRefError(pURL, pRefURL, pPos, "Unable to parse URL: " + pURL);
135         }
136       }
137       url = pURL;
138       if (anchor != null && pRefURL != null) {
139         addAnchorRef(anchor, pRefURL, pPos);
140       }
141     }
142
143     public void addAnchor(String JavaDoc pName) {
144       if (anchors == null) {
145         anchors = new ArrayList JavaDoc();
146       }
147       anchors.add(pName);
148     }
149
150     public void addAnchorRef(String JavaDoc pAnchor, URL JavaDoc pRefURL, int pPos) {
151       AnchorReference anchorReference = new AnchorReference();
152       anchorReference.name = pAnchor;
153       anchorReference.ref = pRefURL;
154       anchorReference.pos = pPos;
155       if (refAnchors == null) {
156         refAnchors = new ArrayList JavaDoc();
157       }
158       refAnchors.add(anchorReference);
159     }
160
161     public void validate() {
162       if (refAnchors != null) {
163         for (Iterator JavaDoc iter = refAnchors.iterator(); iter.hasNext(); ) {
164           AnchorReference anchorReference = (AnchorReference) iter.next();
165           if (anchors == null || !anchors.contains(anchorReference.name)) {
166             handleRefError(url, anchorReference.ref, anchorReference.pos,
167                            "Invalid anchor: " + anchorReference.name);
168           }
169         }
170         refAnchors.clear();
171       }
172     }
173   }
174
175   protected void addEvent(Event pEvent) {
176     final String JavaDoc mName = "addEvent";
177     logger.entering(mName, pEvent.toString());
178     if (pEvent.mySeverity >= Event.ERROR) {
179       haveErrors = true;
180     }
181     if (pEvent.mySeverity >= getSeverity()) {
182       System.err.println(pEvent.toString());
183     }
184     logger.exiting(mName);
185   }
186
187   protected void handleError(URL JavaDoc pURL, int pPos, String JavaDoc pMsg) {
188     addEvent(new Event(Event.ERROR, pURL, pPos, pMsg));
189   }
190
191   protected void handleRefError(URL JavaDoc pURL, URL JavaDoc pRefURL, int pPos, String JavaDoc pMsg) {
192     if (pRefURL == null) {
193       handleError(pURL, pPos, pMsg);
194     }
195     addEvent(new RefEvent(Event.ERROR, pURL, pRefURL, pPos, pMsg));
196   }
197
198   protected void handleWarning(URL JavaDoc pURL, int pPos, String JavaDoc pMsg) {
199     addEvent(new Event(Event.WARNING, pURL, pPos, pMsg));
200   }
201
202   private class URLChecker extends HTMLEditorKit.ParserCallback JavaDoc {
203     CheckedURL url;
204     private URLChecker(CheckedURL pURL) {
205       url = pURL;
206     }
207
208     protected void addLink(String JavaDoc pTagName, String JavaDoc pAttributeName,
209                              String JavaDoc pAttributeValue, int pPos, boolean pCheckExistsOnly) {
210       final String JavaDoc mName = "URLChecker.addLink";
211       logger.finest(mName, "->", new Object JavaDoc[]{pTagName, pAttributeName, pAttributeValue,
212                     Integer.toString(pPos), pCheckExistsOnly ? Boolean.TRUE : Boolean.FALSE});
213       logger.finest(mName, "My URL: " + this.url.url);
214       // First try, whether this is an absolute URL
215
URL JavaDoc myUrl = null;
216       boolean isAbsolute = false;
217       try {
218         myUrl = new URL JavaDoc(pAttributeValue);
219         isAbsolute = true;
220       } catch (MalformedURLException JavaDoc e) {
221       }
222
223       if (!isAbsolute) {
224         try {
225           myUrl = new URL JavaDoc(this.url.url, pAttributeValue);
226         } catch (MalformedURLException JavaDoc e) {
227           
228           LinkChecker.this.handleError(this.url.url, pPos,
229                                        "Failed to parse URL of attribute " + pAttributeName + " in tag " + pTagName);
230           return;
231         }
232       }
233
234       if ("mailto".equals(myUrl.getProtocol())) {
235         return;
236       }
237
238       CheckedURL checkedURL = new CheckedURL(myUrl, this.url.url, pPos);
239       checkedURL.checkExistsOnly = pCheckExistsOnly;
240       checkedURL.isExtern = isAbsolute;
241       addURL(checkedURL);
242       logger.finest(mName, "<-");
243     }
244
245     protected void handleTag(HTML.Tag JavaDoc t, MutableAttributeSet JavaDoc a, int pPos) {
246       final String JavaDoc mName = "URLChecker.handleTag";
247       logger.finest(mName, "->", new Object JavaDoc[]{t, a, Integer.toString(pPos)});
248       String JavaDoc tagName = t.toString().toLowerCase();
249       for (Enumeration JavaDoc en = a.getAttributeNames(); en.hasMoreElements(); ) {
250         Object JavaDoc attributeNameObj = en.nextElement();
251         String JavaDoc attributeName = attributeNameObj.toString().toLowerCase();
252         Object JavaDoc o = a.getAttribute(attributeNameObj);
253         if (o instanceof String JavaDoc) {
254           String JavaDoc attributeValue = (String JavaDoc) o;
255           if (tagName.equals("a")) {
256             if (attributeName.equals("href")) {
257               addLink(tagName, attributeName, attributeValue, pPos, false);
258             } else if (attributeName.equals("name")) {
259               url.addAnchor(attributeValue);
260             }
261           } else if (tagName.equals("img")) {
262             if (attributeName.equals("src")) {
263               addLink(tagName, attributeName, attributeValue, pPos, true);
264             }
265           }
266         } else if (o instanceof Boolean JavaDoc) {
267           // Ignore this
268
} else {
269           handleWarning(url.url, pPos, "Unknown attribute type: " + (o == null ? "null" : o.getClass().getName()));
270         }
271       }
272       logger.finest(mName, "<-");
273     }
274     public void handleSimpleTag(HTML.Tag JavaDoc t, MutableAttributeSet JavaDoc a, int pPos) {
275       super.handleSimpleTag(t, a, pPos);
276       handleTag(t, a, pPos);
277     }
278     public void handleStartTag(HTML.Tag JavaDoc t, MutableAttributeSet JavaDoc a, int pPos) {
279       super.handleStartTag(t, a, pPos);
280       handleTag(t, a, pPos);
281     }
282     public void handleError(String JavaDoc pErrorMsg, int pPos) {
283       super.handleError(pErrorMsg, pPos);
284       handleWarning(url.url, pPos, "Error reported by parser: " + pErrorMsg);
285     }
286   }
287
288   public Logger getLogger() {
289     return logger;
290   }
291
292   public void setLogger(Logger pLogger) {
293     logger = pLogger;
294   }
295
296   public void setSeverity(String JavaDoc pSeverity) {
297     if (pSeverity.equalsIgnoreCase("success")) {
298       severity = Event.SUCCESS;
299     } else if (pSeverity.equalsIgnoreCase("warning")) {
300       severity = Event.WARNING;
301     } else if (pSeverity.equalsIgnoreCase("error")) {
302       severity = Event.ERROR;
303     } else {
304       throw new IllegalArgumentException JavaDoc("Invalid severity, neither of success|warning|error: " + pSeverity);
305     }
306   }
307
308   public int getSeverity() {
309     return severity;
310   }
311
312   public void setProxy(String JavaDoc pProxy) {
313     if (pProxy == null && "".equals(pProxy)) {
314       setProxyHost(null);
315       setProxyPort(null);
316     } else {
317       int offset = pProxy.indexOf(':');
318       if (offset == -1) {
319         setProxyHost(pProxy);
320         setProxyPort(null);
321       } else {
322         setProxyHost(pProxy.substring(0, offset));
323         setProxyPort(pProxy.substring(offset+1));
324       }
325     }
326   }
327
328   public void setProxyHost(String JavaDoc pHost) {
329     if (pHost != null && "".equals(pHost)) {
330       pHost = null;
331     }
332     proxyHost = pHost;
333   }
334
335   public String JavaDoc getProxyHost() {
336     return proxyHost;
337   }
338
339   public void setProxyPort(String JavaDoc pPort) {
340     if (pPort != null && "".equals(pPort)) {
341       pPort = null;
342     }
343     proxyPort = pPort;
344   }
345
346   public String JavaDoc getProxyPort() {
347     return proxyPort;
348   }
349
350   public void addURL(URL JavaDoc pURL, InputStream JavaDoc pStream) {
351     CheckedURL url = new CheckedURL(pURL, null, -1);
352     url.stream = pStream;
353     addURL(url);
354   }
355
356   public void addURL(URL JavaDoc pURL) {
357     addURL(new CheckedURL(pURL, null, -1));
358   }
359
360   public void addURL(CheckedURL pURL) {
361     final String JavaDoc mName = "addURL(URL)";
362     logger.finest(mName, "->", new Object JavaDoc[]{pURL.url, pURL.referencingURL, Integer.toString(pURL.referencingPos)});
363     if (urls.containsKey(pURL.url) || checkedUrls.containsKey(pURL.url)) {
364       logger.exiting(mName, "Already registered");
365       return;
366     }
367     urls.put(pURL.url, pURL);
368     logger.finest(mName, "<-", "New URL");
369   }
370
371   public void parse(CheckedURL pURL) throws IOException JavaDoc {
372     final String JavaDoc mName = "parse(CheckedURL)";
373     logger.finest(mName, "->", pURL.url);
374     logger.fine(mName, "Open", pURL.url);
375     InputStream JavaDoc stream = pURL.stream;
376     if (stream == null) {
377       try {
378         stream = pURL.url.openStream();
379       } catch (IOException JavaDoc e) {
380         handleRefError(pURL.url, pURL.referencingURL, pURL.referencingPos,
381                        "Failed to open URL: " + e.getMessage());
382         return;
383       }
384     }
385
386     if (pURL.checkExistsOnly || pURL.isExtern) {
387       stream.close();
388     } else {
389       BufferedInputStream JavaDoc bStream = new BufferedInputStream JavaDoc(stream, 4096);
390       ParserDelegator JavaDoc parser = new ParserDelegator JavaDoc();
391       HTMLEditorKit.ParserCallback JavaDoc callback = new URLChecker(pURL);
392       parser.parse(new InputStreamReader JavaDoc(bStream), callback, false);
393       bStream.close();
394     }
395     logger.finest(mName, "<-");
396   }
397
398   public void parse() {
399     final String JavaDoc mName = "parse";
400     logger.finest(mName, "->");
401     haveErrors = false;
402
403     boolean isProxySetSet = System.getProperties().contains("http.proxySet");
404     String JavaDoc proxySet = System.getProperty("http.proxySet");
405     boolean isProxyHostSet = System.getProperties().contains("http.proxyHost");
406     String JavaDoc myProxyHost = System.getProperty("http.proxyHost");
407     boolean isProxyPortSet = System.getProperties().contains("http.proxyPort");
408     String JavaDoc myProxyPort = System.getProperty("http.proxyPort");
409
410     String JavaDoc host = getProxyHost();
411     if (host != null) {
412       System.setProperty("http.proxySet", "true");
413       System.setProperty("http.proxyHost", host);
414       String JavaDoc port = getProxyPort();
415       if (port != null) {
416         System.setProperty("http.proxyPort", port);
417       }
418     }
419
420     try {
421       while (!urls.isEmpty()) {
422         Iterator JavaDoc iter = urls.values().iterator();
423         CheckedURL checkedURL = (CheckedURL) iter.next();
424         try {
425           parse(checkedURL);
426         } catch (IOException JavaDoc e) {
427         } finally {
428           urls.remove(checkedURL.url);
429           checkedUrls.put(checkedURL.url, checkedURL);
430         }
431       }
432     } finally {
433       if (host != null) {
434         if (isProxySetSet) {
435           System.setProperty("http.proxySet", proxySet);
436         } else {
437           System.getProperties().remove("http.proxySet");
438         }
439         if (isProxyHostSet) {
440           System.setProperty("http.proxyHost", myProxyHost);
441         } else {
442           System.getProperties().remove("http.proxyHost");
443         }
444         if (isProxyPortSet) {
445           System.setProperty("http.proxyPort", myProxyPort);
446         } else {
447           System.getProperties().remove("http.proxyPort");
448         }
449       }
450     }
451
452     for (Iterator JavaDoc iter = checkedUrls.values().iterator(); iter.hasNext(); ) {
453       CheckedURL checkedURL = (CheckedURL) iter.next();
454       checkedURL.validate();
455     }
456
457     if (!haveErrors) {
458       System.out.println("No errors found.");
459     }
460
461     logger.finest(mName, "<-");
462   }
463
464   public static void main(String JavaDoc[] args) {
465     LinkChecker checker = new LinkChecker();
466
467     for (int i = 0; i < args.length; i++) {
468       URL JavaDoc url;
469       InputStream JavaDoc stream;
470       try {
471         url = new URL JavaDoc(args[i]);
472         stream = url.openStream();
473       } catch (IOException JavaDoc e) {
474         try {
475           File JavaDoc f = new File JavaDoc(args[i]);
476           stream = new FileInputStream JavaDoc(f);
477           url = f.toURL();
478         } catch (IOException JavaDoc f) {
479           System.err.println("Failed to open URL: " + args[i]);
480           continue;
481         }
482       }
483       checker.addURL(url, stream);
484       checker.parse();
485     }
486   }
487 }
488
Popular Tags