/*
** this code is adapted from a version originally
** submitted to ant-dev@jakarta.apache.org by
** Jack Moffitt.
**
** I have modified it to accept a few more jspc options
** and I have removed the buggy -docroot (setDocroot)
** flag.  Weblogic's jspc doesn't seem to do the right
** thing with the docroot flag when it comes to resolving
** files to be included using the <%@ include file ....%>
** tag.  Instead, these included files will be resolved
** by jspc as long as they appear in the classpath.
**
** I also changed it to extend MatchingTask, instead of Java.
** I changed it from his WLJspC to WLjspc510.  I did not
** want it to clash with the current optional WLjspc.java,
** which has apparently been tested for weblogic 4.5.1.
** Since I have no ability to test under 4.5.1, I felt it
** best to offer a second task, which is tested for 5.1.0.
** 
** Notes:
**
** I have modified it and tested it with WebLogic 5.1.0, sp8.
** I have not tested it with taglibs.
** I have not tested the following attributes, which were
** part of Jack's original version:
**
**	setCompiler() (-compiler)
**	setCompilerClass() (-compilerclass)
**	setPackageName() (-packagename)
**	setSuperClass() (-superclass)
**
** I added and tested the following methods:
**
**	setShowVerstion (-version)
**	setCommentary (-commentary)
**
** I failed to get the following weblogic.jspc options
** to work correctly, so I did not include support for them:
**
**	-docroot (removed setDocroot() method)
**	-verboseJavac
**	-nowrite
**
** Finally, I only tested this task as instantiated via JavaScript
** code, called from the <script> task.  I haven't tested it as
** it might appear in a build.xml script as a <wljspc510/> tag, etc.
**
** In order to use this task, it should either be registered
** in the defaults.properties file, as "wljspc510", or it could
** be registered using a <taskdef> tag directly in a build.xml file.
**
**					--Jason Rosenberg
**					1/23/2001
*/

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

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.*;
import org.apache.tools.ant.*;
import org.apache.tools.ant.types.*;
import java.util.*;
import java.io.*;

public class WLJspc510 extends MatchingTask
{
	protected String contextPath = null;
	protected boolean version = false;
	protected boolean keepgenerated = false;
	protected boolean commentary = false;
	protected boolean debug = false;
	protected boolean optimize = false;
	protected boolean deprecation = false;
	protected boolean verbose = false;
	protected Path classpath = null;
	protected String compiler = null;
	protected String compilerclass = null;
	protected String packagename = null;
	protected String superclass = null;
	protected boolean failOnError = false;
	protected File dest = null;
	protected File src = null;

	private static String linesep = System.getProperty("line.separator");

	public void setDest(File dest)
	{
		this.dest = dest;
	}

	public void setSrc(File src)
	{
		this.src = src;
	}

	public void setShowVersion(boolean version)
	{
		this.version = version;
	}

	public void setFailOnError(boolean failOnError)
	{
		this.failOnError = failOnError;
	}

	public void setContextPath(String contextPath)
	{
		File contextPathFile = new File(contextPath);
		this.contextPath = contextPathFile.toString();
	}

	public void setKeepGenerated(boolean keepgenerated)
	{
		this.keepgenerated = keepgenerated;
	}

	public void setDebug(boolean debug)
	{
		this.debug = debug;
	}

	public void setOptimize(boolean optimize)
	{
		this.optimize = optimize;
	}

	public void setDeprecation(boolean deprecation)
	{
		this.deprecation = deprecation;
	}

	public void setVerbose(boolean verbose)
	{
		this.verbose = verbose;
	}

	public void setCommentary(boolean commentary)
	{
		this.commentary = commentary;
	}

	public void setCompiler(String compiler)
	{
		this.compiler = compiler;
	}

	public void setCompilerClass(String compilerclass)
	{
		this.compilerclass = compilerclass;
	}

	public void setPackageName(String packagename)
	{
		this.packagename = packagename;
	}

	public void setSuperClass(String superclass)
	{
		this.superclass = superclass;
	}

	public void setClasspath(Path classpath)
	{
		this.classpath = classpath;
	}

