Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
/*--------------------------------------------------------------------------*
| Copyright (C) 2006 Christopher Kohlhaas |
| |
| 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. A copy of the license has been included with |
| these distribution in the COPYING file, if not go to www.fsf.org |
| |
| As a special exception, you are granted the permissions to link this |
| program with every library, which license fulfills the Open Source |
| Definition as published by the Open Source Initiative (OSI). |
*--------------------------------------------------------------------------*/
package org.rapla;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
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.apache.avalon.framework.container.ContainerUtil;
import org.apache.avalon.framework.logger.Logger;
import org.rapla.components.util.IOUtil;
import org.rapla.framework.Container;
import org.rapla.framework.RaplaContext;
import org.rapla.framework.RaplaContextException;
import org.rapla.framework.StartupEnvironment;
import org.rapla.plugin.RaplaExtensionPoints;
import org.rapla.server.RemoteSession;
import org.rapla.server.ServerService;
import org.rapla.server.ShutdownListener;
import org.rapla.server.ShutdownService;
import org.rapla.server.internal.RemoteSessionImpl;
import org.rapla.server.internal.ServerServiceImpl;
import org.rapla.servletpages.RaplaPageGenerator;
final public class MainServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/** The default config filename is raplaserver.xconf*/
Container raplaMainContainer;
public final static String DEFAULT_CONFIG_NAME = "raplaserver.xconf";
Collection pageList;
ServerService serverService;
long serverStartTime;
String serverId = null;
private File getConfigFile(String entryName, String defaultName) throws ServletException,IOException {
String configName = getServletConfig().getInitParameter(entryName);
if (configName == null)
configName = defaultName;
if (configName == null)
throw new ServletException("Must specify " + entryName + " entry in web.xml !");
File configFile = new File(getServletConfig().getServletContext().getRealPath("/WEB-INF/" + configName));
if (!configFile.exists()) {
String message = "ERROR: Config file not found " + configName;
throw new ServletException(message);
}
return configFile.getCanonicalFile();
}
public String getServerId()
{
return serverId;
}
public void setServerId( String serverId )
{
this.serverId = serverId;
}
/**
* Initializes Servlet and creates a <code>RaplaMainContainer</code> instance
*
* @exception ServletException if an error occurs
*/
public void init()
throws ServletException
{
String realPath = getServletContext().getRealPath("webclient");
// if (realPath != null)
{
File webclientFolder= new File(realPath );
webclientFolder.mkdir();
copy( "WEB-INF/lib/rapla.jar", "webclient/rapla.jar" );
}
startServer();
}
private void copy( String sourceLib, String destLib ) throws ServletException
{
if (!new File(getServletContext().getRealPath(sourceLib)).exists())
{
return;
}
try
{
log("Copy " + sourceLib + " to " + destLib);
IOUtil.copy( getServletContext().getRealPath(sourceLib), getServletContext().getRealPath(destLib), true);
}
catch (IOException e)
{
throw new ServletException("Can't copy " + sourceLib + " Cause " + e.getMessage());
}
}
ShutdownListener shutdownListener = new ShutdownListener() {
public void shutdownInitiated() {
}
public void shutdownComplete( boolean restart) {
if ( restart ) {
Thread restartThread = new Thread() {
public void run() {
try {
log( "Stopping Server");
stopServer();
//getServletContext()
log( "Restarting Server");
startServer();
} catch (Exception e) {
log( "Error while restarting Server", e );
}
}
};
restartThread.setDaemon( false );
restartThread.start();
}
}
};
void startServer()throws ServletException {
log("Starting Rapla Servlet");
Logger logger = null;
serverStartTime = System.currentTimeMillis();
try
{
File configFile = getConfigFile("config-file",DEFAULT_CONFIG_NAME);
URL configURL = configFile.toURI().toURL();
URL logConfigURL = getConfigFile("log-config-file","raplaserver.xlog").toURI().toURL();
RaplaStartupEnvironment env = new RaplaStartupEnvironment();
env.setStartupMode( StartupEnvironment.SERVLET);
env.setConfigURL( configURL );
env.setLogConfigURL( logConfigURL );
raplaMainContainer = new RaplaMainContainer( env );
logger = (Logger)raplaMainContainer.getContext().lookup(Logger.class.getName());
try {
//lookup shutdownService
ShutdownService shutdownService = (ShutdownService) raplaMainContainer.getContext().lookup(ShutdownService.ROLE);
shutdownService.addShutdownListener( shutdownListener );
} catch (RaplaContextException ex) {
log("No shutdown service found. You must stop the server with ctrl-c!");
}
// Start the storage service
RaplaContext sm = raplaMainContainer.getContext();
String lookupName = ServerService.ROLE ;
if (serverId != null)
{
lookupName += "/" + serverId;
}
serverService = (ServerService)sm.lookup( lookupName );
pageList = serverService.getAllServicesFor( RaplaExtensionPoints.SERVLET_PAGE_EXTENSION);
getServletConfig().getServletContext().setAttribute("context", sm);
}
catch( Exception e )
{
if ( logger != null) {
logger.fatalError("Could not start server", e);
}
ContainerUtil.dispose( raplaMainContainer);
log( "Problem starting Rapla ", e );
throw new ServletException( "Error during initialization", e );
}
log("Rapla Servlet started");
}
/**
* Pass all servlet requests through to container to be handled.
^s */
public void service( HttpServletRequest request, HttpServletResponse response )
throws IOException, ServletException
{
String page = request.getParameter("page");
String contextPath =request.getRequestURI();
int rpcIndex=contextPath.indexOf("/rapla/rpc/") ;
if ( rpcIndex>= 0) {
handleRPCCall( request, response, contextPath );
return;
}
if ( page == null || page.trim().length() == 0) {
page = "index";
}
if (pageList.contains( page) ) {
RaplaPageGenerator servletPage;
try {
servletPage = (RaplaPageGenerator) serverService.getContext().lookup( RaplaExtensionPoints.SERVLET_PAGE_EXTENSION + "/" + page );
} catch (RaplaContextException e) {
java.io.PrintWriter out = response.getWriter();
out.println(IOUtil.getStackTraceAsString( e));
throw new ServletException( e);
}
servletPage.generatePage( getServletContext(), request, response);
} else {
throw new ServletException( "Page " + page + " not found in Rapla context");
}
}
private void handleRPCCall( HttpServletRequest request, HttpServletResponse response, String contextPath ) throws IOException
{
int rpcIndex=contextPath.indexOf("/rapla/rpc/") ;
String methodName = contextPath.substring(rpcIndex + "/rapla/rpc/".length());
HttpSession session = request.getSession( true);
if ( methodName.equals("getException"))
{
Exception ex = (Exception)session.getAttribute("lastException");
if ( ex == null)
{
response.sendError( 500 , "No exception found");
} else {
ObjectOutputStream out = new ObjectOutputStream( response.getOutputStream());
out.writeObject( ex);
out.flush();
}
return;
}
String username = (String)session.getAttribute("username");
try
{
Map paramterMap = makeSingles(request.getParameterMap());
ServerServiceImpl server = (ServerServiceImpl)raplaMainContainer.getContext().lookup( ServerService.ROLE);
if ( methodName.equals("login"))
{
username = server.login( paramterMap);
session.setAttribute("username", username);
response.getWriter().println("Login successfull" );
}
else if ( methodName.equals("logout"))
{
session.removeAttribute("username");
response.getWriter().println("User logout" );
}
else
{
RemoteSession remoteSession = (RemoteSession)session.getAttribute(RemoteSession.class.getName());
if ( remoteSession != null)
{
// If session was created by another server, than invalidate
if (((RemoteSessionImpl)remoteSession).getServerStartTime() != serverStartTime)
{
remoteSession = null;
}
}
if ( remoteSession == null)
{
remoteSession = new RemoteSessionImpl(server.getContext(), session.getId(), serverStartTime);
session.setAttribute( RemoteSession.class.getName(), remoteSession);
}
((RemoteSessionImpl)remoteSession).setUsername( username);
byte[] out = server.dispatch(remoteSession, methodName, paramterMap);
response.setContentType( "text/html; charset=utf-8");
//response.setCharacterEncoding( "utf-8" );
response.getOutputStream().write( out );
}
// response.getWriter().println("There are currently " + reservations + " reservations");
}
catch (Exception e)
{
String message = e.getMessage();
if ( message == null )
{
message = e.getClass().getName();
}
session.setAttribute( "lastException", e);
response.addHeader("X-Error-Stacktrace", message);
response.getWriter().println("Error: " + IOUtil.getStackTraceAsString( e));
//response.sendError( 500, e.getMessage());
response.setStatus( 500);
//throw new ServletException( e);
}
}
private Map makeSingles( Map parameterMap )
{
Map singlesMap = new HashMap();
for (Iterator it = parameterMap.keySet().iterator();it.hasNext();)
{
String key = (String)it.next();
String[] values = (String[]) parameterMap.get( key);
if ( values != null && values.length > 0 )
{
singlesMap.put( key,values[0]);
}
else
{
singlesMap.put( key,null);
}
}
return singlesMap;
}
private void stopServer() {
try {
ShutdownService shutdownService = (ShutdownService) raplaMainContainer.getContext().lookup(ShutdownService.ROLE);
shutdownService.removeShutdownListener( shutdownListener );
ContainerUtil.dispose( raplaMainContainer );
} catch (Exception ex) {
log("Error while stopping server");
}
}
/**
* Disposes of container manager and container instance.
*/
public void destroy()
{
log("Destroying rapla");
stopServer();
}
public RaplaContext getContext()
{
return raplaMainContainer.getContext();
}
}