/* * Copyright (c) 2010 StockPlay development team * All rights reserved. * * This program 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. * * This program 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 this program. If not, see <http://www.gnu.org/licenses/>. * */ package com.kapti.backend.xmlrpc; import com.kapti.backend.security.SessionsHandler; import com.kapti.data.persistence.StockPlayDAO; import com.kapti.data.persistence.StockPlayDAOFactory; import com.kapti.exceptions.StockPlayException; import java.io.IOException; import java.net.URL; import java.util.Date; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import org.apache.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.server.AbstractReflectiveHandlerMapping.AuthenticationHandler; import org.apache.xmlrpc.server.PropertyHandlerMapping; import org.apache.xmlrpc.server.XmlRpcHandlerMapping; import org.apache.xmlrpc.server.XmlRpcServerConfigImpl; import org.apache.xmlrpc.webserver.XmlRpcServlet; import org.apache.xmlrpc.webserver.XmlRpcServletServer; /** * \brief XML-RPC servletimplementatie. * * Dit is een uitbreiding van de standaard XML-RPC servlet. Deze voorziet * in een aantal extra features, namelijk: * - Registratie van een authentication handler * - Doorgeven van persistente data aan method handlers * - Flexibele method mapping via property-file * - Gebruik van customized XML-RPC server voor exception trapping */ public class Servlet extends XmlRpcServlet { // // Dataleden // private StockPlayDAO mDAO; private SessionsHandler mSessions; static Logger mLogger = Logger.getLogger(Servlet.class); private static Date mDateStart = new Date(); // // Constructie // public Servlet() throws XmlRpcException { super(); try { mDAO = StockPlayDAOFactory.getDAO(); mSessions = SessionsHandler.getInstance(); } catch (StockPlayException e) { mLogger.error("Can't start StockPlayDAOFactory"); throw new RuntimeException("Can't start StockPlayDAOFactory"); } } // // Methoden // @Override public void init(ServletConfig pConfig) throws ServletException { super.init(pConfig); XmlRpcServerConfigImpl config = new XmlRpcServerConfigImpl(); config.setEnabledForExtensions(true); getXmlRpcServletServer().setConfig(config); } /** * Door deze methode te overschrijven kunnen we een eigen XmlRpcServer * gebruiken. */ @Override protected XmlRpcServletServer newXmlRpcServer(ServletConfig iConfig) throws XmlRpcException { // Configuratie wordt niet gebruikt? XmlRpcServletServer oServer = new ServletServer(); return oServer; } /** * Deze methode wordt gebruikt bij het configureren van de servlet server, * en zorgt voor de connectie tussen aangevraagde methodes en hun lokale * tegenhanger. Om een flexibele manier van werken te bekomen, gebruiken we * hier een property handler in plaats van een statische configuratie. * Ook registreren we hier de authenticatie-handler, verantwoordelijk voor * het controleren van doorgegeven credentials. */ @Override protected XmlRpcHandlerMapping newXmlRpcHandlerMapping() throws XmlRpcException { // Property-handler registreren PropertyHandlerMapping oMapping = null; URL tUrl = Thread.currentThread().getContextClassLoader().getResource("XmlRpcServlet.properties"); if (tUrl == null) { throw new XmlRpcException("Failed to locate resource XmlRpcServlet.properties"); } try { oMapping = newPropertyHandlerMapping(tUrl); } catch (IOException e) { throw new XmlRpcException("Failed to load resource " + tUrl + ": " + e.getMessage(), e); } // Authenticatie-handler registreren AuthenticationHandler tHandler = new AuthHandler(mDAO, mSessions); oMapping.setAuthenticationHandler(tHandler); return oMapping; } /** * Deze methode haalt een property-handler op, gebaseerd op een property- * bestand. Normaal worden de mappings tussen een property name en een * property handler statisch verzorgd, maar door het gebruik van een * eigen property handler maken we dit proces flexibel en makkelijk * aanpasbaar. We bekomen dit door de opgehaalde property handler * dusdanig aan te passen dat een eigen handler-factory gebruikt wordt (dit * is nodig om voor het verwerken van een request de persistente data * te kunnen doorgeven aan de handler in kwestie). */ @Override protected PropertyHandlerMapping newPropertyHandlerMapping(URL iUrl) throws IOException, XmlRpcException { // Property-handler ophalen in superklasse, dit doen we niet zelf PropertyHandlerMapping oMapping = super.newPropertyHandlerMapping(iUrl); // Property-handler aanpassen naar onze wensen ProcessorFactory factory = new ProcessorFactory(mDAO); oMapping.setRequestProcessorFactoryFactory(factory); oMapping.load(Thread.currentThread().getContextClassLoader(), iUrl); return oMapping; } /** * Ophalen van uptime. * * @return */ public static long getUptime() { return (long)(((new Date()).getTime() - mDateStart.getTime())/1000.0); } }