	private String makeDstFilename(String filename)
	{
		try {
			String pack;
			StringBuffer buff = new StringBuffer();
			StringTokenizer st;

			if(contextPath != null) 
				st = new StringTokenizer(contextPath.toString() + File.separator + filename, File.separator);
			else	st = new StringTokenizer(filename, File.separator);

			if (packagename != null) pack = packagename;
			else pack = "jsp_servlet";

			buff.append(dest + File.separator + pack);
			// translate the path
			while (st.countTokens() > 1)
				buff.append(File.separator + "_" + st.nextToken());

			// translate file from file.jsp to _file.class
			StringTokenizer fst = new StringTokenizer(st.nextToken(), ".");
			StringTokenizer ust = new StringTokenizer(fst.nextToken(), "_");
			buff.append(File.separator + "_" + ust.nextToken());
			while (ust.hasMoreTokens())
				buff.append("_" + ust.nextToken());
			buff.append(".class");

			return buff.toString();
		} catch (Exception e) {
			log("Caught exception " + e, Project.MSG_ERR);
			return null;
		}
	}

	public void execute() throws BuildException
	{
		// check for required attributes
		if (dest == null) {
			throw new BuildException("dest must not be null.");
		}

		if (src == null) {
			throw new BuildException("src must not be null.");
		}

        	Java helperTask = (Java)project.createTask("java");
		helperTask.setClassname("weblogic.jspc");
		helperTask.setFork(true);
		helperTask.setDir(src);

		DirectoryScanner ds = this.getDirectoryScanner(src);
		String[] files = ds.getIncludedFiles();

		// scan for the files that need recompiling
		Vector jspfiles = new Vector();
		for (int i = 0; i < files.length; i++) {
			String srcfilename = src.toString() + File.separator + files[i];
			File fsrc = new File(srcfilename);

			String dstfilename = makeDstFilename(files[i]);
			File fdst = new File(dstfilename);

			if (fsrc.lastModified() > fdst.lastModified()) {
				jspfiles.add(files[i]);
			}
		}

		// build the args
		Commandline.Argument cla = helperTask.createArg();

		StringBuffer buff = new StringBuffer();
		buff.append(" -d " + dest.toString());
		if (contextPath != null) buff.append(" -contextPath " + contextPath);
		if (version) buff.append(" -version");
		if (keepgenerated) buff.append(" -keepgenerated");
		if (compiler != null && compilerclass == null) buff.append(" -compiler " + compiler);
		if (compilerclass != null) buff.append(" -compilerclass " + compilerclass);
		if (commentary) buff.append(" -commentary");
		if (debug) buff.append(" -g");
		if (optimize) buff.append(" -O");
		if (deprecation) buff.append(" -deprecation");
		if (verbose) buff.append(" -verbose");
		if (packagename != null) buff.append(" -package " + packagename);
		if (superclass != null) buff.append(" -superclass " + superclass);
		if (classpath != null) {
			buff.append(" -classpath " + classpath.toString());
			helperTask.setClasspath(classpath);
		}

		String cmdline = buff.toString();

		if(jspfiles.size() == 0)
			return;

		// GO GO GO
		log("Compiling " + jspfiles.size() + " jsp file" + (jspfiles.size() == 1 ? "" : "s")
			+ (dest != null ? " to " + dest : ""), Project.MSG_INFO);
		log("Calling class weblogic.jspc with args " + cmdline, Project.MSG_VERBOSE);

		buff = new StringBuffer();
		buff.append("File" + (jspfiles.size() == 1 ? "" : "s") + " to be compiled" + linesep);
		for (int i = 0; i < jspfiles.size(); i++)
			buff.append("   " + jspfiles.elementAt(i) + linesep);
		log(buff.toString(), Project.MSG_VERBOSE);

		for (int i = 0; i < jspfiles.size(); i++) {
			String jspFile = (String)jspfiles.elementAt(i);
			cla.setLine(cmdline + " " + jspFile);

			log("Compiling " + jspFile, Project.MSG_INFO);

			int err = -1;
			if ((err = helperTask.executeJava()) != 0) {
				if (failOnError) {
					throw new BuildException("Java returned: "+err, location);
				} else {
					log("Java Result: " + err, Project.MSG_ERR);
				}
			}
		}
	}
}
