/******************************************************************************* * Copyright (c) 2008-2011 Chair for Applied Software Engineering, * Technische Universitaet Muenchen. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: ******************************************************************************/ package org.eclipse.emf.emfstore.server.connection.xmlrpc; import java.io.IOException; import java.net.InetAddress; import java.net.ServerSocket; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocketFactory; import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.server.PropertyHandlerMapping; import org.apache.xmlrpc.server.XmlRpcServer; import org.apache.xmlrpc.server.XmlRpcServerConfigImpl; import org.apache.xmlrpc.webserver.WebServer; import org.eclipse.emf.emfstore.common.model.util.ModelUtil; import org.eclipse.emf.emfstore.server.EmfStoreController; import org.eclipse.emf.emfstore.server.ServerConfiguration; import org.eclipse.emf.emfstore.server.connection.ServerKeyStoreManager; import org.eclipse.emf.emfstore.server.connection.xmlrpc.util.EObjectTypeConverterFactory; import org.eclipse.emf.emfstore.server.connection.xmlrpc.util.EObjectTypeFactory; import org.eclipse.emf.emfstore.server.exceptions.FatalEmfStoreException; import org.eclipse.emf.emfstore.server.exceptions.ServerKeyStoreException; /** * Manages the webserver for XML RPC connections. * * @author wesendon */ public final class XmlRpcWebserverManager { private static XmlRpcWebserverManager instance; private WebServer webServer; private final int port; private XmlRpcWebserverManager() { int tmp = 8080; try { tmp = Integer.valueOf(ServerConfiguration.getProperties().getProperty(ServerConfiguration.XML_RPC_PORT)); } catch (NumberFormatException e) { tmp = Integer.valueOf(ServerConfiguration.XML_RPC_PORT_DEFAULT); } port = tmp; } /** * Returns instance of the webserver manager. * * @return instance of websever manager. */ public static XmlRpcWebserverManager getInstance() { if (instance == null) { instance = new XmlRpcWebserverManager(); } return instance; } /** * Starts the server. * * @throws FatalEmfStoreException in case of failure */ public void initServer() throws FatalEmfStoreException { if (webServer != null) { return; } try { webServer = new WebServer(port) { @Override protected ServerSocket createServerSocket(int pPort, int backlog, InetAddress addr) throws IOException { SSLServerSocketFactory serverSocketFactory = null; try { SSLContext context = SSLContext.getInstance("TLS"); context.init(ServerKeyStoreManager.getInstance().getKeyManagerFactory().getKeyManagers(), null, null); serverSocketFactory = context.getServerSocketFactory(); } catch (NoSuchAlgorithmException e) { ModelUtil.logException("Couldn't initialize server socket.", e); EmfStoreController.getInstance().shutdown(new FatalEmfStoreException()); } catch (KeyManagementException e) { ModelUtil.logException("Couldn't initialize server socket.", e); EmfStoreController.getInstance().shutdown(new FatalEmfStoreException()); } catch (ServerKeyStoreException e) { ModelUtil.logException("Couldn't initialize server socket.", e); EmfStoreController.getInstance().shutdown(new FatalEmfStoreException()); } return serverSocketFactory.createServerSocket(pPort, backlog, addr); } }; ModelUtil.logInfo("Started XML RPC Webserver on port: " + port); XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer(); xmlRpcServer.setTypeFactory(new EObjectTypeFactory(xmlRpcServer)); EObjectTypeConverterFactory pFactory = new EObjectTypeConverterFactory(); xmlRpcServer.setTypeConverterFactory(pFactory); PropertyHandlerMapping phm = new PropertyHandlerMapping(); phm.setVoidMethodEnabled(true); phm.setTypeConverterFactory(pFactory); xmlRpcServer.setHandlerMapping(phm); XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig(); serverConfig.setEnabledForExtensions(true); serverConfig.setEnabledForExceptions(true); serverConfig.setContentLengthOptional(false); webServer.start(); } catch (IOException e) { throw new FatalEmfStoreException("Couldn't start webserver", e); } } /** * Adds a handler to the webserver. * * @param handlerName handler name * @param clazz class of server interface * @throws FatalEmfStoreException in case of failure */ public void addHandler(String handlerName, Class<?> clazz) throws FatalEmfStoreException { try { PropertyHandlerMapping mapper = (PropertyHandlerMapping) webServer.getXmlRpcServer().getHandlerMapping(); mapper.addHandler(handlerName, clazz); } catch (XmlRpcException e) { throw new FatalEmfStoreException("Couldn't add handler", e); } } /** * Removes a handler from the Webserver. * * @param handlerName the handler's name * @return true, if other handler still available */ public boolean removeHandler(String handlerName) { PropertyHandlerMapping mapper = (PropertyHandlerMapping) webServer.getXmlRpcServer().getHandlerMapping(); mapper.removeHandler(handlerName); try { return mapper.getListMethods().length > 0; } catch (XmlRpcException e) { return false; } } /** * Stops the server. */ public void stopServer() { webServer.shutdown(); webServer = null; } }