/* * BadLinksRecorder.java 1.0 * * Copyright (c) 1999 Emmanuel PUYBARET - eTeks. * All Rights Reserved. * */ import java.net.*; import java.io.*; import java.util.*; import java.text.*; import javax.swing.text.*; import javax.swing.text.html.*; public class BadLinksRecorder { private URL searchedURL; // URL de depart private Vector parsedHtmlFiles; // Ensemble des fichiers HTML lus private Vector otherCheckedFiles; // Ensemble des autre types de fichiers private Vector badFiles; // Ensemble des fichiers incorrects private Hashtable htmlFiles; // Hashtable ayant pour cle une URL et // pour valeur les documents HTML lus private int badURLsCount; // Nombre de mauvaises URLs private int badAnchorsCount; // Nombre d'ancres non definies public BadLinksRecorder (String searchedURL) throws IOException { this.searchedURL = new URL (searchedURL); // Tentative d'ouverture pour verifier la validite de l'URL // Declenchement d'une exception en cas de probleme InputStream inputStream = getInputStream (this.searchedURL); inputStream.close (); } private InputStream getInputStream (URL url) throws IOException { // Tentative d'ouverture du fichier URLConnection connection = url.openConnection (); // Si le fichier est accede via le protocole http // verification si un code 4xx n'a pas ete renvoye if ( connection instanceof HttpURLConnection && ((HttpURLConnection)connection).getResponseCode () / 100 == 4) throw new IOException (); return connection.getInputStream (); } // Methode d'interrogation des resultats du parsing public Vector getHTMLFiles () { return parsedHtmlFiles; } public Vector getMalformedURLs (URL file) { return ((HTMLBadLinks)htmlFiles.get (file)).getMalformedURLs (); } public Vector getBadURLs (URL file) { return ((HTMLBadLinks)htmlFiles.get (file)).badURLs; } public Vector getBadAnchors (URL file) { return ((HTMLBadLinks)htmlFiles.get (file)).badAnchors; } public int getBadURLsCount () { return badURLsCount; } public int getBadAnchorsCount () { return badAnchorsCount; } // Parcours du fichier HTML donne au constructeur et de tous les fichiers // qui lui sont lies. public boolean parseFiles () { parsedHtmlFiles = new Vector (); // Ensemble des fichiers HTML rencontres otherCheckedFiles = new Vector (); // Ensemble des autre types de fichiers htmlFiles = new Hashtable (); badFiles = new Vector (); parsedHtmlFiles.addElement (searchedURL); // Parcours de toutes les urls qui sont ajoutees a parsedHtmlFiles HTMLEditorKit html = new HTMLEditorKit (); for (int i = 0; i < parsedHtmlFiles.size (); i++) { URL searchURL = (URL)parsedHtmlFiles.elementAt (i); Reader urlReader = null; try { InputStream inputStream = getInputStream (searchURL); urlReader = new BufferedReader ( new InputStreamReader (inputStream)); } catch (IOException e) { // En cas d'echec, ajout a l'ensemble des mauvais fichiers badFiles.addElement (searchURL); continue; } try { System.out.println ("Lecture de " + searchURL + "..."); // Creation d'un document HTML ajoute a l'ensemble htmlFiles HTMLBadLinks doc = new HTMLBadLinks (searchURL, parsedHtmlFiles, otherCheckedFiles); htmlFiles.put (searchURL, doc); // Demarrage de la lecture et du parsing du fichier HTML html.read (urlReader, doc, 0); urlReader.close (); for (Enumeration e = doc.getURLs ().elements (); e.hasMoreElements (); ) try { URL url = (URL)e.nextElement (); // Construction de l'URL sans ancre URL urlWithNoAnchor = new URL (url.getProtocol (), url.getHost (), url.getPort (), url.getFile ()); String lowerCaseFile = url.getFile ().toLowerCase (); if ( lowerCaseFile.endsWith (".htm") || lowerCaseFile.endsWith (".html")) { // Si le fichier est un fichier HTML, ajout a l'ensemble // des fichiers HTML (verification de l'extension en minuscules) if (!parsedHtmlFiles.contains (urlWithNoAnchor)) parsedHtmlFiles.addElement (urlWithNoAnchor); } else // Pour les autres types de fichier (GIF, JPG,...), ajout // a l'ensemble des autres fichiers if (!otherCheckedFiles.contains (url)) otherCheckedFiles.addElement (url); } catch (MalformedURLException exception) { } // Ne peut arriver } catch (IOException e) { System.out.println ("Probleme de lecture de " + searchURL); } catch (BadLocationException e) { } } // Suppression des mauvais fichiers de parsedHtmlFiles for (int i = 0; i < parsedHtmlFiles.size (); ) if (badFiles.contains (parsedHtmlFiles.elementAt (i))) parsedHtmlFiles.removeElementAt (i); else i++; // Suppression des mauvais fichiers de otherCheckedFiles for (int i = 0; i < otherCheckedFiles.size (); ) { URL otherFile = (URL)otherCheckedFiles.elementAt (i); try { // Tentative d'ouverture du fichier InputStream inputStream = getInputStream (otherFile); inputStream.close (); i++; } catch (IOException e) { badFiles.addElement (otherFile); otherCheckedFiles.removeElementAt (i); } } badURLsCount = 0; badAnchorsCount = 0; // Recherche des URLs et ancres mauvaises dans tous les fichiers lus for (Enumeration e = htmlFiles.elements (); e.hasMoreElements (); ) { HTMLBadLinks parsedDocument = (HTMLBadLinks)e.nextElement (); badURLsCount += parsedDocument.getMalformedURLs ().size (); // Parcours de toutes les URLs du fichier for (Enumeration eURL = parsedDocument.getURLs ().elements (); eURL.hasMoreElements (); ) try { URL url = (URL)eURL.nextElement (); // Construction de l'URL sans ancre URL urlWithNoAnchor = new URL (url.getProtocol (), url.getHost (), url.getPort (), url.getFile ()); // Verification si l'URL sans ancre est dans les mauvais fichiers if (badFiles.contains (urlWithNoAnchor)) { parsedDocument.badURLs.addElement (urlWithNoAnchor); badURLsCount++; } else if ( !otherCheckedFiles.contains (url) && url.getRef () != null) { HTMLBadLinks htmlDocument = (HTMLBadLinks)htmlFiles.get (urlWithNoAnchor); // Recherche de l'existence de l'ancre dans le fichier indique if (!htmlDocument.getAnchors ().contains (url.getRef ())) { parsedDocument.badAnchors.addElement (url); badAnchorsCount++; } } } catch (MalformedURLException ex) { } // Ne peut arriver } // Tri bulle simple sur le vecteur parsedHtmlFiles // pour une sortie des fichiers par ordre alphabetique boolean sorted; do { sorted = true; for (int i = 0; i < parsedHtmlFiles.size () - 1; i++) { URL url1 = (URL)parsedHtmlFiles.elementAt (i); URL url2 = (URL)parsedHtmlFiles.elementAt (i + 1); if (url1.toString ().compareTo (url2.toString ()) > 0) { parsedHtmlFiles.setElementAt (url2, i); parsedHtmlFiles.setElementAt (url1, i + 1); sorted = false; } } } while (!sorted); // Renvoie true si pas d'erreur rencontree return badURLsCount == 0 && badAnchorsCount == 0; } // Classe derivee de HTMLDocumentLinks qui memorise en plus les URLs // et les ancres mauvaises private class HTMLBadLinks extends HTMLDocumentLinks { Vector badAnchors = new Vector (); Vector badURLs = new Vector (); public HTMLBadLinks (URL file, Vector htmlFiles, Vector otherFiles) { super (file); } } // Methode main () d'exemple de mise en oeuvre // (prend en argument un nom de fichier HTML de depart // sous forme d'URL, par exemple file:/disk/dir1/index.html) public static void main (String args []) { try { BadLinksRecorder recorder = new BadLinksRecorder (args [0]); if (recorder.parseFiles ()) System.out.println ("\nToutes les URL et ancres sont correctes."); else { // Pour chacun des fichiers HTML lus, listing des erreurs for (Enumeration e = recorder.getHTMLFiles ().elements (); e.hasMoreElements (); ) { URL htmlFile = (URL)e.nextElement (); for (Enumeration e2 = recorder.getMalformedURLs (htmlFile).elements (); e2.hasMoreElements (); ) System.out.println ( "Dans le fichier " + htmlFile + " l'URL " + e2.nextElement () + " est incorrecte."); for (Enumeration e2 = recorder.getBadURLs (htmlFile).elements (); e2.hasMoreElements (); ) System.out.println ( "Dans le fichier " + htmlFile + " l'URL " + e2.nextElement () + " n'existe pas."); for (Enumeration e2 = recorder.getBadAnchors (htmlFile).elements (); e2.hasMoreElements (); ) { URL url = (URL)e2.nextElement (); System.out.println ( "Dans le fichier " + htmlFile + " l'ancre" + url.getRef () + " de l'URL " + url + " est inconnue."); } } System.out.println ( "" + recorder.getBadURLsCount () + " URL et " + recorder.getBadAnchorsCount () + " ancres sont incorrectes.\n"); } // Liste de tous les fichiers HTML lus System.out.println ("\nListe des " + recorder.getHTMLFiles ().size () + " fichiers verifies :\n"); for (Enumeration e = recorder.getHTMLFiles ().elements (); e.hasMoreElements (); ) System.out.println (e.nextElement ()); } catch (IOException e) { System.out.println ("Probleme d'acces a l'URL : " + args [0]); } } }