/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 example;

import java.io.*;
import java.util.*;
import java.lang.reflect.*;
import javax.servlet.*;
import javax.servlet.http.*;
import freemarker.template.*;
import freemarker.ext.beans.BeansWrapper;


/**
 * <p>This is very very primitive MVC Controller servlet base class, based
 * on example 1. The application specific controller servlet should extend
 * this class.
 */
public class ControllerServlet extends HttpServlet {

    // Volatile so that it's properly published according to JSR 133 (JMM).
    // Although, the servlet container most certainly makes this unnecessarry.
    private volatile Configuration cfg; 
    
    public void init() {
        // Initialize the FreeMarker configuration;
        // - Create a configuration instance, with the not-100%-backward-compatible
        //   fixes up until FreeMarker 2.3.21 applied (as far as it starts
        //   with 2.3, these are only minor changes that doesn't affect most apps):
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_21);
        // - Templates are stoted in the WEB-INF/templates directory of the Web app.
        cfg.setServletContextForTemplateLoading(
                getServletContext(), "WEB-INF/templates");
        // - At most how often should FreeMarker check if a template was updated:
        cfg.setTemplateUpdateDelay(isInDevelopmentMode() ? 0 : 60);
        // - When developing, set an error handler that prints errors so they are
        //   readable with a Web browser, otherwise we just let the HTTP 500
        //   handler deal with it.
        cfg.setTemplateExceptionHandler(
                isInDevelopmentMode()
                        ? TemplateExceptionHandler.HTML_DEBUG_HANDLER
                        : TemplateExceptionHandler.RETHROW_HANDLER);
        // - Set the default charset of the template files
        cfg.setDefaultEncoding("ISO-8859-1");
        // - Set the charset of the output. This is actually just a hint, that
        //   templates may require for URL encoding and for generating META
        //   element that uses http-equiv="Content-type".
        cfg.setOutputEncoding("UTF-8");
        // - Set the default locale
        cfg.setLocale(Locale.US);
        
        // Finished modifying cfg, so let's publish it to other threads:
        this.cfg = cfg;
    }
    
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        doGet(req, resp);
    }
    
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        
        // Choose action method
        String action = req.getServletPath();
        if (action == null) action = "index";
        if (action.startsWith("/")) action = action.substring(1);
        if (action.lastIndexOf(".") != -1) {
            action = action.substring(0, action.lastIndexOf("."));
        }
        Method actionMethod;
        try {
            actionMethod =
                    getClass().getMethod(action + "Action",
                    new Class[]{HttpServletRequest.class, Page.class});
        } catch (NoSuchMethodException e) {
            throw new ServletException("Unknown action: " + action);
        }
        
        // Set the request charset to the same as the output charset,
        // because HTML forms normally send parameters encoded with that.
        req.setCharacterEncoding(cfg.getOutputEncoding());
        
        // Call the action method
        Page page = new Page();
        try {
            actionMethod.invoke(this, new Object[]{req, page});
        } catch (IllegalAccessException e) {
            throw new ServletException(e);
        } catch (InvocationTargetException e) {
            throw new ServletException(e.getTargetException());
        }
        
        if (page.getTemplate() != null) { // show a page with a template
            // Get the template object
            Template t = cfg.getTemplate(page.getTemplate());
            
            // Prepare the HTTP response:
            // - Set the MIME-type and the charset of the output.
            //   Note that the charset should be in sync with the output_encoding setting.
            resp.setContentType("text/html; charset=" + cfg.getOutputEncoding());
            // - Prevent browser or proxy caching the page.
            //   Note that you should use it only for development and for interactive
            //   pages, as it significantly slows down the Web site.
            resp.setHeader("Cache-Control", "no-store, no-cache, must-revalidate, "
                    + "post-check=0, pre-check=0");
            resp.setHeader("Pragma", "no-cache");
            resp.setHeader("Expires", "Thu, 01 Dec 1994 00:00:00 GMT");
            Writer out = resp.getWriter();
            
            // Merge the data-model and the template
            try {
                t.process(page.getRoot(), out);
            } catch (TemplateException e) {
                throw new ServletException(
                        "Error while processing FreeMarker template", e);
            }
        } else if (page.getForward() != null) { // forward request
            RequestDispatcher rd = req.getRequestDispatcher(page.getForward());
            rd.forward(req, resp);            
        } else {
            throw new ServletException("The action didn't specified a command.");
        }
    }
    
    private boolean isInDevelopmentMode() {
        // FIXME: Should detect this with a system property for example.
        return true;
    }
    
}