/*
 * A utility for linking static html pages that have moved from one server to another
 * Copyright (C) 2000  Stephen Ostermiller <WebMove@Ostermiller.com>
 * 
 * This program 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 2 of the License, or
 * (at your option) any later version.
 * 
 * This program 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.
 *
 */

import java.io.*;

/**
 * Creates redirect documents for web pages.  It creates a new
 * directory with a new file for each web document that you 
 * specify.<P>
 * 
 * If you have access to the server itself, there are
 * better ways of redirecting pages.  Page moved errors and such.
 * This program works by creating a meta redirect page for
 * each page on your site.  Any time that somebody retrieves
 * a page from your old site, they will automatically be 
 * redirected to the same page on the new site after a short
 * delay.<P>
 * 
 * This assumes that all of your web site consists of static pages.
 * This program cannot create pages for dynamically generated pages.
 * It could be used to redirect an entire script to a new script, 
 * but it will not pass any arguments passed to the old script, to
 * the new one. (If you have dynamic pages, you probably want to 
 * look for a bettor solution).<P>
 * 
 * It is also assumed that you have a copy of your site on a local
 * computer.  This program is not a spider, and does not look at 
 * the contents of html documents.  It only creates a document
 * that points to the new location of the original html document
 * for each html document in a directory.<P>
 * 
 * WebMove will also not work well with images.  I know of no
 * good way to redirect image files without access to the server.<P>
 */
public class WebMove {
    
    /**
     * Recurses the current directory and creates 
     * redirect files for each html document or text 
     * file.  The files are created in a directory called 
     * WebMove that is located in the current directory.
     * 
     * The first argument, if present should be the URL of
     * your new web site. For example:<br>
     * java WebMove http://www.mynewsite.com/<br>
     * java WebMove http://myisp.com/~me/<br>
     * 
     * @param args command line arguments
     */
    public static void main(String[] args){
        // create an instance of this class
        WebMove webMove = new WebMove();
        // Check for the argument - the name of the
        // site that we are moving to.
        if (args.length > 0){
            webMove.site = args[0];
        }
        // open the source and destination files and 
        // begin creating redirect files.
        try {
            // we start with the home directory.
            File source = new File(".").getCanonicalFile();
            // Set the number of characters to chop off
            // file names before appending them to the URL
            // to be the number of characters in the destination
            // directory.
            webMove.pathLength = source.toString().length();
            // create the destination directory.
            File destination = new File("WebMove").getCanonicalFile();
            // record the destination file so that we can 
            // check to make sure it in not recursed (infinite
            // recursion is bad)
            webMove.destinationRoot = destination;
            // Only proceed if we are able to make the destination
            // directory.
            if (destination.mkdir()){
                webMove.createMetas(source, destination);
            } else {
                System.out.println("Could not create directory " + destination);
                System.out.println("If you have alread run WebMove, delete this directory before running it again.");
            }
        } catch (IOException e){
            System.out.println(e.getMessage());
        }               
    }
    
    /**
     * The root of the new site.  This is overridden
     * by the first command line argument if it exists.
     * Some examples of this might be:<br>
     * http://www.mynewsite.com/<br>
     * http://myisp.com/~me/<br> 
     */
    private String site = "";
    /**
     * File filter for determining which documents are 
     * returned when recursing the directory looking for
     * web documents
     */
    private FileFilter ff = new HTMLFileFilter();
    
    /**
     * The length of path name of the root directory.
     */
    private int pathLength = 0;

    /**
     * The root directory of the destination directory,
     * so that we can check so that it doesn't get 
     * recursed, causing infinite recursion.
     */
    private File destinationRoot;

    /**
     * A file filter that allows us to look 
     * for web documents and directories.
     */
    private class HTMLFileFilter implements FileFilter{
        /**
         * Whether a pathname is a web document or a directory
         * 
         * @param pathname name of the file to test
         * @returns true if a document is a web document or a directory, false otherwise
         */
        public boolean accept(File pathname){
            if (pathname.isDirectory()){
                // compare to make sure that we don't start 
                // into the place where we are putting files.
                // it would cause infinite recursion
                if (pathname.compareTo(destinationRoot) != 0){
                    return true;
                }
            } 
            if (pathname.getName().toLowerCase().endsWith(".html")){
                return true;
            }
            if (pathname.getName().toLowerCase().endsWith(".htm")){
                return true;
            }
            if (pathname.getName().toLowerCase().endsWith(".txt")){
                return true;
            }
            return false;
        }
    }

