alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *  Copyright 1999-2004 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package org.apache.jasper;

import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Writer;
import java.util.Enumeration;
import java.util.Stack;
import java.util.Vector;

import org.apache.jasper.compiler.CommandLineCompiler;
import org.apache.jasper.servlet.JasperLoader;
import org.apache.tomcat.util.compat.Jdk11Compat;
import org.apache.tomcat.util.log.Log;

/**
 * Shell for the jspc compiler.  Handles all options associated with the 
 * command line and creates compilation contexts which it then compiles
 * according to the specified options.
 * @author Danno Ferrin
 */
public class JspC implements Options { //, JspCompilationContext {

    public static final String DEFAULT_IE_CLASS_ID = 
            "clsid:8AD9C840-044E-11D1-B3E9-00805F499D93";
    
    public static final String SWITCH_VERBOSE = "-v";
    public static final String SWITCH_QUIET = "-q";
    public static final String SWITCH_OUTPUT_DIR = "-d";
    public static final String SWITCH_OUTPUT_SIMPLE_DIR = "-dd";
    public static final String SWITCH_IE_CLASS_ID = "-ieplugin";
    public static final String SWITCH_PACKAGE_NAME = "-p";
    public static final String SWITCH_CLASS_NAME = "-c";
    public static final String SWITCH_FULL_STOP = "--";
    public static final String SWITCH_URI_BASE = "-uribase";
    public static final String SWITCH_URI_ROOT = "-uriroot";
    public static final String SWITCH_FILE_WEBAPP = "-webapp";
    public static final String SWITCH_WEBAPP_INC = "-webinc";
    public static final String SWITCH_WEBAPP_XML = "-webxml";
    public static final String SWITCH_MAPPED = "-mapped";
    public static final String SWITCH_DIE = "-die";

    public static final int NO_WEBXML = 0;
    public static final int INC_WEBXML = 10;
    public static final int ALL_WEBXML = 20;

    public static final int DEFAULT_DIE_LEVEL = 1;
    public static final int NO_DIE_LEVEL = 0;

    // future direction
    //public static final String SWITCH_XML_OUTPUT = "-xml";
  
    
    boolean largeFile = false;
    boolean mappedFile = false;

    int jspVerbosityLevel = Log.INFORMATION;

    File scratchDir;

    String ieClassId = DEFAULT_IE_CLASS_ID;

    //String classPath;
    
    String targetPackage;
    
    String targetClassName;

    String uriBase;

    String uriRoot;

    String webxmlFile;

    int webxmlLevel;

    int dieLevel;
    boolean dieOnExit = false;
    static int die; // I realize it is duplication, but this is for
                    // the static main catch

    //JspLoader loader;

    boolean dirset;

    Vector extensions;

    public boolean getKeepGenerated() {
        // isn't this why we are running jspc?
        return true;
    }
    
    public boolean getLargeFile() {
        return largeFile;
    }

    /**
     * Are we supporting HTML mapped servlets?
     */
    public boolean getMappedFile() {
		return mappedFile;
	}

    // Off-line compiler, no need for security manager
    public Object getProtectionDomain() {
	return null;
    }
    
    public boolean getSendErrorToClient() {
        // implied send to System.err
        return true;
    }
 
    public boolean getClassDebugInfo() {
        // compile with debug info
        return false;
    }

    public String getIeClassId() {
        return ieClassId;
    }
    
    public int getJspVerbosityLevel() {
        return jspVerbosityLevel;
    }

    public File getScratchDir() {
        return scratchDir;
    }

    //public String getClassPath() {
    //    return classpath;
    //}

    public Class getJspCompilerPlugin() {
       // we don't compile, so this is meanlingless
        return null;
    }

    public String getJspCompilerPath() {
       // we don't compile, so this is meanlingless
        return null;
    }

    public String getJavaEncoding() {
	return "UTF-8";
    }

    public String getClassPath() {
        return System.getProperty("java.class.path");
    }
    
