Package org.onemind.swingweb.servlet

Source Code of org.onemind.swingweb.servlet.AbstractSwingWebServlet$RenderCallBack

/*
* Copyright (C) 2004 TiongHiang Lee
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not,  write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* Email: thlee@onemindsoft.org
*/

package org.onemind.swingweb.servlet;

import java.io.*;
import java.net.URLEncoder;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.apache.commons.fileupload.DiskFileUpload;
import org.onemind.awtbridge.BridgeContextSession;
import org.onemind.awtbridge.session.SessionLifecycleListener;
import org.onemind.commons.java.util.*;
import org.onemind.commons.java.xml.digest.SaxDigesterHandler;
import org.onemind.jxp.*;
import org.onemind.swingweb.*;
import org.onemind.swingweb.resource.Resource;
import org.onemind.swingweb.session.SwingWebSession;
import org.onemind.swingweb.session.URLLocal;
import org.onemind.swingweb.util.ComponentOptions;
/**
* A Abstract Servlet for initializing the swingweb application. There's only two parameter needed
* for the application: <br>
* <ul>
*     <li>app-class - the application class </li>
*     <li>swingweb-config - the swing web configuration </li>
* </ul>
*
* @author TiongHiang Lee (thlee@onemindsoft.org)
*
*/
public abstract class AbstractSwingWebServlet extends HttpServlet implements SessionLifecycleListener
{

    /** the logger * */
    private static final Logger _logger = Logger.getLogger(AbstractSwingWebServlet.class.getName());

    public static final String KEY_SWCONTEXTS = "SwingWebContexts";

    private static final String KEY_APP_CLASS = "app-class";

    private static final String KEY_CONFIG = "swingweb-config";

    private static final String KEY_ENCODING = "char-encoding";

    private static final String KEY_GET_AFTER_POST = "get-after-post";

    private static final String KEY_TEMPLATE_CONTENT = "content-template";

    private static final String KEY_TEMPLATE_SESSION_ENDED = "session-ended-template";

    private static final String KEY_COMPONENT_OPTIONS = "component-options-config";

    /** the application to start **/
    private String _appClass;

    /** the session ended message **/
    private String _sessionEndedMessage;

    /** redirect to get after post **/
    private boolean _getAfterPost = true;

    /** the upload **/
    private DiskFileUpload _uploadRepository;

    /** the swing web manager **/
    private SwingWebAppManager _manager;

    /** the encoding **/
    private String _charEncoding;

    /** the sessions **/
    private WeakHashMap _sessions = new WeakHashMap();

    /** the jxp processor **/
    private JxpProcessor _processor;

    /** the context template **/
    private String _contentTemplate;

    /** the session end template **/
    private String _sessionEndTemplate;

    /** the component options **/
    private ComponentOptions _comOpts;

    /** the component options file **/
    private File _comOptsFile;

    /** a callback to pass to the template for rendering **/
    public interface CallBack
    {

        public void call() throws Exception;
    }

    class RenderCallBack implements CallBack
    {

        Writer _writer;

        public RenderCallBack(Writer writer)
        {
            _writer = writer;
        }

        public void call() throws Exception
        {
            _manager.renderOutput(_writer);
        }
    };

    class InputRenderCallBack extends RenderCallBack
    {

        Map _form;

        public InputRenderCallBack(Writer writer, Map form)
        {
            super(writer);
            _form = form;
        }

        public void call() throws Exception
        {
            _manager.handleInput(_form);
            _manager.renderOutput(_writer);
        }
    };

    /**
     * {@inheritDoc}
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        doPost(req, resp);
    }

    public String getConfig(ServletConfig config, String key, String def)
    {
        String value = config.getInitParameter(key);
        if (value == null)
        {
            value = def;
        }
        return value;
    }

    /**
     * {@inheritDoc}
     */
    public void init(ServletConfig config) throws ServletException
    {
        super.init(config);
        //make it run swingweb
        System.getProperties().put("awt.toolkit", "org.onemind.swingweb.SwingWebToolkit");
        LogUtils.initLoggingFromClassPath();
        _appClass = config.getInitParameter(KEY_APP_CLASS);
        String swConfig = config.getInitParameter(KEY_CONFIG);
        _charEncoding = getConfig(config, KEY_ENCODING, "UTF-8");
        _getAfterPost = ObjectUtils.toBool(config.getInitParameter(KEY_GET_AFTER_POST), true);
        // create a new file upload handler
        _uploadRepository = new DiskFileUpload();
        // set upload parameters
        _uploadRepository.setRepositoryPath(System.getProperty("java.io.tmpdir")); //TODO: make become configurable setting
        //_uploadRepository.setSizeThreshold(1000000); //file > 1 meg write to disk
        _uploadRepository.setSizeThreshold(0); //write any file to disk
        _uploadRepository.setSizeMax(-1); //no maximum size
        _comOpts = loadComponentOptions(config);
        try
        {
            _manager = new SwingWebAppManager(new FileInputStream(getServletContext().getRealPath(swConfig)));
            synchronized (KEY_SWCONTEXTS)
            {
                Set contextSet = (Set) getServletContext().getAttribute(KEY_SWCONTEXTS);
                if (contextSet == null)
                {
                    contextSet = new HashSet();
                    getServletContext().setAttribute(KEY_SWCONTEXTS, contextSet);
                }
                contextSet.add(_manager.getContext());
            }
            _contentTemplate = getConfig(config, KEY_TEMPLATE_CONTENT, "/org/onemind/swingweb/servlet/swingweb-app-content.jxp");
            _sessionEndTemplate = getConfig(config, KEY_TEMPLATE_SESSION_ENDED,
                    "/org/onemind/swingweb/servlet/swingweb-app-session-ended.jxp");
        } catch (Exception e)
        {
            throw new ServletException("Cannot init swingweb servlet", e);
        }
    }

    private ComponentOptions loadComponentOptions(ServletConfig config) throws ServletException
    {
        String configFile = config.getInitParameter(KEY_COMPONENT_OPTIONS);
        if (configFile == null)
        {
            throw new ServletException(KEY_COMPONENT_OPTIONS + " must be configured");
        }
        File comOptsFile = new File(getServletContext().getRealPath(configFile));
        if (comOptsFile.exists())
        {
            try
            {
                SaxDigesterHandler handler = new SaxDigesterHandler();
                ComponentOptions comOpts = new ComponentOptions();
                handler.addDigester(comOpts);
                handler.parse(new FileInputStream(comOptsFile));
                _comOptsFile = comOptsFile;
                return comOpts;
            } catch (Exception ex)
            {
                throw new ServletException("Unable to initialize " + KEY_COMPONENT_OPTIONS + comOptsFile.getAbsolutePath(), ex);
            }
        } else
        {
            throw new ServletException(KEY_COMPONENT_OPTIONS + comOptsFile.getAbsolutePath() + " does not exist");
        }
    }

    /**
     * Get the processor
     * @param req the request
     * @return the processor
     * @throws Exception
     */
    private JxpProcessor getProcessor(HttpServletRequest req)
    {
        if (_processor == null)
        {
            synchronized (this)
            {
                MultiSourcePageSource multisource = new MultiSourcePageSource();
                FilePageSource filesource = new FilePageSource(req.getRealPath("/"), _charEncoding);
                filesource.setModCheck(true);
                filesource.setCaching(true);
                multisource.addPageSource(filesource);
                ResourceStreamPageSource streamsource = new ResourceStreamPageSource("/");
                multisource.addPageSource(streamsource);
                _processor = new JxpProcessor(new JxpContext(multisource));
            }
        }
        return _processor;
    }

    /**
     * {@inheritDoc}
     */
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
    {
        resp.setContentType("text/html; charset=" + _charEncoding);
        resp.setStatus(200, "OK");
        if (_appClass == null)
        {
            PrintWriter writer = resp.getWriter();
            writer.write("No application is configured at this url");
            writer.flush();
            writer.close();
        } else
        {
            //TODO: decide whether this environment need to be passed on      
            Map env = new HashMap();
            env.putAll(ServletUtils.getServletEnvironment(getServletConfig()));
            env.putAll(ServletUtils.getRequestEnvironment(req));
            env.putAll(ServletUtils.getExtraRequestEnvironment(req));
            PrintWriter writer = null;
            try
            {
                Map form = ServletUtils.getRequestParameters(req, _uploadRepository);
                if (form.containsKey("swresource"))
                {
                    sendResource(req, resp, (String) form.get("swresource"));
                } else
                {
                    String uri = req.getRequestURI();
                    HttpSession session = req.getSession(true);
                    writer = resp.getWriter();
                    Object obj = session.getValue(uri);
                    if (obj instanceof Boolean)
                    {//session ended
                        renderWithTemplate(req, null, _sessionEndTemplate, form, writer, null);
                        session.removeAttribute(uri);
                    } else
                    {
                        try
                        {
                            SwingWebSession swSession = (SwingWebSession) obj;
                            if (swSession == null)
                            {
                                swSession = (SwingWebSession) createSession(_manager.getContext(), session);
                                swSession.addListener(this);
                                swSession.putValue("SWINGWEB_SESSION_ID", String.valueOf(System.currentTimeMillis()));
                                session.setAttribute(uri, swSession);
                                swSession.putAllValues(env);
                                swSession.putValue("HTTP_FORM", form);
                                swSession.putValue("HTTP_SESSION", session);
                                swSession.putValue("COMPONENT_OPTIONS_CONFIG", _comOptsFile.getAbsolutePath());
                                swSession.putValue("COMPONENT_OPTIONS", _comOpts);
                                _sessions.put(swSession, session);
                                _manager.setCurrentSession(swSession);
                                startApp(swSession, req, resp);
                            } else
                            {
                                swSession.putAllValues(env);
                                swSession.putValue("COMPONENT_OPTIONS_CONFIG", _comOptsFile.getAbsolutePath());
                                swSession.putValue("COMPONENT_OPTIONS", _comOpts);
                                swSession.putValue("HTTP_FORM", form);
                                swSession.putValue("HTTP_SESSION", session);
                                _manager.setCurrentSession(swSession);
                            }
                            if (_getAfterPost)
                            {
                                if (req.getMethod().equalsIgnoreCase("GET"))
                                {
                                    assertURLLocals(swSession, req);
                                    renderWithTemplate(req, swSession, _contentTemplate, form, writer, new RenderCallBack(writer));
                                } else
                                {
                                    _manager.handleInput(form);
                                    StringBuffer url = new StringBuffer(uri);
                                    String queryString = constructURLFromURLLocals(swSession, req);
                                    if (queryString.length() > 0)
                                    {
                                        url.append("?");
                                        url.append(queryString);
                                    }
                                    //                            url.append("&");
                                    //                            url.append(System.currentTimeMillis());
                                    resp.sendRedirect(url.toString());
                                }
                            } else
                            {
                                renderWithTemplate(req, swSession, _contentTemplate, form, writer, new InputRenderCallBack(writer,
                                        form));
                            }
                        } finally
                        {
                            _manager.setCurrentSession(null);
                        }
                    }
                }
            } catch (IOException e)
            {
                _logger.severe(LogUtils.getTrace(e));
                if (writer != null)
                {
                    e.printStackTrace(writer);
                }
            } catch (Exception e)
            {
                //e.printStackTrace(writer);
                _logger.severe(LogUtils.getTrace(e));
                if (writer != null)
                {
                    e.printStackTrace(writer);
                }
            }
            if (writer != null)
            {
                writer.flush();
            }
            resp.flushBuffer();
            if (_logger.isLoggable(Level.FINEST))
            {
                _logger.finest("Done handling request");
            }
        }
    }

    private void renderWithTemplate(HttpServletRequest req, SwingWebSession swSession, String templateName, Map form,
            Writer writer, CallBack callBack) throws Exception
    {
        JxpProcessor processor = getProcessor(req);
        Map env = new HashMap();
        env.put("request", req);
        env.put("writer", writer);
        env.put("form", form);
        env.put("callBack", callBack);
        env.put("swSession", swSession);
        env.put("session", req.getSession());
        processor.process(templateName, writer, env);
    }

    protected void generateEnvironment()
    {
    }

    protected abstract SwingWebSession createSession(SwingWebContext context, HttpSession session);

    protected abstract void startApp(SwingWebSession swSession, HttpServletRequest req, HttpServletResponse resp) throws Exception;

    private String constructURLFromURLLocals(SwingWebSession swSession, HttpServletRequest req)
    {
        StringBuffer sb = new StringBuffer();
        SwingWebComponentManager man = (SwingWebComponentManager) swSession.getComponentManager();
        List urlLocals = man.getURLLocals();
        Iterator it = urlLocals.iterator();
        boolean isFirst = true;
        while (it.hasNext())
        {
            URLLocal local = (URLLocal) it.next();
            String value = local.getSetValue();
            if (value != null)
            {
                if (isFirst)
                {
                    isFirst = false;
                } else
                {
                    sb.append("&");
                }
                sb.append(URLEncoder.encode(local.getName()));
                sb.append("=");
                sb.append(URLEncoder.encode(value));
            } else if (local.isAlwaysShow())
            {
                if (isFirst)
                {
                    isFirst = false;
                } else
                {
                    sb.append("&");
                }
                sb.append(URLEncoder.encode(local.getName()));
                sb.append("=");
                sb.append(URLEncoder.encode((String) local.getValue()));
            }
        }
        return sb.toString();
    }

    private static void assertURLLocals(SwingWebSession swSession, HttpServletRequest req)
    {
        Map param = req.getParameterMap();
        SwingWebComponentManager man = (SwingWebComponentManager) swSession.getComponentManager();
        List urlLocals = man.getURLLocals();
        Iterator it = urlLocals.iterator();
        while (it.hasNext())
        {
            URLLocal local = (URLLocal) it.next();
            Object value = param.get(local.getName());
            if (value instanceof String[])
            {
                value = ((String[]) value)[0];
            }
            String paramValue = (String) value;
            local.setValue(paramValue);
        }
    }

    /**
     * Send the resource
     * @param resp
     * @param object
     */
    private void sendResource(HttpServletRequest req, HttpServletResponse resp, String id)
    {
        Resource res = _manager.getContext().getResource(id);
        if (res != null)
        {
            try
            {
                resp.setContentType(res.getType());
                resp.setStatus(200, "Ok");
                OutputStream out = new BufferedOutputStream(resp.getOutputStream());
                FileUtils.copyStream(res.getInputStream(), out, 1024);
                out.flush();
            } catch (Exception e)
            {
                _logger.throwing(getClass().getName(), "sendResource", e);
            }
        } else
        {
            resp.setContentType("text/html");
            resp.setStatus(404, "Resource not found");
        }
    }

    public final SwingWebAppManager getManager()
    {
        return _manager;
    }

    public final String getAppClass()
    {
        return _appClass;
    }

    public void sessionDestroyed(HttpSessionEvent evt)
    {
        //close up swingweb sessions when httpsession ended
        if (_manager != null)
        {
            HttpSession session = evt.getSession();
            Enumeration names = session.getAttributeNames();
            while (names.hasMoreElements())
            {
                String name = (String) names.nextElement();
                Object value = session.getAttribute(name);
                if (value instanceof SwingWebSession)
                {
                    SwingWebSession swSession = ((SwingWebSession) value);
                    _manager.setCurrentSession(swSession);
                    try
                    {
                        swSession.close();
                    } finally
                    {
                        _manager.setCurrentSession(null);
                    }
                }
            }
        }
    }

    public void sessionEnded(BridgeContextSession session)
    {
        //This will be called by Session.close()
        HttpSession httpSession = (HttpSession) _sessions.remove(session);
        if (httpSession != null)
        {
            Enumeration names = httpSession.getAttributeNames();
            while (names.hasMoreElements())
            {
                String name = (String) names.nextElement();
                if (httpSession.getAttribute(name) == session)
                {
                    httpSession.removeAttribute(name);
                    httpSession.setAttribute(name, Boolean.FALSE);
                }
            }
        }
    }
}
TOP

Related Classes of org.onemind.swingweb.servlet.AbstractSwingWebServlet$RenderCallBack

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.