/* * Copyright 2011 Future Systems * * 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.krakenapps.webfx; import groovy.lang.GroovyShell; import groovy.util.GroovyScriptEngine; import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.util.Date; import java.util.HashMap; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.osgi.framework.BundleContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class DispatcherServlet extends HttpServlet { private static final long serialVersionUID = 1L; private final Logger logger = LoggerFactory.getLogger(DispatcherServlet.class.getName()); private File baseDir; private BundleContext bc; private GroovyScriptEngine engine; private GroovyShell shell; private Map<String, Object> data; private Router router; public DispatcherServlet(BundleContext bc, File baseDir) { this.bc = bc; this.baseDir = baseDir; this.router = new Router(); } public void start() throws IOException { File controllerDir = new File(baseDir, "app/controllers"); engine = new GroovyScriptEngine(new String[] { controllerDir.getAbsolutePath() }); engine.getGroovyClassLoader().setShouldRecompile(true); shell = new GroovyShell(engine.getGroovyClassLoader()); data = new HashMap<String, Object>(); data.put("linkTo", shell.evaluate("def c = { s -> controller.linkTo(s) } ")); data.put("include", shell.evaluate("def c = { s -> controller.include(s) } ")); data.put("osgi", shell.evaluate("def c = { s -> controller.osgi(s) }")); data.put("yield", shell.evaluate("def c = { s -> controller.yield(s) }")); data.put("bc", bc); } public void stop() { engine.getGroovyClassLoader().clearCache(); } public Router getRouter() { return router; } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { logger.trace("kraken webfx: GET request [{}]", req.getPathInfo()); Date begin = new Date(); invokeGroovy(req, resp, begin); long elapsed = new Date().getTime() - begin.getTime(); logger.trace("kraken webfx: request [{}], {}ms used", req.getRequestURI(), elapsed); } catch (Exception e) { e.printStackTrace(); } } private void invokeGroovy(HttpServletRequest req, HttpServletResponse resp, Date begin) throws Exception { ControllerAction action = router.map(req.getPathInfo()); if (action == null) { logger.trace("kraken webfx: mapping not found [{}]", req.getPathInfo()); return; } Map<String, Object> d = new HashMap<String, Object>(data); d.put("controller", action.getController()); d.put("action", action.getAction()); String name = action.getController() + "Controller"; Class<?> clazz = engine.getGroovyClassLoader().loadClass(name, true, false, true); Controller controller = (Controller) clazz.newInstance(); controller.init(bc, shell, baseDir, d, req, resp); Method m = controller.getClass().getMethod(action.getAction()); m.invoke(controller); } }