    int argPos;
    // value set by beutifully obsfucscated java
    boolean fullstop = false;
    String args[];

    private void pushBackArg() {
        if (!fullstop) {
            argPos--;
        }
    }

    private String nextArg() {
        if ((argPos >= args.length)
            || (fullstop = SWITCH_FULL_STOP.equals(args[argPos]))) {
            return null;
        } else {
            return args[argPos++];
        }
    }
        
    private String nextFile() {
        if (fullstop) argPos++;
        if (argPos >= args.length) {
            return null;
        } else {
            return args[argPos++];
        }
    }

    public JspC(String[] arg, PrintStream log) {
        args = arg;
        String tok;

        int verbosityLevel = Log.WARNING;
        dieLevel = NO_DIE_LEVEL;
        die = dieLevel;

	// Hack for Runtime package
	String rt=System.getProperty( "jsp.runtime.package" );
	if( rt!=null ) {
	    Constants.JSP_RUNTIME_PACKAGE=rt;
	    Constants.JSP_SERVLET_BASE=rt+".HttpJspBase";
	}
	
        while ((tok = nextArg()) != null) {
            if (tok.equals(SWITCH_QUIET)) {
                verbosityLevel = Log.WARNING;
            } else if (tok.equals(SWITCH_VERBOSE)) {
                verbosityLevel = Log.INFORMATION;
            } else if (tok.startsWith(SWITCH_VERBOSE)) {
                try {
                    verbosityLevel
                     = Integer.parseInt(tok.substring(SWITCH_VERBOSE.length()));
                } catch (NumberFormatException nfe) {
                    log.println(
                        "Verbosity level " 
                        + tok.substring(SWITCH_VERBOSE.length()) 
                        + " is not valid.  Option ignored.");
                }
            } else if (tok.equals(SWITCH_OUTPUT_DIR)) {
                tok = nextArg();
                if (tok != null) {
                    scratchDir = new File(new File(tok).getAbsolutePath());
                    dirset = true;
                } else {
                    // either an in-java call with an explicit null
                    // or a "-d --" sequence should cause this,
                    // which would mean default handling
                    /* no-op */
                    scratchDir = null;
                }
            } else if (tok.equals(SWITCH_OUTPUT_SIMPLE_DIR)) {
                tok = nextArg();
                if (tok != null) {
                    scratchDir = new File(new File(tok).getAbsolutePath());
                    dirset = false;
                } else {
                    // either an in-java call with an explicit null
                    // or a "-d --" sequence should cause this,
                    // which would mean default handling
                    /* no-op */
                    scratchDir = null;
                }
            } else if (tok.equals(SWITCH_PACKAGE_NAME)) {
                targetPackage = nextArg();
            } else if (tok.equals(SWITCH_CLASS_NAME)) {
                targetClassName = nextArg();
            } else if (tok.equals(SWITCH_URI_BASE)) {
                uriBase = nextArg();
            } else if (tok.equals(SWITCH_URI_ROOT)) {
                uriRoot = nextArg();
            } else if (tok.equals(SWITCH_WEBAPP_INC)) {
                webxmlFile = nextArg();
                if (webxmlFile != null) {
                    webxmlLevel = INC_WEBXML;
                }
            } else if (tok.equals(SWITCH_WEBAPP_XML)) {
                webxmlFile = nextArg();
                if (webxmlFile != null) {
                    webxmlLevel = ALL_WEBXML;
                }
            } else if (tok.equals(SWITCH_MAPPED)) {
                mappedFile = true;
            } else if (tok.startsWith(SWITCH_DIE)) {
                try {
                    dieLevel = Integer.parseInt(
                        tok.substring(SWITCH_DIE.length()));
                } catch (NumberFormatException nfe) {
                    dieLevel = DEFAULT_DIE_LEVEL;
                }
                die = dieLevel;
            } else {
                pushBackArg();
                // Not a recognized Option?  Start treting them as JSP Pages
                break;
            }
        }

// 	QueueLogger ql = new QueueLogger();
// 	ql.setVerbosityLevel(verbosityLevel);
        Constants.jasperLog = Log.getLog("JASPER_LOG", this );
//         Constants.jasperLog.setLogger( ql );

    }