    /**
     * Create redirect files for the given source, inside the given
     * destination folder.  If the source is a directory, create
     * redirects for all files in it recursively.
     * 
     * @param source the file which we want redirected
     * @param destination directory in which we want the redirect made
     * @throws IOException if it cannot read from source or write to destination
     */
    private void createMetas(File source, File destination) throws IOException{
        if (source.isDirectory()){
            // recursive stuff
            File[] files = source.listFiles(ff);
            for (int i=0; i<files.length; i++){
                if (files[i].isDirectory()){
                    File f = new File(destination.getCanonicalFile(), files[i].getName());
                    f.mkdir();
                    createMetas(files[i], f);
                } else {
                    createMetas(files[i], destination);
                }
            }           
        } else {
            // handle the redirect for a single file
            File f = new File(destination.getCanonicalFile(), source.getName());
            String newURL = site + source.getCanonicalPath().substring(pathLength).replace('\\','/');
            PrintWriter pw = new PrintWriter(new FileOutputStream(f));
            // an html file can automatically be redirected after a short
            // pause using a meta tag.
            if (source.getName().toLowerCase().endsWith(".html") || source.getName().toLowerCase().endsWith(".htm")){
                pw.println("<html>");
                pw.println("<head>");
                pw.println("<title>");
                pw.println("Page has Moved");
                pw.println("</title>");
                pw.println("<meta http-equiv=\"Refresh\" content=\"1;url=" + newURL + "\">");
                pw.println("</head>");
                pw.println("<body>");
                pw.println("This page has moved to: <a href=\"" + newURL + "\">" + newURL + "</a>.");
                pw.println("</body>");
                pw.println("</html>");
            } 
            // a text document can contain the new url in the body of 
            // the text
            if (source.getName().toLowerCase().endsWith(".txt")){
                pw.println("This page has moved.  Try:");
                pw.println(newURL);
            }
            pw.close();
            // display progress to the user
            System.out.println(f.getCanonicalPath() + " > " + newURL);
        }
    }
}

/**
     * Create redirect files for the given source, inside the given
     * destination folder.  If the source is a directory, create
     * redirects for all files in it recursively.
     * 
     * @param source the file which we want redirected
     * @param destination directory in which we want the redirect made
     * @throws IOException if it cannot read from source or write to destination
     */
    private void createMetas(File source, File destination) throws IOException{
        if (source.isDirectory()){
            // recursive stuff
            File[] files = source.listFiles(ff);
            for (int i=0; i<files.length; i++){
                if (files[i].isDirectory()){
                    File f = new File(destination.getCanonicalFile(), files[i].getName());
                    f.mkdir();
                    createMetas(files[i], f);
                } else {
                    createMetas(files[i], destination);
                }
            }           
        } else {
            // handle the redirect for a single file
            File f = new File(destination.getCanonicalFile(), source.getName());
            String newURL = site + source.getCanonicalPath().substring(pathLength).replace('\\','/');
            PrintWriter pw = new PrintWriter(new FileOutputStream(f));
            // an html file can automatically be redirected after a short
            // pause using a meta tag.
            if (source.getName().toLowerCase().endsWith(".html") || source.getName().toLowerCase().endsWith(".htm")){
                pw.println("<html>");
                pw.println("<head>");
                pw.println("<title>");
                pw.println("Page has Moved");
                pw.println("</title>");
                pw.println("<meta http-equiv=\"Refresh\" content=\"1;url=" + newURL + "\">");
                pw.println("</head>");
                pw.println("<body>");
                pw.println("This page has moved to: <a href=\"" + newURL + "\">" + newURL + "</a>.");
                pw.println("</body>");
                pw.println("</html>");
            } 
            // a text document can contain the new url in the body of 
            // the text
            if (source.getName().toLowerCase().endsWith(".txt")){
                pw.println("This page has moved.  Try:");
                pw.println(newURL);
            }
            pw.close();
            // display progress to the user
            System.out.println(f.getCanonicalPath() + " > " + newURL);
        }
    }
}