/* * Copyright 2004-2005 Revolution Systems Inc. * * 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 com.revolsys.ui.web.servlet; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.UnavailableException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.log4j.Logger; import com.revolsys.ui.web.config.Argument; import com.revolsys.ui.web.config.Attribute; import com.revolsys.ui.web.config.AttributeLoader; import com.revolsys.ui.web.config.Config; import com.revolsys.ui.web.config.InvalidConfigException; import com.revolsys.ui.web.config.Layout; import com.revolsys.ui.web.config.Page; import com.revolsys.ui.web.config.WebUiContext; import com.revolsys.ui.web.config.XmlConfigLoader; import com.revolsys.ui.web.exception.ActionException; import com.revolsys.ui.web.exception.AuthenticationException; import com.revolsys.ui.web.exception.FinishRequestException; import com.revolsys.ui.web.exception.PageNotFoundException; import com.revolsys.ui.web.exception.RedirectException; public final class IafServlet extends HttpServlet { /** The logging category */ private static final Logger log = Logger.getLogger(IafServlet.class); /** The unique serial version UID for the class. */ private static final long serialVersionUID = -5543695651259069014L; /** The defintion of the application */ private Config applicationConfig; private ServletContext servletContext; /** * Handle the GET request. Calls processRequest to handle the request. * * @param request the parameters of the client request * @param response the response sent back to the client * @exception ServletException if there was a problem handling the request * @exception IOException if an input output error occurs when handling the * request */ @Override public void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Handle the POST request. Calls processRequest to handle the request. * * @param request the parameters of the client request * @param response the response sent back to the client * @exception ServletException if there was a problem handling the request * @exception IOException if an input output error occurs when handling the * request */ @Override public void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } /** * Forward the request to the specified resource. * * @param path the path to the resource to forward to * @param request the parameters of the client request * @param response the response sent back to the client * @exception ServletException if there was a problem handling the request * @exception IOException if an input output error occurs when handling the * request */ public void forward(final String path, final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { if (!response.isCommitted()) { getServletConfig().getServletContext().getRequestDispatcher(path).forward(request, response); } } /** * Initialise the servlet. Loads the configuration from the * /WEB-INF/nice-config.xml file. * * @param config The servlet configuration parameters * @exception ServletException if there was a problem initialising the servlet */ @Override public void init(final ServletConfig config) throws ServletException { super.init(config); try { this.servletContext = config.getServletContext(); final URL configResource = this.servletContext.getResource("/WEB-INF/iaf-config.xml"); WebUiContext.setServletContext(this.servletContext); final XmlConfigLoader configLoader = new XmlConfigLoader(configResource, this.servletContext); this.applicationConfig = configLoader.loadConfig(); this.servletContext.setAttribute("rsWebUiConfig", this.applicationConfig); } catch (final InvalidConfigException ice) { ice.printStackTrace(); log.fatal(ice.getErrors()); throw new UnavailableException(ice.getMessage() + ":" + ice.getErrors()); } catch (final MalformedURLException mue) { log.fatal(mue.getMessage(), mue); throw new UnavailableException("Failed to initialise Servlet"); } catch (final Throwable t) { t.printStackTrace(); log.error(t.getMessage(), t); } } /** * @param page * @param request * @throws PageNotFoundException */ private void processArguments(final Page page, final HttpServletRequest request) throws ActionException { for (final Object element : page.getArguments()) { final Argument argument = (Argument)element; final String name = argument.getName(); Object value = null; String stringValue = request.getParameter(name); if (stringValue == null) { stringValue = argument.getDefault(); } if (stringValue != null) { final Class argumentType = argument.getType(); try { value = argument.valueOf(stringValue); } catch (final NumberFormatException e) { throw new PageNotFoundException("Page argument is not a valid number: " + name); } } if (value != null) { request.setAttribute(name, value); } else if (argument.isRequired()) { throw new PageNotFoundException("Missing page argument: " + name); } } } /** * @param page * @param request * @throws PageNotFoundException */ private void processAttributes(final Page page, final HttpServletRequest request) throws ActionException { for (final Object element : page.getFields()) { final Attribute attribute = (Attribute)element; final String name = attribute.getName(); final AttributeLoader loader = attribute.getLoader(); Object value = null; if (loader != null) { value = loader.getValue(request); } else { value = attribute.getValue(); } if (value != null) { request.setAttribute(name, value); } } } /** * Process the service request, uses the full path name of the request to * finds the page definition. The component heirarchy, list of request * processors and the menu tree from the config are used to handle the * request. If a PageNotFoundException was thrown by any of the request * processors a 404 response error code is set and no further processing is * performed. If a RedirectException is thrown the response is redirected to * the url from the exception. * * @param request the servlet request * @param response the servlet response * @exception ServletException if any unhandled exceptions occured during the * processing of the request * @exception IOException if there was a problem sending data to the client * @see PageNotFoundException * @see RedirectException */ public void processRequest(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException { try { String path = request.getServletPath(); final String pathInfo = request.getPathInfo(); if (pathInfo != null && !path.endsWith(pathInfo)) { path += pathInfo; } boolean secure = false; final String contextPath = request.getContextPath(); if (path.endsWith(".wp")) { path = path.substring(0, path.length() - 3); } else if (path.endsWith(".wps")) { secure = true; path = path.substring(0, path.length() - 4); } final Page page = this.applicationConfig.getPage(contextPath + path); WebUiContext .set(new WebUiContext(this.applicationConfig, contextPath, page, request, response)); if (page.isSecure() && !secure) { response.sendRedirect(page.getFullUrl()); return; } processArguments(page, request); processAttributes(page, request); request.setAttribute("niceConfig", this.applicationConfig); request.setAttribute("nicePage", page); final String menuName = request.getParameter("menuName"); request.setAttribute("menuSelected", menuName); request.setAttribute("title", page.getTitle()); page.invokeActions(this.servletContext, request, response); final Layout layout = page.getLayout(); if (layout != null) { final String file = layout.getFile(); if (file != null && file.length() > 0) { forward(file, request, response); } } } catch (final FinishRequestException fre) { // Do nothing as the actions have handled the request return; } catch (final AuthenticationException pne) { response.sendError(HttpServletResponse.SC_UNAUTHORIZED); } catch (final PageNotFoundException pne) { log.error(pne.getMessage(), pne); response.sendError(HttpServletResponse.SC_NOT_FOUND); } catch (final RedirectException re) { response.sendRedirect(response.encodeRedirectURL(re.getUrl())); } catch (final Throwable t) { log.error(t.getMessage(), t); throw new ServletException(t); } } }