package org.appfuse.webapp.action;

import org.appfuse.model.User;
import org.appfuse.dao.UserDAO;
import org.appfuse.fop.UserInputSource;
import org.appfuse.fop.UserXMLReader;

import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;
import org.apache.fop.apps.Driver;
import org.apache.fop.apps.XSLTInputHandler;
import org.apache.fop.apps.TraxInputHandler;
import org.apache.fop.messaging.MessageHandler;

import java.io.*;
import java.util.Date;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.support.ServletContextResource;
import org.springframework.core.io.*; 
import org.xml.sax.InputSource;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;

/**
 * Implementation of <strong>HttpServlet</strong> that is used
 * to autogenerate a PDF document.
 *
 * <p><a href="FopServlet.java.html"><i>View Source</i></a></p>
 *
 * @author <a href="mailto:mailto:ben@jazzyphones.com">Ben Gill</a>
 * @version $Revision: 1.1 $ $Date: 2005/03/12 17:46:09 $
 *
 * @web.servlet
 *     display-name="Fop Servlet"
 *     load-on-startup="1"
 *     name="fop"
 *
 * @web.servlet-mapping
 *     url-pattern="/fop/*"
 */

public class FopServlet extends HttpServlet {
	
    private Logger logger = null;    
    private ApplicationContext ctx = null;
    private ServletContext servletContext = null;
    

    public void init() throws ServletException {
    	this.servletContext = getServletContext();
    	this.ctx =  
    		WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
    }

    /**
     * Route the user to the execute method
     *
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
        execute(request, response);
    }

    /**
     * Route the user to the execute method
     *
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
        execute(request, response);
    }

    /**
     * Process the specified HTTP request, and create the corresponding HTTP
     * response (or forward to another web component that will create it).
     *
     * @param request The HTTP request we are processing
     * @param response The HTTP response we are creating
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet exception occurs
     */
    public void execute(HttpServletRequest request, HttpServletResponse response)
        throws IOException, ServletException {
    	
    	ByteArrayOutputStream out = null;
    	
    	try {
            String userName = request.getParameter("userName");
        	
            UserDAO dao = (UserDAO)ctx.getBean("userDAO");
            User user = dao.getUser(userName);
            
	    Driver driver = new Driver();
	    Logger logger = new ConsoleLogger(ConsoleLogger.LEVEL_INFO);
	    driver.setLogger(logger);
	    MessageHandler.setScreenLogger(logger);
	    driver.setRenderer(Driver.RENDER_PDF);
	        
            out = new ByteArrayOutputStream();
            driver.setOutputStream(out);

            ServletContextResource resource = 
		new ServletContextResource(servletContext, 
		"/WEB-INF/classes/org/appfuse/webapp/fop/user2fo.xsl");
            File xslFile = resource.getFile();
            
            //Setup XSLT
            TransformerFactory factory = TransformerFactory.newInstance();
            Transformer transformer = factory.newTransformer(new StreamSource(xslFile));
        
            //Setup input for XSLT transformation
            Source src = new UserInputSource(user).getSource();
        
            //Resulting SAX events (the generated FO) must be piped through to FOP
            Result res = new SAXResult(driver.getContentHandler());

            //Start XSLT transformation and FOP processing
            transformer.transform(src, res);
            
            byte[] content = out.toByteArray();
            response.setContentType("application/pdf");
            response.setContentLength(content.length);
            response.getOutputStream().write(content);
            response.getOutputStream().flush();
            
        } catch (Exception e) {
            throw new ServletException(e);
        } finally {
        	if (out!=null) {
        		out.close();
        	}
        }
    }
}