    static Jdk11Compat jdkCompat=Jdk11Compat.getJdkCompat();
    
    public boolean parseFile(PrintStream log, String file, Writer servletout,
			     Writer mappingout)
    {
        try {
            JasperLoader loader =
                    new JasperLoader();
	    loader.setParentClassLoader(getClass().getClassLoader());
	    loader.setOptions( this);
            CommandLineContext clctxt = new CommandLineContext(
                    loader, getClassPath(), file, uriBase, uriRoot, false,
                    this);

	    // Same execution env. as in 'normal' jasper
	    // Some tags may need it ( at compile time )
	    jdkCompat.setContextClassLoader(loader);
	    
            if ((targetClassName != null) && (targetClassName.length() > 0)) {
                clctxt.setServletClassName(targetClassName);
                clctxt.lockClassName();
            }
            if (targetPackage != null) {
                clctxt.setServletPackageName(targetPackage);
                clctxt.lockPackageName();
            }
            if (dirset) {
                clctxt.setOutputInDirs(true);
            }
            File uriDir = new File(clctxt.getRealPath("/"));
            if (uriDir.exists()) {
                if ((new File(uriDir, "WEB-INF/classes")).exists()) {
                    loader.addJar(clctxt.getRealPath("/WEB-INF/classes"));
                }
                File lib = new File(clctxt.getRealPath("WEB-INF/lib"));
                if (lib.exists() && lib.isDirectory()) {
                    String[] libs = lib.list();
                    for (int i = 0; i < libs.length; i++) {
                        try {
                            loader.addJar(lib.getCanonicalPath()
                                    + File.separator
                                    + libs[i]);
                        } catch (IOException ioe) {
                            // failing a toCanonicalPath on a file that
                            // exists() should be a JVM regression test,
                            // therefore we have permission to freak out
                            throw new RuntimeException(ioe.toString());
                        }
                    }
                }
            }
            CommandLineCompiler clc = new CommandLineCompiler(clctxt);

            clc.compile();

            targetClassName = null;
            String thisServletName;
            if  (clc.getPackageName() == null) {
                thisServletName = clc.getClassName();
             } else {
                thisServletName = clc.getPackageName()
                    + '.' + clc.getClassName();
            }
            if (servletout != null) {
                servletout.write("\n\t\n\t\t");
                servletout.write(thisServletName);
                servletout.write("\n\t\t");
                servletout.write(thisServletName);
                servletout.write("\n\t\n");
            }
            if (mappingout != null) {
                mappingout.write("\n\t\n\t\t");
                mappingout.write(thisServletName);
                mappingout.write("\n\t\t");
                mappingout.write(file.replace('\\', '/'));
                mappingout.write("\n\t\n");
            }
            return true;
        } catch (JasperException je) {
            //je.printStackTrace(log);
            Constants.message("jspc.error.jasperException", 
                    new Object[] {file, je}, Log.ERROR);
	    je.printStackTrace();
	    if( je.getRootCause() != null )
		je.getRootCause().printStackTrace();
            if (dieLevel != NO_DIE_LEVEL) {
                dieOnExit = true;
            }
        } catch (FileNotFoundException fne) {
                Constants.message("jspc.error.fileDoesNotExist", 
                        new Object[] {fne.getMessage()}, Log.WARNING);
        } catch (Exception e) {
            Constants.message("jspc.error.generalException", 
                    new Object[] {file, e}, Log.ERROR);
	    e.printStackTrace();
            if (dieLevel != NO_DIE_LEVEL) {
                dieOnExit = true;
            }
        }
        return false;
    }


