diff options
author | mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2010-07-14 15:22:56 +0000 |
---|---|---|
committer | mcentner <mcentner@8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4> | 2010-07-14 15:22:56 +0000 |
commit | 5e10b6b575993c78ac22191849c464b618c4fa8a (patch) | |
tree | 55911c2b6d69e787dd408d63c1e641d6db39c5dc /BKUOnline/src/main/java/at/gv/egiz/bku | |
parent | dc95c76a126b4f3135645d3e20b152134d201244 (diff) | |
download | mocca-5e10b6b575993c78ac22191849c464b618c4fa8a.tar.gz mocca-5e10b6b575993c78ac22191849c464b618c4fa8a.tar.bz2 mocca-5e10b6b575993c78ac22191849c464b618c4fa8a.zip |
MOCCA Online HTTP binding refactored.
git-svn-id: https://joinup.ec.europa.eu/svn/mocca/trunk@762 8a26b1a7-26f0-462f-b9ef-d0e30c41f5a4
Diffstat (limited to 'BKUOnline/src/main/java/at/gv/egiz/bku')
10 files changed, 577 insertions, 605 deletions
diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/AbstractWebRequestHandler.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/AbstractWebRequestHandler.java deleted file mode 100644 index 3cd6dd85..00000000 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/AbstractWebRequestHandler.java +++ /dev/null @@ -1,327 +0,0 @@ -/* -* Copyright 2009 Federal Chancellery Austria and -* Graz University of Technology -* -* 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 at.gv.egiz.bku.online.webapp; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Arrays; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; -import java.util.regex.Pattern; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.MDC; - -import at.gv.egiz.bku.binding.HTTPBindingProcessor; -import at.gv.egiz.bku.binding.HttpUtil; -import at.gv.egiz.bku.binding.Id; -import at.gv.egiz.bku.binding.IdFactory; -import at.gv.egiz.bku.binding.InputDecoderFactory; -import at.gv.egiz.bku.utils.StreamUtil; -import at.gv.egiz.org.apache.tomcat.util.http.AcceptLanguage; - -public abstract class AbstractWebRequestHandler extends SpringBKUServlet { - - private static final long serialVersionUID = 1L; - - public static final String APPLET_PAGE_P = "appletPage"; - public static final String APPLET_PAGE_DEFAULT = "applet.jsp"; - - public static final String PARAM_APPLET_WIDTH = "appletWidth"; - public static final String ATTR_APPLET_WIDTH = "appletWidth"; - - public static final String PARAM_APPLET_HEIGHT = "appletHeight"; - public static final String ATTR_APPLET_HEIGHT = "appletHeight"; - - public static final String PARAM_APPLET_BACKGROUND = "appletBackground"; - public static final String ATTR_APPLET_BACKGROUND = "appletBackground"; - - public static final String PARAM_APPLET_BACKGROUND_COLOR = "appletBackgroundColor"; - public static final String ATTR_APPLET_BACKGROUND_COLOR = "appletBackgroundColor"; - - public static final Pattern PATTERM_APPLET_BACKGROUND_COLOR = Pattern.compile("\\#[0-9a-fA-F]{6}"); - public static final String PARAM_APPLET_GUI_STYLE = "appletGuiStyle"; - public static final String ATTR_APPLET_GUI_STYLE = "appletGuiStyle"; - - public static final String[] VALUES_APPLET_GUI_STYLE = new String[] {"tiny", "simple", "advanced"}; - public static final String PARAM_APPLET_EXTENSION = "appletExtension"; - public static final String ATTR_APPLET_EXTENSION = "appletExtension"; - - public static final String[] VALUES_APPLET_EXTENSION = new String[] {"pin", "activation"}; - public static final String PARAM_LOCALE = "locale"; - public static final String ATTR_LOCALE = "locale"; - - public static final Pattern PATTERN_LOCALE = Pattern.compile("[a-zA-Z][a-zA-Z](_[a-zA-Z][a-zA-Z]){0,2}"); - public static final String REDIRECT_URL_SESSION_ATTRIBUTE = "redirectUrl"; - - private final Logger log = LoggerFactory.getLogger(BKURequestHandler.class); - - protected static String getStringFromStream(InputStream is, String encoding) - throws IOException { - if (is == null) { - return null; - } - if (encoding == null) { - encoding = HttpUtil.DEFAULT_CHARSET; - } - ByteArrayOutputStream os = new ByteArrayOutputStream(); - StreamUtil.copyStream(is, os); - return new String(os.toByteArray(), encoding); - } - - protected abstract String getRequestProtocol(HttpServletRequest req); - - protected HTTPBindingProcessor getBindingProcessor(Id id, HttpServletRequest req, Locale locale) { - - // remove existing binding processor if present - getBindingProcessorManager().removeBindingProcessor(id); - - // create new binding processor - return (HTTPBindingProcessor) getBindingProcessorManager().createBindingProcessor(getRequestProtocol(req), locale); - - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, - java.io.IOException { - - String msg = (req.getSession(false) == null) ? "New session created." - : "Session already established."; - - Id id = IdFactory.getInstance().createId(req.getSession().getId()); - MDC.put("id", id.toString()); - - String acceptLanguage = req.getHeader("Accept-Language"); - Locale locale = AcceptLanguage.getLocale(acceptLanguage); - - if (log.isInfoEnabled()) { - log.info("Recieved request (Accept-Language locale: {}). {}", locale, msg); - } - - try { - - HTTPBindingProcessor bindingProcessor = getBindingProcessor(id, req, locale); - - Map<String, String> headerMap = new HashMap<String, String>(); - for (Enumeration<?> headerName = req.getHeaderNames(); headerName - .hasMoreElements();) { - String header = (String) headerName.nextElement(); - if (header != null) { - headerMap.put(header, req.getHeader(header)); - } - } - - InputStream inputStream; - String charset; - if (req.getMethod().equals("POST")) { - charset = req.getCharacterEncoding(); - String contentType = req.getContentType(); - if (charset != null) { - contentType += ";" + charset; - } - headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, contentType); - inputStream = req.getInputStream(); - } else { - charset = "UTF-8"; - headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, - InputDecoderFactory.URL_ENCODED); - String queryString = req.getQueryString(); - if (queryString != null) { - inputStream = new ByteArrayInputStream(queryString.getBytes(charset)); - } else { - inputStream = new ByteArrayInputStream(new byte[] {}); - } - } - bindingProcessor.setHTTPHeaders(headerMap); - bindingProcessor.consumeRequestStream(req.getRequestURL().toString(), - inputStream); - - req.getInputStream().close(); - getBindingProcessorManager().process(id, bindingProcessor); - - HttpSession session = req.getSession(); - - log.trace("Looking for applet parameters in request."); - - // appletWidth - String width = getStringFromStream(bindingProcessor - .getFormData(PARAM_APPLET_WIDTH), charset); - if (width != null && !width.isEmpty()) { - try { - // must be a valid integer - session.setAttribute(ATTR_APPLET_WIDTH, Integer.parseInt(width)); - log.debug("Found parameter " + PARAM_APPLET_WIDTH + "='{}'.", width); - } catch (NumberFormatException nfe) { - log.warn("Parameter " + PARAM_APPLET_WIDTH - + " does not contain a valid value.", nfe); - } - } - - // appletHeight - String height = getStringFromStream(bindingProcessor - .getFormData(PARAM_APPLET_HEIGHT), charset); - if (height != null && !height.isEmpty()) { - try { - // must be a valid integer - session.setAttribute(ATTR_APPLET_HEIGHT, Integer.parseInt(height)); - log.debug("Found parameter " + PARAM_APPLET_HEIGHT + "='{}'.", height); - } catch (NumberFormatException nfe) { - log.warn("Parameter " + PARAM_APPLET_HEIGHT - + " does not contain a valid value.", nfe); - } - } - - // appletBackground - String background = getStringFromStream(bindingProcessor - .getFormData(PARAM_APPLET_BACKGROUND), charset); - if (background != null && !background.isEmpty()) { - session.setAttribute(ATTR_APPLET_BACKGROUND, background); - try { - // must be a valid http or https URL - URI backgroundURL = new URI(background); - if ("http".equals(backgroundURL.getScheme()) - || "https".equals(backgroundURL.getScheme())) { - session.setAttribute(ATTR_APPLET_BACKGROUND, backgroundURL - .toASCIIString()); - log.debug("Found parameter " + PARAM_APPLET_BACKGROUND + "='{}'.", - backgroundURL.toASCIIString()); - } else { - log.warn("Parameter " + PARAM_APPLET_BACKGROUND - + "='{}' is not a valid http/https URL.", background); - } - } catch (URISyntaxException e) { - log.warn("Parameter " + PARAM_APPLET_BACKGROUND - + "='{}' is not a valid http/https URL.", background, e); - } - } - - // appletBackgroundColor - String backgroundColor = getStringFromStream(bindingProcessor - .getFormData(PARAM_APPLET_BACKGROUND_COLOR), charset); - if (backgroundColor != null && !backgroundColor.isEmpty()) { - // must be a valid color definition - if (PATTERM_APPLET_BACKGROUND_COLOR.matcher(backgroundColor).matches()) { - session.setAttribute(ATTR_APPLET_BACKGROUND_COLOR, backgroundColor); - log.debug("Faund parameter " + PARAM_APPLET_BACKGROUND_COLOR - + "='{}'.", backgroundColor); - } else { - log.warn("Parameter " + PARAM_APPLET_BACKGROUND_COLOR - + "='{}' is not a valid color definition " - + "(must be of form '#hhhhhh').", backgroundColor); - } - } - - // appletGuiStyle - String guiStyle = getStringFromStream(bindingProcessor - .getFormData(PARAM_APPLET_GUI_STYLE), charset); - if (guiStyle != null && !guiStyle.isEmpty()) { - // must be one of VALUES_APPLET_GUI_STYLE - String style = guiStyle.toLowerCase(); - if (Arrays.asList(VALUES_APPLET_GUI_STYLE).contains(style)) { - session.setAttribute(ATTR_APPLET_GUI_STYLE, style); - log.debug("Found parameter " + PARAM_APPLET_GUI_STYLE + "='{}'.", style); - } else { - StringBuilder sb = new StringBuilder(); - sb.append("Parameter ").append(PARAM_APPLET_GUI_STYLE).append( - "='").append(guiStyle).append("' is not valid (must be one of ") - .append(Arrays.toString(VALUES_APPLET_GUI_STYLE)).append(")."); - log.warn(sb.toString()); - } - } - - // appletExtension - String extension = getStringFromStream(bindingProcessor - .getFormData(PARAM_APPLET_EXTENSION), charset); - if (extension != null && !extension.isEmpty()) { - // must be one of VALUES_APPLET_EXTENSION - String ext = extension.toLowerCase(); - if (Arrays.asList(VALUES_APPLET_EXTENSION).contains(ext)) { - session.setAttribute(ATTR_APPLET_EXTENSION, ext); - log.debug("Found parameter " + PARAM_APPLET_EXTENSION + "='{}'.", ext); - } else { - StringBuilder sb = new StringBuilder(); - sb.append("Parameter ").append(PARAM_APPLET_EXTENSION).append( - "='").append(extension).append("' is not valid (must be one of ") - .append(Arrays.toString(VALUES_APPLET_EXTENSION)).append(")."); - log.warn(sb.toString()); - } - } - - // locale - String localeFormParam = getStringFromStream(bindingProcessor - .getFormData(PARAM_LOCALE), charset); - if (localeFormParam != null && !localeFormParam.isEmpty()) { - // must be a valid locale - if (PATTERN_LOCALE.matcher(localeFormParam).matches()) { - locale = new Locale(localeFormParam); - log.debug("Override accept-language header locale {} " - + "with form param {}.", locale, localeFormParam); - } else { - log.warn("Parameter " + PARAM_LOCALE - + "='{}' is not a valid locale definition.", localeFormParam); - } - } - if (locale != null) { - log.debug("Using locale {}.", locale); - session.setAttribute(ATTR_LOCALE, locale.toString()); - } - - beforeAppletPage(req, bindingProcessor); - - String appletPage = getStringFromStream(bindingProcessor - .getFormData(APPLET_PAGE_P), charset); - if (appletPage == null || appletPage.isEmpty()) { - appletPage = APPLET_PAGE_DEFAULT; - } - log.debug("Sending redirect to UI page '{}'.", appletPage + ";jsessionid=" + id); - resp.sendRedirect(appletPage + ";jsessionid=" + id); - - } finally { - MDC.remove("id"); - } - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, java.io.IOException { - doPost(req, resp); - } - - /** - * Called before the request is forwarded or redirected to the Applet page. - * - * @param req - * @param bindingProcessor - */ - protected void beforeAppletPage(HttpServletRequest req, - HTTPBindingProcessor bindingProcessor) { - } - -} diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/AppletDispatcher.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/AppletDispatcher.java deleted file mode 100644 index 9e455621..00000000 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/AppletDispatcher.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * 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 at.gv.egiz.bku.online.webapp; - -import java.io.IOException; -import java.util.regex.Pattern; -import javax.servlet.RequestDispatcher; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * prevent applet caching, - * could be removed once applet is loaded via jnlp - * - * @author Clemens Orthacker <clemens.orthacker@iaik.tugraz.at> - */ -public class AppletDispatcher extends HttpServlet { - - private static final long serialVersionUID = 1L; - - private final Logger log = LoggerFactory.getLogger(AppletDispatcher.class); - - public static final String DISPATCH_CTX = "dispatch/"; - public static final String RAND_PREFIX = "__"; - public static final String RAND_ATTRIBUTE = "rand"; - public static final Pattern ctxPattern = Pattern.compile(DISPATCH_CTX); - public static final Pattern archivePattern = Pattern.compile(RAND_PREFIX + "[a-zA-Z0-9]*\\.jar$"); - - /** - * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods. - * @param request servlet request - * @param response servlet response - * @throws ServletException if a servlet-specific error occurs - * @throws IOException if an I/O error occurs - */ - protected void processRequest(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - - String uri = request.getRequestURI(); -// log.trace("request URI " + uri); - - uri = uri.substring(request.getContextPath().length()); -// log.trace("removing contextPath " + uri); - - uri = ctxPattern.matcher(uri).replaceAll(""); -// log.trace("removing dispatch context " + uri); - - uri = archivePattern.matcher(uri).replaceAll(".jar"); -// log.trace("removing random suffix " + uri); - - log.trace("Dispatching request URI {} to {}.", request.getRequestURI(), uri); - - RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(uri); - dispatcher.forward(request, response); - } - - // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code."> - /** - * Handles the HTTP <code>GET</code> method. - * @param request servlet request - * @param response servlet response - * @throws ServletException if a servlet-specific error occurs - * @throws IOException if an I/O error occurs - */ - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processRequest(request, response); - } - - /** - * Handles the HTTP <code>POST</code> method. - * @param request servlet request - * @param response servlet response - * @throws ServletException if a servlet-specific error occurs - * @throws IOException if an I/O error occurs - */ - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - processRequest(request, response); - } - - /** - * Returns a short description of the servlet. - * @return a String containing servlet description - */ - @Override - public String getServletInfo() { - return "Short description"; - }// </editor-fold> - -} diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java deleted file mode 100644 index d42f911c..00000000 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/BKURequestHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2008 Federal Chancellery Austria and - * Graz University of Technology - * - * 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 at.gv.egiz.bku.online.webapp; - -import javax.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import at.gv.egiz.bku.binding.HTTPBindingProcessor; -import at.gv.egiz.bku.binding.HTTPBindingProcessorImpl; - -/** - * Handles SL requests and instantiates BindingProcessors - * - */ -public class BKURequestHandler extends AbstractWebRequestHandler { - - private static final long serialVersionUID = 1L; - - private final Logger log = LoggerFactory.getLogger(BKURequestHandler.class); - - @Override - protected void beforeAppletPage(HttpServletRequest req, HTTPBindingProcessor bindingProcessor) { - // handle server side redirect url after processing - String redirectUrl = ((HTTPBindingProcessorImpl) bindingProcessor).getRedirectURL(); - if ( redirectUrl != null) { - log.info("Got redirect URL '{}'. Deferring browser redirect.", redirectUrl); - req.getSession().setAttribute(REDIRECT_URL_SESSION_ATTRIBUTE, redirectUrl); - } - } - - @Override - protected String getRequestProtocol(HttpServletRequest req) { - return "HTTP"; - } - -} diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/MoccaParameterBean.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/MoccaParameterBean.java new file mode 100644 index 00000000..0d2f847e --- /dev/null +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/MoccaParameterBean.java @@ -0,0 +1,210 @@ +/* + * Copyright 2009 Federal Chancellery Austria and + * Graz University of Technology + * + * 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 at.gv.egiz.bku.online.webapp; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.util.Arrays; +import java.util.Locale; +import java.util.regex.Pattern; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.binding.HTTPBindingProcessor; +import at.gv.egiz.bku.utils.StreamUtil; + +public class MoccaParameterBean { + + private final Logger log = LoggerFactory.getLogger(MoccaParameterBean.class); + + public static final String PARAM_UI_PAGE_P = "appletPage"; + + public static final String PARAM_APPLET_WIDTH = "appletWidth"; + + public static final String PARAM_APPLET_HEIGHT = "appletHeight"; + + public static final String PARAM_APPLET_BACKGROUND = "appletBackground"; + + public static final String PARAM_APPLET_BACKGROUND_COLOR = "appletBackgroundColor"; + public static final Pattern PATTERM_APPLET_BACKGROUND_COLOR = Pattern.compile("\\#[0-9a-fA-F]{6}"); + + public static final String PARAM_APPLET_GUI_STYLE = "appletGuiStyle"; + public static final String[] VALUES_APPLET_GUI_STYLE = new String[] {"tiny", "simple", "advanced"}; + + public static final String PARAM_APPLET_EXTENSION = "appletExtension"; + public static final String[] VALUES_APPLET_EXTENSION = new String[] {"pin", "activation"}; + + public static final String PARAM_LOCALE = "locale"; + public static final Pattern PATTERN_LOCALE = Pattern.compile("[a-zA-Z][a-zA-Z](_[a-zA-Z][a-zA-Z]){0,2}"); + + private Charset charset = Charset.forName("ISO-8859-1"); + + private HTTPBindingProcessor bindingProcessor; + + public MoccaParameterBean(HTTPBindingProcessor bindingProcessor) { + this.bindingProcessor = bindingProcessor; + } + + public Charset getCharset() { + return charset; + } + + public void setCharset(Charset charset) { + this.charset = (charset != null) ? Charset.forName("ISO-8859-1") : charset; + } + + public String getUIPage(String defaultValue) { + String uiPage = getString(PARAM_UI_PAGE_P); + return (uiPage != null) ? uiPage : defaultValue; + } + + public Integer getAppletWidth() { + return getInteger(PARAM_APPLET_WIDTH); + } + + public Integer getAppletHeight() { + return getInteger(PARAM_APPLET_HEIGHT); + } + + public String getAppletBackground() { + String background = getString(PARAM_APPLET_BACKGROUND); + if (background != null && !background.isEmpty()) { + try { + // must be a valid http or https URL + URI backgroundURL = new URI(background); + if ("http".equals(backgroundURL.getScheme()) + || "https".equals(backgroundURL.getScheme())) { + return background.toString(); + } else { + log.warn("Parameter " + PARAM_APPLET_BACKGROUND + + "='{}' is not a valid http/https URL.", background); + } + } catch (URISyntaxException e) { + log.warn("Parameter " + PARAM_APPLET_BACKGROUND + + "='{}' is not a valid http/https URL.", background, e); + } + } + return null; + } + + public String getAppletBackgroundColor() { + String backgroundColor = getString(PARAM_APPLET_BACKGROUND_COLOR); + if (backgroundColor != null && !backgroundColor.isEmpty()) { + // must be a valid color definition + if (PATTERM_APPLET_BACKGROUND_COLOR.matcher(backgroundColor).matches()) { + return backgroundColor; + } else { + log.warn("Parameter " + PARAM_APPLET_BACKGROUND_COLOR + + "='{}' is not a valid color definition " + + "(must be of form '#hhhhhh').", backgroundColor); + } + } + return null; + } + + public String getGuiStyle() { + String guiStyle = getString(PARAM_APPLET_GUI_STYLE); + if (guiStyle != null && !guiStyle.isEmpty()) { + // must be one of VALUES_APPLET_GUI_STYLE + String style = guiStyle.toLowerCase(); + if (Arrays.asList(VALUES_APPLET_GUI_STYLE).contains(style)) { + return style; + } else { + StringBuilder sb = new StringBuilder(); + sb.append("Parameter ").append(PARAM_APPLET_GUI_STYLE).append( + "='").append(guiStyle).append("' is not valid (must be one of ") + .append(Arrays.toString(VALUES_APPLET_GUI_STYLE)).append(")."); + log.warn(sb.toString()); + } + } + return null; + } + + public String getExtension() { + String extension = getString(PARAM_APPLET_EXTENSION); + if (extension != null && !extension.isEmpty()) { + // must be one of VALUES_APPLET_EXTENSION + String ext = extension.toLowerCase(); + if (Arrays.asList(VALUES_APPLET_EXTENSION).contains(ext)) { + log.debug("Found parameter " + PARAM_APPLET_EXTENSION + "='{}'.", ext); + return ext; + } else { + StringBuilder sb = new StringBuilder(); + sb.append("Parameter ").append(PARAM_APPLET_EXTENSION).append( + "='").append(extension).append("' is not valid (must be one of ") + .append(Arrays.toString(VALUES_APPLET_EXTENSION)).append(")."); + log.warn(sb.toString()); + } + } + return null; + } + + public Locale getLocale() { + String locale = getString(PARAM_LOCALE); + if (locale != null && !locale.isEmpty()) { + // must be a valid locale + if (PATTERN_LOCALE.matcher(locale).matches()) { + log.debug("Found parameter " + PARAM_LOCALE + "='{}'.", locale); + return new Locale(locale); + } else { + log.warn("Parameter " + PARAM_LOCALE + + "='{}' is not a valid locale definition.", locale); + } + } + return null; + } + + public Integer getInteger(String parameterName) { + String string = getString(parameterName); + if (string == null || string.isEmpty()) { + return null; + } else { + try { + return Integer.parseInt(string); + } catch (NumberFormatException e) { + log.warn("Parameter {} does not contain a valid value.", parameterName, + e); + return null; + } + } + } + + public String getString(String parameterName) { + if (bindingProcessor != null) { + InputStream formData = bindingProcessor.getFormData(parameterName); + if (formData != null) { + InputStreamReader reader = new InputStreamReader(formData, charset); + StringWriter writer = new StringWriter(); + try { + StreamUtil.copyStream(reader, writer); + } catch (IOException e) { + log.warn("Failed to get parameter {}.", parameterName, e); + } + return writer.toString(); + } + } + return null; + } + +} diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/RequestIdFilter.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/RequestIdFilter.java new file mode 100644 index 00000000..210f482f --- /dev/null +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/RequestIdFilter.java @@ -0,0 +1,58 @@ +package at.gv.egiz.bku.online.webapp; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.slf4j.MDC; + +import at.gv.egiz.bku.binding.Id; +import at.gv.egiz.bku.binding.IdFactory; + +/** + * Servlet Filter implementation class BindingProcessorFilter + */ +public class RequestIdFilter implements Filter { + + /** + * @see Filter#destroy() + */ + public void destroy() { + } + + /** + * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) + */ + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + + if (request instanceof HttpServletRequest) { + HttpSession session = ((HttpServletRequest) request).getSession(); + Id id = IdFactory.getInstance().createId(session.getId()); + MDC.put("id", id.toString()); + request.setAttribute("id", id); + } + + // pass the request along the filter chain + try { + chain.doFilter(request, response); + } finally { + MDC.remove("id"); + } + + } + + /** + * @see Filter#init(FilterConfig) + */ + public void init(FilterConfig fConfig) throws ServletException { + } + +} diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java index 5fd01775..cdc5a3ef 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/ResultServlet.java @@ -17,63 +17,56 @@ package at.gv.egiz.bku.online.webapp; import java.io.IOException; -import java.util.Iterator; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Map; +import java.util.Map.Entry; -import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.slf4j.MDC; import at.gv.egiz.bku.binding.BindingProcessor; +import at.gv.egiz.bku.binding.BindingProcessorManager; import at.gv.egiz.bku.binding.HTTPBindingProcessor; import at.gv.egiz.bku.binding.Id; -import at.gv.egiz.bku.binding.IdFactory; import at.gv.egiz.bku.utils.NullOutputStream; /** * Delivers the result to the browser * */ -public class ResultServlet extends SpringBKUServlet { +public class ResultServlet extends HttpServlet { private static final long serialVersionUID = 1L; private final Logger log = LoggerFactory.getLogger(ResultServlet.class); - private String encoding = "UTF-8"; - private String expiredPage = "./expiredError.jsp"; - - public ResultServlet() { - } - - private void myInit() { - String enc = getServletContext().getInitParameter("responseEncoding"); - if (enc != null) { - log.trace("Init default encoding to: {}.", enc); - encoding = enc; - } - String expP = getServletConfig().getInitParameter("expiredPage"); - if (expP != null) { - log.trace("Init expired page to: {}.", expP); - expiredPage = expP; - } - } + private String responseEncoding = "UTF-8"; + + private String expiredPageUrl = "expired.jsp"; @Override public void init() throws ServletException { - super.init(); - myInit(); - } - - @Override - public void init(ServletConfig config) throws ServletException { - super.init(config); - myInit(); + String encoding = getServletConfig().getInitParameter("responseEncoding"); + if (encoding != null) { + log.info("Init default responseEncoding to: {}.", encoding); + responseEncoding = encoding; + } + String url = getServletConfig().getInitParameter("expiredPageUrl"); + if (url != null) { + try { + expiredPageUrl = new URL(url).toString(); + log.info("Init expiredPageUrl to: {}.", expiredPageUrl); + } catch (MalformedURLException e) { + log.error("Failed to set expiredUrlPage {}.", url, e); + } + } } protected void doPost(HttpServletRequest req, HttpServletResponse resp) @@ -84,64 +77,55 @@ public class ResultServlet extends SpringBKUServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, java.io.IOException { - HttpSession session = req.getSession(false); - if (session == null) { - resp.sendRedirect(expiredPage); + BindingProcessorManager bindingProcessorManager = (BindingProcessorManager) getServletContext() + .getAttribute("bindingProcessorManager"); + if (bindingProcessorManager == null) { + String msg = "Configuration error: BindingProcessorManager missing!"; + log.error(msg); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg); return; } - Id id = IdFactory.getInstance().createId(session.getId()); - - HTTPBindingProcessor bp; - BindingProcessor bindingProcessor = getBindingProcessorManager().getBindingProcessor(id); - if (bindingProcessor instanceof HTTPBindingProcessor) { - bp = (HTTPBindingProcessor) bindingProcessor; - } else { - session.invalidate(); - resp.sendRedirect(expiredPage); + Id id = (Id) req.getAttribute("id"); + BindingProcessor bindingProcessor = null; + if (id == null + || !((bindingProcessor = bindingProcessorManager + .getBindingProcessor(id)) instanceof HTTPBindingProcessor)) { + resp.sendRedirect(expiredPageUrl); return; } - MDC.put("id", id.toString()); + + HTTPBindingProcessor bp = (HTTPBindingProcessor) bindingProcessor; try { - String redirectUrl = (String) session - .getAttribute(AbstractWebRequestHandler.REDIRECT_URL_SESSION_ATTRIBUTE); - if (redirectUrl == null) { - redirectUrl = bp.getRedirectURL(); - } - if (redirectUrl != null) { - try { - bp.writeResultTo(new NullOutputStream(), encoding); - getBindingProcessorManager().removeBindingProcessor(bp.getId()); - } finally { - log.info("Sending deferred redirect, RedirectURL={}.", redirectUrl); - resp.sendRedirect(redirectUrl); - session.invalidate(); + OutputStream outputStream; + String redirectUrl = bp.getRedirectURL(); + if (redirectUrl != null && !redirectUrl.trim().isEmpty()) { + log.info("Sending (deferred) redirect to {}.", redirectUrl); + resp.sendRedirect(redirectUrl); + // TODO Couldn't we simply discard the output? + outputStream = new NullOutputStream(); + } else { + log.debug("Setting HTTP status code {}.", bp.getResponseCode()); + resp.setStatus(bp.getResponseCode()); + resp.setHeader("Cache-Control", "no-store"); // HTTP 1.1 + resp.setHeader("Pragma", "no-cache"); // HTTP 1.0 + resp.setDateHeader("Expires", 0); + Map<String, String> responseHeaders = bp.getResponseHeaders(); + for (Entry<String, String> header : responseHeaders.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + log.debug("Setting response header {}: {}.", key, value); + resp.setHeader(key, value); } - return; - } - - log.trace("Setting response code: {}.", bp.getResponseCode()); - resp.setStatus(bp.getResponseCode()); - resp.setHeader("Cache-Control", "no-store"); // HTTP 1.1 - resp.setHeader("Pragma", "no-cache"); // HTTP 1.0 - resp.setDateHeader("Expires", 0); - for (Iterator<String> it = bp.getResponseHeaders().keySet().iterator(); it - .hasNext();) { - String header = it.next(); - log.trace("Setting response header {}: {}.", header, bp.getResponseHeaders().get(header)); - resp.setHeader(header, bp.getResponseHeaders().get(header)); + resp.setContentType(bp.getResultContentType()); + log.info("Sending result."); + outputStream = resp.getOutputStream(); } - resp.setContentType(bp.getResultContentType()); - resp.setCharacterEncoding(encoding); - log.info("Sending result."); - bp.writeResultTo(resp.getOutputStream(), encoding); - resp.getOutputStream().flush(); - session.invalidate(); - getBindingProcessorManager().removeBindingProcessor(bp.getId()); - + bp.writeResultTo(outputStream, responseEncoding); + outputStream.flush(); } finally { - MDC.remove("id"); + bindingProcessorManager.removeBindingProcessor(id); } } } diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SessionListener.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SessionListener.java index 1bec31b6..e7f05862 100644 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SessionListener.java +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SessionListener.java @@ -35,11 +35,12 @@ public class SessionListener implements HttpSessionListener { @Override public void sessionCreated(HttpSessionEvent event) { + log.info("Session {} created.", event.getSession().getId()); } @Override public void sessionDestroyed(HttpSessionEvent event) { - BindingProcessorManager manager = (BindingProcessorManager) event.getSession().getServletContext().getAttribute(SpringBKUServlet.BEAN_NAME); + BindingProcessorManager manager = (BindingProcessorManager) event.getSession().getServletContext().getAttribute("bindingProcessorManager"); manager.removeBindingProcessor(IdFactory.getInstance().createId(event.getSession().getId())); log.info("Session {} destroyed.", event.getSession().getId()); } diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SpringBKUServlet.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SpringBKUServlet.java deleted file mode 100644 index 6a6f11e8..00000000 --- a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/SpringBKUServlet.java +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright 2008 Federal Chancellery Austria and -* Graz University of Technology -* -* 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 at.gv.egiz.bku.online.webapp;
-
-import javax.servlet.http.HttpServlet; - -import at.gv.egiz.bku.binding.BindingProcessorManager; -
-public abstract class SpringBKUServlet extends HttpServlet {
-
- private static final long serialVersionUID = 1L; - - public final static String BEAN_NAME="bindingProcessorManager"; - - protected BindingProcessorManager getBindingProcessorManager() {
- return (BindingProcessorManager) getServletContext().getAttribute(BEAN_NAME);
- } - -}
diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/UIServlet.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/UIServlet.java new file mode 100644 index 00000000..9b9b9927 --- /dev/null +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/UIServlet.java @@ -0,0 +1,106 @@ +/* + * Copyright 2009 Federal Chancellery Austria and + * Graz University of Technology + * + * 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 at.gv.egiz.bku.online.webapp; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; + +import javax.servlet.RequestDispatcher; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.binding.BindingProcessor; +import at.gv.egiz.bku.binding.BindingProcessorManager; +import at.gv.egiz.bku.binding.HTTPBindingProcessor; +import at.gv.egiz.bku.binding.Id; + +public class UIServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private final Logger log = LoggerFactory.getLogger(UIServlet.class); + + private String expiredPageUrl = "expired.jsp"; + + @Override + public void init() throws ServletException { + String url = getServletConfig().getInitParameter("expiredPageUrl"); + if (url != null) { + try { + expiredPageUrl = new URL(url).toString(); + log.info("Init expiredPageUrl to: {}.", expiredPageUrl); + } catch (MalformedURLException e) { + log.error("Failed to set expiredUrlPage {}.", url, e); + } + } + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + + BindingProcessorManager bindingProcessorManager = (BindingProcessorManager) getServletContext() + .getAttribute("bindingProcessorManager"); + if (bindingProcessorManager == null) { + String msg = "Configuration error: BindingProcessorManager missing!"; + log.error(msg); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg); + return; + } + + Id id = (Id) req.getAttribute("id"); + BindingProcessor bindingProcessor = null; + if (id == null + || !((bindingProcessor = bindingProcessorManager + .getBindingProcessor(id)) instanceof HTTPBindingProcessor)) { + resp.sendRedirect(expiredPageUrl); + return; + } + + MoccaParameterBean parameterBean = new MoccaParameterBean((HTTPBindingProcessor) bindingProcessor); + req.setAttribute("moccaParam", parameterBean); + + String uiPage = getServletConfig().getInitParameter("uiPage"); + uiPage = parameterBean.getUIPage(uiPage); + if (uiPage == null) { + uiPage = "applet.jsp"; + } + + RequestDispatcher dispatcher = req.getRequestDispatcher(uiPage); + if (dispatcher == null) { + log.warn("Failed to get RequestDispatcher for page {}.", uiPage); + resp.sendError(HttpServletResponse.SC_NOT_FOUND); + } else { + dispatcher.forward(req, resp); + } + + } + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + super.doPost(req, resp); + } + +} diff --git a/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/WebRequestHandler.java b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/WebRequestHandler.java new file mode 100644 index 00000000..08b50699 --- /dev/null +++ b/BKUOnline/src/main/java/at/gv/egiz/bku/online/webapp/WebRequestHandler.java @@ -0,0 +1,137 @@ +/* +* Copyright 2009 Federal Chancellery Austria and +* Graz University of Technology +* +* 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 at.gv.egiz.bku.online.webapp; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Enumeration; +import java.util.LinkedHashMap; +import java.util.Locale; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import at.gv.egiz.bku.binding.BindingProcessorManager; +import at.gv.egiz.bku.binding.HTTPBindingProcessor; +import at.gv.egiz.bku.binding.HttpUtil; +import at.gv.egiz.bku.binding.Id; +import at.gv.egiz.bku.binding.InputDecoderFactory; +import at.gv.egiz.org.apache.tomcat.util.http.AcceptLanguage; + +public class WebRequestHandler extends HttpServlet { + + private static final long serialVersionUID = 1L; + + private final Logger log = LoggerFactory.getLogger(WebRequestHandler.class); + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, + java.io.IOException { + + BindingProcessorManager bindingProcessorManager = (BindingProcessorManager) getServletContext() + .getAttribute("bindingProcessorManager"); + if (bindingProcessorManager == null) { + String msg = "Configuration error: BindingProcessorManager missing!"; + log.error(msg); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg); + return; + } + + Id id = (Id) req.getAttribute("id"); + if (id == null) { + String msg = "No request id! Configuration error: ServletFilter missing?"; + log.error(msg); + resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg); + return; + } + + // if binding processor with same id is present: remove + bindingProcessorManager.removeBindingProcessor(id); + + Locale locale = AcceptLanguage.getLocale(req.getHeader("Accept-Language")); + if (log.isInfoEnabled()) { + log.info("Recieved request (Accept-Language locale: {}).", locale); + } + + // create new binding processor + String protocol = getServletConfig().getInitParameter("protocol"); + if (protocol == null || protocol.isEmpty()) { + protocol = req.getScheme(); + } + HTTPBindingProcessor bindingProcessor = (HTTPBindingProcessor) bindingProcessorManager + .createBindingProcessor(protocol, locale); + + // set headers + LinkedHashMap<String, String> headerMap = new LinkedHashMap<String, String>(); + if (req.getHeaderNames() != null) { + for (Enumeration<?> headerName = req.getHeaderNames(); headerName + .hasMoreElements();) { + String name = (String) headerName.nextElement(); + // Account for multiple headers with the same field-name, but + // they are very rare, so we are not using a StringBuffer. + Enumeration<?> headers = req.getHeaders(name); + String value = null; + while (headers.hasMoreElements()) { + value = (value == null) + ? (String) headers.nextElement() + : value + ", " + headers.nextElement(); + } + headerMap.put(name, value); + } + } + bindingProcessor.setHTTPHeaders(headerMap); + + // set request stream + InputStream inputStream; + if (req.getMethod().equals("POST")) { + inputStream = req.getInputStream(); + } else { + headerMap.put(HttpUtil.HTTP_HEADER_CONTENT_TYPE, InputDecoderFactory.URL_ENCODED); + String queryString = req.getQueryString(); + if (queryString != null) { + inputStream = new ByteArrayInputStream(queryString.getBytes("UTF-8")); + } else { + inputStream = new ByteArrayInputStream(new byte[] {}); + } + } + bindingProcessor.consumeRequestStream(req.getRequestURL().toString(), inputStream); + inputStream.close(); + + // process + bindingProcessorManager.process(id, bindingProcessor); + + log.debug("Sending redirect to user interface."); + // TODO: appending the jsessionid here breaks the separation of request + // handling and request state tracking done in the servlet filter, but + // the servlet filter does not allow us to modify the redirect + resp.sendRedirect("ui;jsessionid=" + id.toString()); + + } + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, java.io.IOException { + doPost(req, resp); + } + +} |