JAL-3210 Barebones gradle/buildship/eclipse. See README
[jalview.git] / utils / HelpLinksChecker.java
diff --git a/utils/HelpLinksChecker.java b/utils/HelpLinksChecker.java
deleted file mode 100644 (file)
index 1279b31..0000000
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- * 
- * This file is part of Jalview.
- * 
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License 
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *  
- * Jalview is distributed in the hope that it will be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty 
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
- * PURPOSE.  See the GNU General Public License for more details.
- * 
- * You should have received a copy of the GNU General Public License
- * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URL;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A class to check help file cross-references, and external URLs if internet
- * access is available
- * 
- * @author gmcarstairs
- *
- */
-public class HelpLinksChecker implements BufferedLineReader.LineCleaner
-{
-  private static final String HELP_HS = "help.hs";
-
-  private static final String HELP_TOC_XML = "helpTOC.xml";
-
-  private static final String HELP_JHM = "help.jhm";
-
-  private static boolean internetAvailable = true;
-
-  private int targetCount = 0;
-
-  private int mapCount = 0;
-
-  private int internalHrefCount = 0;
-
-  private int anchorRefCount = 0;
-
-  private int invalidAnchorRefCount = 0;
-
-  private int externalHrefCount = 0;
-
-  private int invalidMapUrlCount = 0;
-
-  private int invalidTargetCount = 0;
-
-  private int invalidImageCount = 0;
-
-  private int invalidInternalHrefCount = 0;
-
-  private int invalidExternalHrefCount = 0;
-
-  /**
-   * The only parameter should be a path to the root of the help directory in
-   * the workspace
-   * 
-   * @param args
-   *          [0] path to the /html folder in the workspace
-   * @param args
-   *          [1] (optional) -nointernet to suppress external link checking for
-   *          a fast check of internal links only
-   * @throws IOException
-   */
-  public static void main(String[] args) throws IOException
-  {
-    if (args.length == 0 || args.length > 2
-            || (args.length == 2 && !args[1].equals("-nointernet")))
-    {
-      log("Usage: <pathToHelpFolder> [-nointernet]");
-      return;
-    }
-
-    if (args.length == 2)
-    {
-      internetAvailable = false;
-    }
-
-    new HelpLinksChecker().checkLinks(args[0]);
-  }
-
-  /**
-   * Checks help links and reports results
-   * 
-   * @param helpDirectoryPath
-   * @throws IOException
-   */
-  void checkLinks(String helpDirectoryPath) throws IOException
-  {
-    log("Checking help file links");
-    File helpFolder = new File(helpDirectoryPath).getCanonicalFile();
-    if (!helpFolder.exists())
-    {
-      log("Can't find " + helpDirectoryPath);
-      return;
-    }
-
-    internetAvailable &= connectToUrl("http://www.example.org");
-
-    Map<String, String> tocTargets = checkHelpMappings(helpFolder);
-
-    Map<String, String> unusedTargets = new HashMap<String, String>(
-            tocTargets);
-
-    checkTableOfContents(helpFolder, tocTargets, unusedTargets);
-
-    checkHelpSet(helpFolder, tocTargets, unusedTargets);
-
-    checkHtmlFolder(new File(helpFolder, "html"));
-
-    reportResults(unusedTargets);
-  }
-
-  /**
-   * Checks all html files in the given directory or its sub-directories
-   * 
-   * @param folder
-   * @throws IOException
-   */
-  private void checkHtmlFolder(File folder) throws IOException
-  {
-    File[] files = folder.listFiles();
-    for (File f : files)
-    {
-      if (f.isDirectory())
-      {
-        checkHtmlFolder(f);
-      }
-      else
-      {
-        if (f.getAbsolutePath().endsWith(".html"))
-        {
-          checkHtmlFile(f, folder);
-        }
-      }
-    }
-  }
-
-  /**
-   * Checks that any image attribute in help.hs is a valid target
-   * 
-   * @param helpFolder
-   * @param tocTargets
-   * @param unusedTargets
-   *          used targets are removed from here
-   */
-  private void checkHelpSet(File helpFolder,
-          Map<String, String> tocTargets, Map<String, String> unusedTargets)
-          throws IOException
-  {
-    BufferedReader br = new BufferedReader(new FileReader(new File(
-            helpFolder, HELP_HS)));
-    String data = br.readLine();
-    int lineNo = 0;
-
-    while (data != null)
-    {
-      lineNo++;
-      String image = getAttribute(data, "image");
-      if (image != null)
-      {
-        unusedTargets.remove(image);
-        if (!tocTargets.containsKey(image))
-        {
-          log(String.format("Invalid image '%s' at line %d of %s", image,
-                  lineNo, HELP_HS));
-          invalidImageCount++;
-        }
-      }
-      data = br.readLine();
-    }
-    br.close();
-  }
-
-  /**
-   * Print counts to sysout
-   * 
-   * @param unusedTargets
-   */
-  private void reportResults(Map<String, String> unusedTargets)
-  {
-    log("\nResults:");
-    log(targetCount + " distinct help targets");
-    log(mapCount + " help mappings");
-    log(invalidTargetCount + " invalid targets");
-    log(unusedTargets.size() + " unused targets");
-    for (String target : unusedTargets.keySet())
-    {
-      log(String.format("    %s: %s", target, unusedTargets.get(target)));
-    }
-    log(invalidMapUrlCount + " invalid map urls");
-    log(invalidImageCount + " invalid image attributes");
-    log(String.format("%d internal href links (%d with anchors)",
-            internalHrefCount, anchorRefCount));
-    log(invalidInternalHrefCount + " invalid internal href links");
-    log(invalidAnchorRefCount + " invalid internal anchor links");
-    log(externalHrefCount + " external href links");
-    if (internetAvailable)
-    {
-      log(invalidExternalHrefCount + " invalid external href links");
-    }
-    else
-    {
-      System.out
-              .println("External links not verified as internet not available");
-    }
-    if (invalidInternalHrefCount > 0 || invalidExternalHrefCount > 0
-            || invalidImageCount > 0 || invalidAnchorRefCount > 0)
-    {
-      log("*** Failed ***");
-      System.exit(1);
-    }
-    log("*** Success ***");
-  }
-
-  /**
-   * @param s
-   */
-  static void log(String s)
-  {
-    System.out.println(s);
-  }
-
-  /**
-   * Reads the given html file and checks any href attibute values are either
-   * <ul>
-   * <li>a valid relative file path, or</li>
-   * <li>a valid absolute URL (if external link checking is enabled)</li>
-   * </ul>
-   * 
-   * @param htmlFile
-   * @param htmlFolder
-   *          the parent folder (for validation of relative paths)
-   */
-  private void checkHtmlFile(File htmlFile, File htmlFolder)
-          throws IOException
-  {
-    BufferedReader br = new BufferedReader(new FileReader(htmlFile));
-    String data = br.readLine();
-    int lineNo = 0;
-    while (data != null)
-    {
-      lineNo++;
-      String href = getAttribute(data, "href");
-      if (href != null)
-      {
-        String anchor = null;
-        int anchorPos = href.indexOf("#");
-        if (anchorPos != -1)
-        {
-          anchor = href.substring(anchorPos + 1);
-          href = href.substring(0, anchorPos);
-        }
-        boolean badLink = false;
-        if (href.startsWith("http"))
-        {
-          externalHrefCount++;
-          if (internetAvailable)
-          {
-            if (!connectToUrl(href))
-            {
-              badLink = true;
-              invalidExternalHrefCount++;
-            }
-          }
-        }
-        else
-        {
-          internalHrefCount++;
-          File hrefFile = href.equals("") ? htmlFile : new File(htmlFolder,
-                  href);
-          if (hrefFile != htmlFile && !fileExists(hrefFile, href))
-          {
-            badLink = true;
-            invalidInternalHrefCount++;
-          }
-          if (anchor != null)
-          {
-            anchorRefCount++;
-            if (!badLink)
-            {
-              if (!checkAnchorExists(hrefFile, anchor))
-              {
-                log(String.format("Invalid anchor: %s at line %d of %s",
-                        anchor, lineNo, getPath(htmlFile)));
-                invalidAnchorRefCount++;
-              }
-            }
-          }
-        }
-        if (badLink)
-        {
-          log(String.format("Invalid href %s at line %d of %s", href,
-                  lineNo, getPath(htmlFile)));
-        }
-      }
-      data = br.readLine();
-    }
-    br.close();
-  }
-
-  /**
-   * Performs a case-sensitive check that the href'd file exists
-   * 
-   * @param hrefFile
-   * @return
-   * @throws IOException
-   */
-  boolean fileExists(File hrefFile, String href) throws IOException
-  {
-    if (!hrefFile.exists())
-    {
-      return false;
-    }
-
-    /*
-     * On Mac or Windows, file.exists() is not case sensitive, so do an
-     * additional check with case sensitivity 
-     */
-    int slashPos = href.lastIndexOf(File.separator);
-    String expectedFileName = slashPos == -1 ? href : href
-            .substring(slashPos + 1);
-    String cp = hrefFile.getCanonicalPath();
-    slashPos = cp.lastIndexOf(File.separator);
-    String actualFileName = slashPos == -1 ? cp : cp
-            .substring(slashPos + 1);
-
-    return expectedFileName.equals(actualFileName);
-  }
-
-  /**
-   * Reads the file and checks for the presence of the given html anchor
-   * 
-   * @param hrefFile
-   * @param anchor
-   * @return true if anchor is found else false
-   */
-  private boolean checkAnchorExists(File hrefFile, String anchor)
-  {
-    String nameAnchor = "<a name=\"" + anchor + "\"";
-    String idAnchor = "<a id=\"" + anchor + "\"";
-    boolean found = false;
-    try
-    {
-      BufferedReader br = new BufferedReader(new FileReader(hrefFile));
-      BufferedLineReader blr = new BufferedLineReader(br, 3, this);
-      String data = blr.read();
-      while (data != null)
-      {
-        if (data.contains(nameAnchor) || data.contains(idAnchor))
-        {
-          found = true;
-          break;
-        }
-        data = blr.read();
-      }
-      br.close();
-    } catch (IOException e)
-    {
-      // ignore
-    }
-    return found;
-  }
-
-  /**
-   * Returns the part of the file path starting from /help/
-   * 
-   * @param helpFile
-   * @return
-   */
-  private String getPath(File helpFile)
-  {
-    String path = helpFile.getPath();
-    int helpPos = path.indexOf("/help/");
-    return helpPos == -1 ? path : path.substring(helpPos);
-  }
-
-  /**
-   * Returns true if the URL returns an input stream, or false if the URL
-   * returns an error code or we cannot connect to it (e.g. no internet
-   * available)
-   * 
-   * @param url
-   * @return
-   */
-  private boolean connectToUrl(String url)
-  {
-    try
-    {
-      URL u = new URL(url);
-      InputStream connection = u.openStream();
-      connection.close();
-      return true;
-    } catch (Throwable t)
-    {
-      return false;
-    }
-  }
-
-  /**
-   * Reads file help.jhm and checks that
-   * <ul>
-   * <li>each target attribute is in tocTargets</li>
-   * <li>each url attribute is a valid relative file link</li>
-   * </ul>
-   * 
-   * @param helpFolder
-   */
-  private Map<String, String> checkHelpMappings(File helpFolder)
-          throws IOException
-  {
-    Map<String, String> targets = new HashMap<String, String>();
-    BufferedReader br = new BufferedReader(new FileReader(new File(
-            helpFolder, HELP_JHM)));
-    String data = br.readLine();
-    int lineNo = 0;
-    while (data != null)
-    {
-      lineNo++;
-
-      /*
-       * record target, check for duplicates
-       */
-      String target = getAttribute(data, "target");
-      if (target != null)
-      {
-        mapCount++;
-        if (targets.containsKey(target))
-        {
-          log(String.format(
-                  "Duplicate target mapping to %s at line %d of %s",
-                  target, lineNo, HELP_JHM));
-        }
-        else
-        {
-          targetCount++;
-        }
-      }
-
-      /*
-       * validate url
-       */
-      String url = getAttribute(data, "url");
-      if (url != null)
-      {
-        targets.put(target, url);
-        int anchorPos = url.indexOf("#");
-        if (anchorPos != -1)
-        {
-          url = url.substring(0, anchorPos);
-        }
-        if (!new File(helpFolder, url).exists())
-        {
-          log(String.format("Invalid url path '%s' at line %d of %s", url,
-                  lineNo, HELP_JHM));
-          invalidMapUrlCount++;
-        }
-      }
-      data = br.readLine();
-    }
-    br.close();
-    return targets;
-  }
-
-  /**
-   * Reads file helpTOC.xml and reports any invalid targets
-   * 
-   * @param helpFolder
-   * @param tocTargets
-   * @param unusedTargets
-   *          used targets are removed from this map
-   * 
-   * @return
-   * @throws IOException
-   */
-  private void checkTableOfContents(File helpFolder,
-          Map<String, String> tocTargets, Map<String, String> unusedTargets)
-          throws IOException
-  {
-    BufferedReader br = new BufferedReader(new FileReader(new File(
-            helpFolder, HELP_TOC_XML)));
-    String data = br.readLine();
-    int lineNo = 0;
-    while (data != null)
-    {
-      lineNo++;
-      /*
-       * assuming no more than one "target" per line of file here
-       */
-      String target = getAttribute(data, "target");
-      if (target != null)
-      {
-        unusedTargets.remove(target);
-        if (!tocTargets.containsKey(target))
-        {
-          log(String.format("Invalid target '%s' at line %d of %s", target,
-                  lineNo, HELP_TOC_XML));
-          invalidTargetCount++;
-        }
-      }
-      data = br.readLine();
-    }
-    br.close();
-  }
-
-  /**
-   * Returns the value of an attribute if found in the data, else null
-   * 
-   * @param data
-   * @param attName
-   * @return
-   */
-  private static String getAttribute(String data, String attName)
-  {
-    /*
-     * make a partial attempt at ignoring within <!-- html comments -->
-     * (doesn't work if multi-line)
-     */
-    int commentStartPos = data.indexOf("<!--");
-    int commentEndPos = commentStartPos == -1 ? -1 : data.substring(
-            commentStartPos + 4).indexOf("-->");
-    String value = null;
-    String match = attName + "=\"";
-    int attPos = data.indexOf(match);
-    if (attPos > 0
-            && (commentStartPos == -1 || attPos < commentStartPos || attPos > commentEndPos))
-    {
-      data = data.substring(attPos + match.length());
-      value = data.substring(0, data.indexOf("\""));
-    }
-    return value;
-  }
-
-  /**
-   * Trim whitespace from concatenated lines but preserve one space for valid
-   * parsing
-   */
-  @Override
-  public String cleanLine(String l)
-  {
-    return l.trim() + " ";
-  }
-}