PageRenderTime 51ms CodeModel.GetById 35ms RepoModel.GetById 0ms app.codeStats 0ms

/branches/CalendarWeeksPlugin/src/org/rapla/MainServlet.java

http://rapla.googlecode.com/
Java | 357 lines | 281 code | 42 blank | 34 comment | 35 complexity | 8dae555724ff982bd01a48055fcdb22d MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, CPL-1.0, LGPL-2.0, AGPL-1.0
  1. /*--------------------------------------------------------------------------*
  2. | Copyright (C) 2006 Christopher Kohlhaas |
  3. | |
  4. | This program is free software; you can redistribute it and/or modify |
  5. | it under the terms of the GNU General Public License as published by the |
  6. | Free Software Foundation. A copy of the license has been included with |
  7. | these distribution in the COPYING file, if not go to www.fsf.org |
  8. | |
  9. | As a special exception, you are granted the permissions to link this |
  10. | program with every library, which license fulfills the Open Source |
  11. | Definition as published by the Open Source Initiative (OSI). |
  12. *--------------------------------------------------------------------------*/
  13. package org.rapla;
  14. import java.io.File;
  15. import java.io.IOException;
  16. import java.io.ObjectOutputStream;
  17. import java.net.URL;
  18. import java.util.ArrayList;
  19. import java.util.Collection;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.TreeMap;
  24. import javax.servlet.ServletException;
  25. import javax.servlet.http.HttpServlet;
  26. import javax.servlet.http.HttpServletRequest;
  27. import javax.servlet.http.HttpServletResponse;
  28. import javax.servlet.http.HttpSession;
  29. import org.apache.avalon.framework.container.ContainerUtil;
  30. import org.apache.avalon.framework.logger.Logger;
  31. import org.rapla.components.util.IOUtil;
  32. import org.rapla.framework.Container;
  33. import org.rapla.framework.RaplaContext;
  34. import org.rapla.framework.RaplaContextException;
  35. import org.rapla.framework.StartupEnvironment;
  36. import org.rapla.plugin.RaplaExtensionPoints;
  37. import org.rapla.server.RemoteServer;
  38. import org.rapla.server.RemoteSession;
  39. import org.rapla.server.ServerService;
  40. import org.rapla.server.ShutdownListener;
  41. import org.rapla.server.ShutdownService;
  42. import org.rapla.server.internal.RemoteSessionImpl;
  43. import org.rapla.server.internal.ServerServiceImpl;
  44. import org.rapla.servletpages.RaplaPageGenerator;
  45. final public class MainServlet extends HttpServlet {
  46. private static final long serialVersionUID = 1L;
  47. /** The default config filename is raplaserver.xconf*/
  48. Container raplaMainContainer;
  49. public final static String DEFAULT_CONFIG_NAME = "raplaserver.xconf";
  50. Collection pageList;
  51. ServerService serverService;
  52. long serverStartTime;
  53. private File getConfigFile(String entryName, String defaultName) throws ServletException,IOException {
  54. String configName = getServletConfig().getInitParameter(entryName);
  55. if (configName == null)
  56. configName = defaultName;
  57. if (configName == null)
  58. throw new ServletException("Must specify " + entryName + " entry in web.xml !");
  59. File configFile = new File(getServletConfig().getServletContext().getRealPath("/WEB-INF/" + configName));
  60. if (!configFile.exists()) {
  61. String message = "ERROR: Config file not found " + configName;
  62. throw new ServletException(message);
  63. }
  64. return configFile.getCanonicalFile();
  65. }
  66. /**
  67. * Initializes Servlet and creates a <code>RaplaMainContainer</code> instance
  68. *
  69. * @exception ServletException if an error occurs
  70. */
  71. public void init()
  72. throws ServletException
  73. {
  74. String realPath = getServletContext().getRealPath("webclient");
  75. // if (realPath != null)
  76. {
  77. File webclientFolder= new File(realPath );
  78. webclientFolder.mkdir();
  79. copy( "WEB-INF/lib/rapla.jar", "webclient/rapla.jar" );
  80. }
  81. startServer();
  82. }
  83. private void copy( String sourceLib, String destLib ) throws ServletException
  84. {
  85. if (!new File(getServletContext().getRealPath(sourceLib)).exists())
  86. {
  87. return;
  88. }
  89. try
  90. {
  91. log("Copy " + sourceLib + " to " + destLib);
  92. IOUtil.copy( getServletContext().getRealPath(sourceLib), getServletContext().getRealPath(destLib), true);
  93. }
  94. catch (IOException e)
  95. {
  96. throw new ServletException("Can't copy " + sourceLib + " Cause " + e.getMessage());
  97. }
  98. }
  99. ShutdownListener shutdownListener = new ShutdownListener() {
  100. public void shutdownInitiated() {
  101. }
  102. public void shutdownComplete( boolean restart) {
  103. if ( restart ) {
  104. Thread restartThread = new Thread() {
  105. public void run() {
  106. try {
  107. log( "Stopping Server");
  108. stopServer();
  109. //getServletContext()
  110. log( "Restarting Server");
  111. startServer();
  112. } catch (Exception e) {
  113. log( "Error while restarting Server", e );
  114. }
  115. }
  116. };
  117. restartThread.setDaemon( false );
  118. restartThread.start();
  119. }
  120. }
  121. };
  122. void startServer()throws ServletException {
  123. log("Starting Rapla Servlet");
  124. Logger logger = null;
  125. serverStartTime = System.currentTimeMillis();
  126. try
  127. {
  128. File configFile = getConfigFile("config-file",DEFAULT_CONFIG_NAME);
  129. URL configURL = configFile.toURI().toURL();
  130. URL logConfigURL = getConfigFile("log-config-file","raplaserver.xlog").toURI().toURL();
  131. RaplaStartupEnvironment env = new RaplaStartupEnvironment();
  132. env.setStartupMode( StartupEnvironment.SERVLET);
  133. env.setConfigURL( configURL );
  134. env.setLogConfigURL( logConfigURL );
  135. raplaMainContainer = new RaplaMainContainer( env );
  136. logger = (Logger)raplaMainContainer.getContext().lookup(Logger.class.getName());
  137. try {
  138. //lookup shutdownService
  139. ShutdownService shutdownService = (ShutdownService) raplaMainContainer.getContext().lookup(ShutdownService.ROLE);
  140. shutdownService.addShutdownListener( shutdownListener );
  141. } catch (RaplaContextException ex) {
  142. log("No shutdown service found. You must stop the server with ctrl-c!");
  143. }
  144. // Start the storage service
  145. RaplaContext sm = raplaMainContainer.getContext();
  146. String lookupName = ServerService.ROLE ;
  147. serverService = (ServerService)sm.lookup( lookupName );
  148. pageList = serverService.getAllServicesFor( RaplaExtensionPoints.SERVLET_PAGE_EXTENSION);
  149. getServletConfig().getServletContext().setAttribute("context", sm);
  150. }
  151. catch( Exception e )
  152. {
  153. if ( logger != null) {
  154. logger.fatalError("Could not start server", e);
  155. }
  156. ContainerUtil.dispose( raplaMainContainer);
  157. log( "Problem starting Rapla ", e );
  158. throw new ServletException( "Error during initialization", e );
  159. }
  160. log("Rapla Servlet started");
  161. }
  162. /**
  163. * Pass all servlet requests through to container to be handled.
  164. ^s */
  165. public void service( HttpServletRequest request, HttpServletResponse response )
  166. throws IOException, ServletException
  167. {
  168. String page = request.getParameter("page");
  169. String contextPath =request.getRequestURI();
  170. int rpcIndex=contextPath.indexOf("/rapla/rpc/") ;
  171. if ( rpcIndex>= 0) {
  172. handleRPCCall( request, response, contextPath );
  173. return;
  174. }
  175. if ( page == null || page.trim().length() == 0) {
  176. page = "index";
  177. }
  178. if (pageList.contains( page) ) {
  179. RaplaPageGenerator servletPage;
  180. try {
  181. servletPage = (RaplaPageGenerator) serverService.getContext().lookup( RaplaExtensionPoints.SERVLET_PAGE_EXTENSION + "/" + page );
  182. } catch (RaplaContextException e) {
  183. java.io.PrintWriter out = response.getWriter();
  184. out.println(IOUtil.getStackTraceAsString( e));
  185. throw new ServletException( e);
  186. }
  187. servletPage.generatePage( getServletContext(), request, response);
  188. } else {
  189. throw new ServletException( "Page " + page + " not found in Rapla context");
  190. }
  191. }
  192. private void handleRPCCall( HttpServletRequest request, HttpServletResponse response, String contextPath ) throws IOException
  193. {
  194. int rpcIndex=contextPath.indexOf("/rapla/rpc/") ;
  195. String methodName = contextPath.substring(rpcIndex + "/rapla/rpc/".length());
  196. HttpSession session = request.getSession( true);
  197. if ( methodName.equals("getException"))
  198. {
  199. Exception ex = (Exception)session.getAttribute("lastException");
  200. if ( ex == null)
  201. {
  202. response.sendError( 500 , "No exception found");
  203. } else {
  204. ObjectOutputStream out = new ObjectOutputStream( response.getOutputStream());
  205. out.writeObject( ex);
  206. out.flush();
  207. }
  208. return;
  209. }
  210. String username = (String)session.getAttribute("username");
  211. try
  212. {
  213. Map originalMap = request.getParameterMap();
  214. Map parameterMap = makeSingles(originalMap);
  215. ServerServiceImpl server = (ServerServiceImpl)raplaMainContainer.getContext().lookup( ServerService.ROLE);
  216. if ( methodName.equals(RemoteServer.ROLE + "/login"))
  217. {
  218. List arg = new ArrayList(parameterMap.values());
  219. username = (String) arg.get(0);
  220. String password = (String) arg.get( 1);
  221. //parameterMap.get("password");
  222. server.login( username, password);
  223. session.setAttribute("username", username);
  224. response.getWriter().println("Login successfull" );
  225. }
  226. else if ( methodName.equals(RemoteServer.ROLE + "/logout"))
  227. {
  228. session.removeAttribute("username");
  229. response.getWriter().println("User logout" );
  230. }
  231. else
  232. {
  233. RemoteSession remoteSession = (RemoteSession)session.getAttribute(RemoteSession.class.getName());
  234. currentSession.set( remoteSession);
  235. if ( remoteSession != null)
  236. {
  237. // If session was created by another server, than invalidate
  238. if (((RemoteSessionImpl)remoteSession).getServerStartTime() != serverStartTime)
  239. {
  240. remoteSession = null;
  241. }
  242. }
  243. if ( remoteSession == null)
  244. {
  245. remoteSession = new RemoteSessionImpl(server.getContext(), session.getId(), serverStartTime);
  246. session.setAttribute( RemoteSession.class.getName(), remoteSession);
  247. }
  248. ((RemoteSessionImpl)remoteSession).setUsername( username);
  249. byte[] out = server.dispatch(remoteSession, methodName, parameterMap);
  250. response.setContentType( "text/html; charset=utf-8");
  251. //response.setCharacterEncoding( "utf-8" );
  252. response.getOutputStream().write( out );
  253. }
  254. // response.getWriter().println("There are currently " + reservations + " reservations");
  255. }
  256. catch (Exception e)
  257. {
  258. String message = e.getMessage();
  259. if ( message == null )
  260. {
  261. message = e.getClass().getName();
  262. }
  263. session.setAttribute( "lastException", e);
  264. response.addHeader("X-Error-Stacktrace", message);
  265. response.getWriter().println("Error: " + IOUtil.getStackTraceAsString( e));
  266. //response.sendError( 500, e.getMessage());
  267. response.setStatus( 500);
  268. //throw new ServletException( e);
  269. }
  270. }
  271. private Map makeSingles( Map parameterMap )
  272. {
  273. TreeMap singlesMap = new TreeMap();
  274. for (Iterator it = parameterMap.keySet().iterator();it.hasNext();)
  275. {
  276. String key = (String)it.next();
  277. String[] values = (String[]) parameterMap.get( key);
  278. if ( values != null && values.length > 0 )
  279. {
  280. singlesMap.put( key,values[0]);
  281. }
  282. else
  283. {
  284. singlesMap.put( key,null);
  285. }
  286. }
  287. return singlesMap;
  288. }
  289. private void stopServer() {
  290. try {
  291. ShutdownService shutdownService = (ShutdownService) raplaMainContainer.getContext().lookup(ShutdownService.ROLE);
  292. shutdownService.removeShutdownListener( shutdownListener );
  293. ContainerUtil.dispose( raplaMainContainer );
  294. } catch (Exception ex) {
  295. log("Error while stopping server");
  296. }
  297. }
  298. /**
  299. * Disposes of container manager and container instance.
  300. */
  301. public void destroy()
  302. {
  303. log("Destroying rapla");
  304. stopServer();
  305. }
  306. public RaplaContext getContext()
  307. {
  308. return raplaMainContainer.getContext();
  309. }
  310. static ThreadLocal<RemoteSession> currentSession = new ThreadLocal<RemoteSession>();
  311. static public RemoteSession getSession()
  312. {
  313. return currentSession.get();
  314. }
  315. }