    public void parseFiles(PrintStream log)  throws JasperException {

        boolean scratchDirSet = (scratchDir != null);
        boolean urirootSet = (uriRoot != null);

        // set up a scratch/output dir if none is provided
        if (scratchDir == null) {
            String temp = System.getProperty("java.io.tempdir");
            if (temp == null) {
                temp = "";
            }
            scratchDir = new File(new File(temp).getAbsolutePath());
        }

 
        File f = new File(args[argPos]);
        while (!f.exists()) {
            boolean webApp = false;
            if (SWITCH_FILE_WEBAPP.equals(args[argPos])) {
                webApp = true;
                if (args.length > argPos + 1) {
                    f = new File(args[argPos + 1]);
                } else {
                    // end of arguments, nothing left to parse
                    Constants.message("jspc.error.emptyWebApp", 
                            Log.ERROR);
                    return;
                }
            }
            if (!f.exists()) {
                Constants.message("jspc.error.fileDoesNotExist", 
                        new Object[] {f}, Log.WARNING);
                argPos++;
                if (webApp) {
                    argPos++;
                }
                if (argPos >= args.length) {
                    // end of arguments, nothing left to parse
                    return;
                } else {
                    f = new File(args[argPos]);
                }
            }
        }
        if (uriRoot == null) {
            if (SWITCH_FILE_WEBAPP.equals(args[argPos])) {
                if (args.length > argPos + 1) {
                    f = new File(args[argPos + 1]);
                } else {
                    // end of arguments, nothing left to parse
                    return;
                }
            }
            // set up the uri root if none is explicitly set
            String tUriBase = uriBase;
            if (tUriBase == null) {
                tUriBase = "/";
            }
            try {
                if (f.exists()) {
                    f = new File(f.getCanonicalPath());
                    while (f != null) {
                        File g = new File(f, "WEB-INF");
                        if (g.exists() && g.isDirectory()) {
                            uriRoot = f.getCanonicalPath();
                            uriBase = tUriBase;
                            Constants.message("jspc.implicit.uriRoot",
                                              new Object[] { uriRoot },
                                              Log.INFORMATION);
                            break;
                        }
                        if (f.exists() && f.isDirectory()) {
                            tUriBase = "/" + f.getName() + "/" + tUriBase;
                        }
                        
                        String fParent = f.getParent();
                        if (fParent == null) {
                            f = new File(args[argPos]);
                            fParent = f.getParent();
                            if (fParent == null) {
                                fParent = File.separator;
                            }
                            uriRoot = new File(fParent).getCanonicalPath();
                            uriBase = "/";
                            break;
                        } else {
                            f = new File(fParent);
                        }

                        // If there is no acceptible candidate, uriRoot will
                        // remain null to indicate to the CompilerContext to
                        // use the current working/user dir.
                    }
                }
            } catch (IOException ioe) {
                // since this is an optional default and a null value
                // for uriRoot has a non-error meaning, we can just
                // pass straight through
            }
        }


        String file = nextFile();
        File froot = new File(uriRoot);
        String ubase = null;
        try {
            ubase = froot.getCanonicalPath();
        } catch (IOException ioe) {
            // if we cannot get the base, leave it null
        }

        while (file != null) {
            if (SWITCH_FILE_WEBAPP.equals(file)) {
                String base = nextFile();
                if (base == null) {
                    Constants.message("jspc.error.emptyWebApp", 
                            Log.ERROR);
                    return;
                }// else if (".".equals(base)) {
                //    base = "";
                //}
                String oldRoot = uriRoot;
                if (!urirootSet) {
                    uriRoot = base;
                }
                Vector pages = new Vector();

                Stack dirs = new Stack();
                dirs.push(base);
                if (extensions == null) {
                    extensions = new Vector();
                    extensions.addElement("jsp");
                }
                while (!dirs.isEmpty()) {
                    String s = dirs.pop().toString();
                    //System.out.println("--" + s);
                    f = new File(s);
                    if (f.exists() && f.isDirectory()) {
                        String[] files = f.list();
                        String ext;
                        for (int i = 0; i < files.length; i++) {
                            File f2 = new File(s, files[i]);
                            //System.out.println(":" + f2.getPath());
                            if (f2.isDirectory()) {
                                dirs.push(f2.getPath());
                                //System.out.println("++" + f2.getPath());
                            } else {
                                ext = files[i].substring(
                                        files[i].lastIndexOf('.') + 1);
                                if (extensions.contains(ext)) {
                                    //System.out.println(s + "?" + files[i]);
                                    pages.addElement(
                                        s + File.separatorChar + files[i]);
                                } else {
                                    //System.out.println("not done:" + ext);
                                }
                            }
                        }
                    }
                }

                String ubaseOld = ubase;
                File frootOld = froot;
                froot = new File(uriRoot);

                try {
                    ubase = froot.getCanonicalPath();
                } catch (IOException ioe) {
                    // if we cannot get the base, leave it null
                }

                //System.out.println("==" + ubase);


                Writer mapout;
                CharArrayWriter servletout, mappingout;
                try {
                    if (webxmlLevel >= INC_WEBXML) {
                        File fmapings = new File(webxmlFile);
                        mapout = new FileWriter(fmapings);
                        servletout = new CharArrayWriter();
                        mappingout = new CharArrayWriter();
                    } else {
                        mapout = null;
                        servletout = null;
                        mappingout = null;
                    }
                    if (webxmlLevel >= ALL_WEBXML) {
                        mapout.write(Constants.getString("jspc.webxml.header"));
                    } else if (webxmlLevel>= INC_WEBXML) {
                        mapout.write(Constants.getString("jspc.webinc.header"));
                    }
                } catch (IOException ioe) {
                    mapout = null;
                    servletout = null;
                    mappingout = null;
                }

                Enumeration e = pages.elements();
                while (e.hasMoreElements())
                {
                    String nextjsp = e.nextElement().toString();
                    try {
                        if (ubase != null) {
                            File fjsp = new File(nextjsp);
                            String s = fjsp.getCanonicalPath();
                            //System.out.println("**" + s);
                            if (s.startsWith(ubase)) {
                                nextjsp = s.substring(ubase.length());
                            }
                        }
                    } catch (IOException ioe) {
                        // if we got problems dont change the file name
                    }

                    if (nextjsp.startsWith("." + File.separatorChar)) {
                        nextjsp = nextjsp.substring(2);
                    }

                    parseFile(log, nextjsp, servletout, mappingout);
                }
                uriRoot = oldRoot;
                ubase = ubaseOld;
                froot = frootOld;

                if (mapout != null) {
                    try {
                        servletout.writeTo(mapout);
                        mappingout.writeTo(mapout);
                        if (webxmlLevel >= ALL_WEBXML) {
                            mapout.write(Constants.getString("jspc.webxml.footer"));
                        } else if (webxmlLevel >= INC_WEBXML) {
                            mapout.write(Constants.getString("jspc.webinc.footer"));
                        }
                        mapout.close();
                    } catch (IOException ioe) {
                        // noting to do if it fails since we are done with it
                    }
                }
            } else {
                try {
                    if (ubase != null) {
                        File fjsp = new File(file);
                        String s = fjsp.getCanonicalPath();
                        if (s.startsWith(ubase)) {
                            file = s.substring(ubase.length());
                        }
                    }
                } catch (IOException ioe) {
                     // if we got problems dont change the file name
                }

                parseFile(log, file, null, null);
            }
            file = nextFile();
        }
        if (dieOnExit) {
            System.exit(die);
        }
    }

    public static void main(String arg[]) {
        if (arg.length == 0) {
           System.out.println(Constants.getString("jspc.usage"));
        } else {
            try {
                JspC jspc = new JspC(arg, System.out);
                jspc.parseFiles(System.out);
            } catch (JasperException je) {
                System.err.print("error:");
                System.err.println(je.getMessage());
                if (die != NO_DIE_LEVEL) {
                    System.exit(die);
                }
            }
        }
    }

}

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.