/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

package org.apache.tools.ant.taskdefs.optional;

import java.io.*;
import java.net.*;
import java.lang.reflect.*;

import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import org.apache.tools.ant.taskdefs.*;

/**
 * Uses JSPC on a file
 * @author Joe Walker
 */
public class JspcTask extends Task
{
  private CommandlineJava cmdl = new CommandlineJava();
    
  /** Setter for property classnameprefix.
   * @param classnameprefix New value of property classnameprefix.
   */
  public void setClassnameprefix(String classnameprefix) {
    this.classnameprefix = classnameprefix;
  }
  /**
   * Set the classpath to be used for this compilation.
   */
  public void setClasspath(Path s) {
    createClasspath().append(s);
  }
  
  /**
   * Creates a nested classpath element
   */
  public Path createClasspath() {
    return cmdl.createClasspath(project).createPath();
  }
  
  /**
   * Adds a reference to a CLASSPATH defined elsewhere.
   */
  public void setClasspathRef(Reference r) {
    createClasspath().setRefid(r);
  }
  
  
  public void setSrcdir(File srcdir)
  {
    this.srcdir = srcdir;
  }
  
  public void setDestdir(File destdir)
  {
    this.destdir = destdir;
  }
  
  public void setPackage(String pkg)
  {
    this.pkg = pkg;
  }
  
  public void setUriroot(File uriroot)
  {
    this.uriroot = uriroot;
  }
  
  public void setTomcathome(File tomcat)
  {
    this.tomcat = tomcat;
  }
  
  public void setFork(boolean fork)
  {
    this.fork = fork;
  }
  
  public void execute() throws BuildException
  {
    if (srcdir == null)
    {
      throw new BuildException("srcdir attribute must be set");
    }
    if (destdir == null)
    {
      throw new BuildException("destdir attribute must be set");
    }
    if (uriroot == null)
    {
      throw new BuildException("uriroot attribute must be set");
    }
    if (tomcat == null)
    {
      throw new BuildException("tomcat attribute must be set");
    }

    try {
      if (fork) {
        cmdl.setClassname("org.apache.jasper.JspC");
        
        final Path classpath = cmdl.createClasspath(project);
        classpath.createPathElement().setLocation(new File(tomcat.getAbsolutePath() + "/lib/jasper.jar"));
        classpath.createPathElement().setLocation(new File(tomcat.getAbsolutePath() + "/lib/servlet.jar"));
        
        if( uriroot != null ) {
          cmdl.createArgument().setValue("-uriroot");
          cmdl.createArgument().setValue(uriroot.getAbsolutePath());
        }
        if( destdir != null ) {
          cmdl.createArgument().setValue("-d");
          cmdl.createArgument().setValue(destdir.getAbsolutePath());
        }
        if( pkg != null ) {
          cmdl.createArgument().setValue("-p");
          cmdl.createArgument().setValue(pkg);
        }
//        if( srcdir != null ) {
//          cmdl.createArgument().setValue("-webapp");
//          cmdl.createArgument().setValue(srcdir.getAbsolutePath());
//        }
        
        Execute exe = new Execute(new LogStreamHandler(this, Project.MSG_INFO,
                                                       Project.MSG_WARN), 
                                  null);
//        ExecuteJava exe = new ExecuteJava();
//        exe.setJavaCommand("org.apache.jasper.JspC");
        DirectoryScanner ds = new DirectoryScanner();
        ds.setBasedir(srcdir);
        ds.setIncludes(new String[] {"**/*.jsp"});
        ds.scan();
        String[] files = ds.getIncludedFiles();
        
        for( int i=0; i< files.length; i++ ) {
          // For each jsp file in the webapp directory, execute the compiler
          CommandlineJava specificCmdl = (CommandlineJava)cmdl.clone();
					// Set the name of the generated class
          String newName = null;
          File f = new File( files[i] );
          log("Renaming " + f.getName(), Project.MSG_VERBOSE);
          newName = classnameprefix + f.getName().substring(0,f.getName().indexOf(".jsp"));
//					newName = classnameprefix + files[i].substring(0,files[i].indexOf(".jsp"));
          specificCmdl.createArgument().setValue( "-c" );
          specificCmdl.createArgument().setValue( newName );
					// Set the actual file to be JSP compiled
          specificCmdl.createArgument().setValue( srcdir.getAbsolutePath() + File.separatorChar + files[i] );
          log("JSP Compiling " + newName, Project.MSG_VERBOSE);
          String[] comLine = specificCmdl.getCommandline();
          
          log("Using commandLine:", Project.MSG_VERBOSE);
          String s ="";
          for( int j=0;j<comLine.length;j++) {
            s += comLine[j] + " ";
          }
          log(s, Project.MSG_VERBOSE);
          exe.setCommandline(specificCmdl.getCommandline());
          try {
            exe.execute();
          } catch (IOException e) {
            throw new BuildException(e, location);
          }
        }
      }
      else
      {
        // It would be nice to be able to simply do:
        // org.apache.jasper.JspC.main(args);
        // However that means that there is a compile time
        // dependancy on jasper which is no good if we want to also
        // compile jserv stuff (which is probably why you want jspc
        // anyway
        
        // So we use reflection to get rid of the compile time dep.
/*        String[] args = { "-uriroot", uriroot, "-d", destdir, "-p", pkg, "-webapp", srcdir };
        Class jspc_class = Class.forName("org.apache.jasper.JspC");
        Object jspc = jspc_class.newInstance();
        Method main = jspc_class.getMethod("main", new Class[] { String[].class });
        main.invoke(jspc, new Object[] { args });
  */      
        // Oh and this bit isn't tested at all ...
      }
    }
    catch(Exception ex)
    {
      ex.printStackTrace();
      throw new BuildException("error during JSP compile: " + ex);
    }
  }
  
  
  private File srcdir;
  private File destdir;
  private String pkg = null;
  private File uriroot;
  private File tomcat;
  private boolean fork = false;
  
    /** Holds value of property classnameprefix. */
  private String classnameprefix;
  
}