Package com.caucho.jsp

Source Code of com.caucho.jsp.JspPrecompileResource

/*
* Copyright (c) 1998-2011 Caucho Technology -- all rights reserved
*
* This file is part of Resin(R) Open Source
*
* Each copy or derived work must preserve the copyright notice and this
* notice unmodified.
*
* Resin Open Source 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.
*
* Resin Open Source 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, or any warranty
* of NON-INFRINGEMENT.  See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with Resin Open Source; if not, write to the
*
*   Free Software Foundation, Inc.
*   59 Temple Place, Suite 330
*   Boston, MA 02111-1307  USA
*
* @author Scott Ferguson
*/

package com.caucho.jsp;

import com.caucho.config.ConfigException;
import com.caucho.config.types.FileSetType;
import com.caucho.config.types.PathPatternType;
import com.caucho.env.thread.ThreadPool;
import com.caucho.java.JavaCompiler;
import com.caucho.java.LineMap;
import com.caucho.lifecycle.Lifecycle;
import com.caucho.server.webapp.WebApp;
import com.caucho.util.Alarm;
import com.caucho.util.CompileException;
import com.caucho.util.L10N;
import com.caucho.vfs.Path;
import com.caucho.vfs.Vfs;

import javax.annotation.PostConstruct;
import javax.servlet.jsp.JspFactory;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
* Resource for precompiling all the *.jsp files on startup.
*/
public class JspPrecompileResource {
  private static final Logger log
    = Logger.getLogger(JspPrecompileResource.class.getName());
  private static final L10N L = new L10N(JspPrecompileResource.class);

  private FileSetType _fileSet;
 
  private WebApp _webApp;

  private final Lifecycle _lifecycle = new Lifecycle();

  private int _threadCount = 2;

  private int _completeCount;

  /**
   * Sets the webApp.
   */
  public void setWebApp(WebApp app)
  {
    _webApp = app;
  }

  /**
   * Add a pattern.
   */
  public FileSetType createFileset()
  {
    if (_fileSet == null) {
      _fileSet = new FileSetType();
      _fileSet.setDir(Vfs.lookup());
    }

    return _fileSet;
  }

  /**
   * @deprecated
   */
  public FileSetType createFileSet()
  {
    return createFileset();
  }

  /**
   * Sets the number of threads to spawn.
   */
  public void setThreadCount(int count)
  {
    if (count < 1)
      count = 1;
   
    _threadCount = count;
  }

  /**
   * Initialize the resource.
   */
  @PostConstruct
  public void init()
    throws ConfigException
  {
    Path pwd = Vfs.lookup();

    if (_fileSet == null) {
      createFileset().addInclude(new PathPatternType("**/*.jsp"));
    }

    if (_webApp == null) {
      _webApp = WebApp.getLocal();
    }

    if (_webApp == null)
      throw new ConfigException(L.l("JspPrecompileResource must be used in a web-app context."));

    start();
  }

  /**
   * Starts the resource.
   */
  public void start()
  {
    if (! _lifecycle.toActive())
      return;
   
    // JspManager manager = new JspManager(_webApp);

    if (JspFactory.getDefaultFactory() == null)
      JspFactory.setDefaultFactory(new QJspFactory());

    ArrayList<Path> paths = _fileSet.getPaths();
    ArrayList<String> classes = new ArrayList<String>();

    for (int i = 0; i < _threadCount; i++) {
      CompileTask task = new CompileTask(paths, classes);
     
      ThreadPool.getThreadPool().schedule(task);
    }

    long expire = Alarm.getCurrentTime() + 60000;
    synchronized (this) {
      while (_completeCount < _threadCount) {
        try {
          long timeout = expire - Alarm.getCurrentTime();

          if (timeout <= 0)
            return;

          wait(timeout);
        } catch (Exception e) {
        }
      }
    }
  }

  class CompileTask implements Runnable {
    private int _chunkCount;
    private ArrayList<Path> _paths;
    private ArrayList<String> _classes;
    private JspCompiler _compiler;

    CompileTask(ArrayList<Path> paths,
                ArrayList<String> classes)
    {
      _paths = paths;
      _classes = classes;

      synchronized (_paths) {
        _chunkCount = (_paths.size() + _threadCount) / _threadCount;
      }
     
      _compiler = new JspCompiler();
      _compiler.setWebApp(_webApp);
    }

    public void run()
    {
      try {
        while (compilePath()) {
        }
     
        while (compileClasses()) {
        }
      } finally {
        synchronized (JspPrecompileResource.this) {
          _completeCount++;

          JspPrecompileResource.this.notifyAll();
        }
      }
    }

    private boolean compilePath()
    {
      String contextPath = _webApp.getContextPath();
      if (! contextPath.endsWith("/"))
        contextPath = contextPath + "/";
   
      Path pwd = Vfs.lookup();
      Path path = null;

      synchronized (_paths) {
        if (_paths.size() == 0)
          return false;

        path = _paths.remove(0);
      }

      String uri = path.getPath().substring(pwd.getPath().length());

      if (_webApp.getContext(contextPath + uri) != _webApp)
        return true;

      String className = JspCompiler.urlToClassName(uri);

      try {
        CauchoPage page = (CauchoPage) _compiler.loadClass(className, true);

        page.init(pwd);

        if (! page._caucho_isModified()) {
          log.fine("pre-loaded " + uri);
          return true;
        }
      } catch (ClassNotFoundException e) {
      } catch (Throwable e) {
        log.log(Level.FINER, e.toString(), e);
      }

      log.fine("compiling " + uri);
     
      try {
        JspCompilerInstance compilerInst;
        compilerInst = _compiler.getCompilerInstance(path, uri, className);

        JspGenerator generator = compilerInst.generate();

        if (generator.isStatic())
          return true;

        LineMap lineMap = generator.getLineMap();

        synchronized (_classes) {
          _classes.add(className.replace('.', '/') + ".java");
        }
      } catch (Exception e) {
        if (e instanceof CompileException)
          log.warning(e.getMessage());
        else
          log.log(Level.WARNING, e.toString(), e);
      }

      return true;
    }

    private boolean compileClasses()
    {
      String []files;
     
      synchronized (_classes) {
        if (_classes.size() == 0)
          return false;

        files = new String[_classes.size()];
        _classes.toArray(files);
        _classes.clear();
      }

      try {
        JavaCompiler javaCompiler = JavaCompiler.create(null);
        javaCompiler.setClassDir(_compiler.getClassDir());

        javaCompiler.compileBatch(files);
      } catch (Exception e) {
        if (e instanceof CompileException)
          log.warning(e.getMessage());
        else
          log.log(Level.WARNING, e.toString(), e);
      }

      return true;
    }
  }
}
TOP

Related Classes of com.caucho.jsp.JspPrecompileResource

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.