Skip to content

Instantly share code, notes, and snippets.

@yokolet
Created September 27, 2011 15:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save yokolet/1245405 to your computer and use it in GitHub Desktop.
Save yokolet/1245405 to your computer and use it in GitHub Desktop.
package chestnut
import java.io.{File, IOException}
import java.util.{ArrayList, List}
import javax.servlet.{ServletConfig, ServletException}
import javax.servlet.annotation.WebServlet
import javax.servlet.http.{HttpServlet, HttpServletRequest => HSReq, HttpServletResponse => HSResp}
import org.jruby.embed.{LocalContextScope, ScriptingContainer => Container}
import scala.collection.JavaConversions._
import scala.collection.mutable.ListBuffer
class HelloSinatra extends HttpServlet() {
private val gemPaths = new ListBuffer[String]
private var config: ServletConfig = _
private val container = new Container(LocalContextScope.THREADSAFE)
private var config_ru_path: String = _
def addGemPaths(gem_path: String) {
val gem_dir = new File(gem_path)
val gems = gem_dir.listFiles
for (gem <- gems) {
val path = gem + "/lib"
gemPaths += path
}
}
override def init(c: ServletConfig) {
config = c
val path = config.getServletContext().getRealPath("/WEB-INF/lib/vendor/jruby/1.8/gems")
addGemPaths(path)
gemPaths += config.getServletContext().getRealPath("/WEB-INF/lib/app")
config_ru_path = config.getServletContext().getRealPath("/WEB-INF/lib/app/config.ru")
}
override def doGet(request: HSReq, response: HSResp) = processHttpRequest(request, response)
override def doPost(request: HSReq, response: HSResp) = processHttpRequest(request, response)
private def processHttpRequest(request: HSReq, response: HSResp) {
container.setLoadPaths(gemPaths)
container.runScriptlet("require 'rubygems'")
container.put("config_ru_path", config_ru_path);
container.put("request", request);
container.put("config", config);
val script =
"""require 'rack'
rack_app, options = Rack::Builder.parse_file config_ru_path
require 'jruby-rack'
require 'rack/handler/servlet'
handler = Rack::Handler::Servlet.new rack_app
request.instance_variable_set(:@context, config.getServletContext)
class << request
def to_io
self.getInputStream.to_io
end
def getScriptName
self.getPathTranslated
end
def context
@context
end
end
handler.call(request)"""
var rack_response = container.runScriptlet(script);
var body : String = container.callMethod(rack_response, "getBody").asInstanceOf[String]
body += "\n\n\nand Hello from Scala Servlet!!"
response.getWriter().print(body);
container.clear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment