package org.h3270.web; /* * Copyright (C) 2003-2008 akquinet tech@spree * * This file is part of h3270. * * h3270 is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * h3270 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with h3270; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, * MA 02110-1301 USA */ import java.io.File; import java.io.IOException; import java.net.*; import java.util.Iterator; import javax.servlet.ServletException; import javax.servlet.http.*; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; import org.h3270.host.*; import org.h3270.logicalunit.*; import org.h3270.render.*; /** * @author Andre Spiegel spiegel@gnu.org * @version $Id: Servlet.java,v 1.36 2008/11/21 14:50:33 spiegel Exp $ */ public class Servlet extends AbstractServlet { private static final long serialVersionUID = 1L; private static final String STYLE_JSP = "/screen.jsp"; private static final String DEFAULT_JSP = "/simple-screen.jsp"; private String targetHost; private boolean autoconnect; private String execPath; private String templateDir; private final HtmlRenderer basicRenderer = new HtmlRenderer(); private Engine engine = null; private H3270Configuration configuration; private String mainJSP = DEFAULT_JSP; private LogicalUnitPool logicalUnitPool; public void init() throws ServletException { super.init(); configuration = getConfiguration(); Configuration styleConfig = configuration.getChild("style"); try { if (styleConfig.getValue() != null) { mainJSP = STYLE_JSP; } } catch (ConfigurationException e) { logger.info("Set main jsp to default"); } targetHost = configuration.getChild("target-host").getValue(null); if (targetHost != null) { autoconnect = configuration.getChild("target-host") .getAttributeAsBoolean("autoconnect", false); } Configuration dirConfig = configuration.getChild("template-dir"); templateDir = getRealPath(dirConfig.getValue("/WEB-INF/templates")); engine = new Engine(templateDir); execPath = configuration.getChild("exec-path").getValue("/usr/local/bin"); logicalUnitPool = LogicalUnitPoolFactory .createLogicalUnitPool(configuration); if (logicalUnitPool != null) { getServletContext().setAttribute(LogicalUnitPool.SERVLET_CONTEXT_KEY, logicalUnitPool); } if (logger.isDebugEnabled()) { logger.info("Using main JSP: " + mainJSP); logger.info("Set template-dir to " + templateDir); logger.info("Set exec-path to " + execPath); logger.info("Use Logical Unit Pool " + (logicalUnitPool != null)); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { SessionState state = getSessionState(request); if (state.getTerminal(request) == null && autoconnect) { connect(request, state, targetHost); } if (state.getTerminal(request) != null) { state.getTerminal(request).updateScreen(); Screen s = state.getTerminal(request).getScreen(); Renderer r = (state.useRenderers() && engine.canRender(s)) ? (Renderer) engine : (Renderer) basicRenderer; state.setScreen(request, r.render(s, "", state.getTerminalId(request))); } getServletContext().getRequestDispatcher(mainJSP) .forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { SessionState state = getSessionState(request); state.setException(request, null); handlePreferences(state, request, response); Terminal terminal = state.getTerminal(request); if (request.getParameter("connect") != null) { String hostname = (targetHost == null) ? request.getParameter("hostname") : targetHost; // TODO message to user if no hostname specified if (!hostname.equals("")) { connect(request, state, hostname); } } else if (request.getParameter("disconnect") != null) { disconnect(request, state, terminal); } else if (request.getParameter("refresh") != null) { terminal.updateScreen(); } else if (request.getParameter("dumpfile") != null && !request.getParameter("dumpfile").equals("")) { String filename = new File(getRealPath("/WEB-INF/dump"), request .getParameter("dumpfile")).toString(); terminal.dumpScreen(filename); } else if (request.getParameter("keypad") != null) { state.useKeypad(request, !state.useKeypad(request)); } else if (terminal != null) { submitScreen(request); String key = request.getParameter("key"); if (key != null) terminal.doKey(key); } doGet(request, response); } private void disconnect(HttpServletRequest request, SessionState state, Terminal terminal) { if (terminal != null) terminal.disconnect(); String logicalUnit = terminal.getLogicalUnit(); releaseLogicalUnit(logicalUnit); state.setTerminal(request, null); state.setScreen(request, null); } private void connect(HttpServletRequest request, SessionState state, String hostname) throws IOException, MalformedURLException { try { if (logger.isInfoEnabled()) { logger.info("Connecting to " + hostname); } if (hostname.startsWith("file:")) { String filename = new File(getRealPath("/WEB-INF/dump"), hostname .substring(5)).toString(); state.setTerminal(request, new FileTerminal(new URL("file:" + filename))); } else { state.setTerminal(request, new S3270(leaseLogicalUnit(), hostname, configuration)); } state.useKeypad(request, false); } catch (Exception ex) { state.setException(request, ex); } } private String leaseLogicalUnit() throws LogicalUnitException { if (logicalUnitPool != null) { return logicalUnitPool.leaseLogicalUnit(); } return null; } private void releaseLogicalUnit(String logicalUnit) { if (logicalUnit != null) { logicalUnitPool.releaseLogicalUnit(logicalUnit); } } /** * If any preferences have been changed by the user in this request, take the * appropriate action. */ private void handlePreferences(SessionState state, HttpServletRequest request, HttpServletResponse response) throws IOException { String colorscheme = request.getParameter("colorscheme"); String render = request.getParameter("render"); String font = request.getParameter("font"); boolean modified = false; response.setContentType("text/html"); if (colorscheme != null) { colorscheme = URLDecoder.decode(request.getParameter("colorscheme"), "UTF-8"); modified = state.setActiveColorScheme(request, colorscheme); } if (render != null) { if (render.equals("true")) { if (!state.useRenderers()) { engine = new Engine(templateDir); } state.useRenderers(true); } else if (render.equals("false")) { state.useRenderers(false); } modified = true; } if (font != null && !font.equals("")) { state.setFontName(font); modified = true; } if (modified) { Cookie cookie = new Cookie(SessionState.COOKIE_NAME, state .getSavedState()); if (logger.isDebugEnabled()) { logger.debug("Sending Cookie: " + state); } cookie.setMaxAge(Integer.MAX_VALUE); response.addCookie(cookie); } } /** * Gets the input field parameters from the request and fills them into the * Fields of the Screen, then submits them back to s3270. */ private void submitScreen(HttpServletRequest request) throws IOException { SessionState state = getSessionState(request); Screen s = state.getTerminal(request).getScreen(); if (s.isFormatted()) { for (Iterator i = s.getFields().iterator(); i.hasNext();) { Field f = (Field) i.next(); if (f instanceof InputField) { if (!f.isMultiline()) { String value = request.getParameter("field_" + f.getStartX() + "_" + f.getStartY()); if (value != null) { ((InputField) f).setValue(value); } } else { // multi-line field for (int j = 0; j < f.getHeight(); j++) { String value = request.getParameter("field_" + f.getStartX() + "_" + f.getStartY() + "_" + j); if (value != null) { ((InputField) f).setValue(j, value); } } } } } state.getTerminal(request).submitScreen(); } else { state.getTerminal(request).submitUnformatted( (String) request.getParameter("field")); } } /** * Returns the SessionState object that is associated with the given request, * creates the object if it doesn't already exist. */ private SessionState getSessionState(HttpServletRequest request) throws IOException { boolean forceNewSession = request.getParameter("dump.session") != null; HttpSession session = request.getSession(forceNewSession); if (session == null) { session = request.getSession(); } if (this.targetHost != null) { String targetHost = (String) session.getAttribute("targetHost"); if (targetHost == null) { session.setAttribute("targetHost", this.targetHost); } } SessionState result = (SessionState) session.getAttribute("sessionState"); if (result == null) { String savedState = getSavedSessionState(request); result = new SessionState(configuration, savedState); session.setAttribute("sessionState", result); } return result; } private String getSavedSessionState(HttpServletRequest request) { Cookie cookie = getCookie(request); if (cookie != null) { return cookie.getValue(); } return ""; } private Cookie getCookie(HttpServletRequest request) { Cookie[] cookies = request.getCookies(); if (cookies != null) { for (int x = 0; x < cookies.length; ++x) { if (SessionState.COOKIE_NAME.equals(cookies[x].getName())) { return cookies[x]; } } } return null; } }