00001 /* 00002 * Copyright (C) 2011 Google Inc. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 00005 * use this file except in compliance with the License. You may obtain a copy of 00006 * the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 00013 * License for the specific language governing permissions and limitations under 00014 * the License. 00015 */ 00016 00017 package org.ros.internal.node.server; 00018 00019 import org.apache.commons.logging.Log; 00020 import org.apache.commons.logging.LogFactory; 00021 import org.apache.xmlrpc.XmlRpcException; 00022 import org.apache.xmlrpc.server.PropertyHandlerMapping; 00023 import org.apache.xmlrpc.server.XmlRpcServerConfigImpl; 00024 import org.apache.xmlrpc.webserver.WebServer; 00025 import org.ros.address.AdvertiseAddress; 00026 import org.ros.address.BindAddress; 00027 import org.ros.exception.RosRuntimeException; 00028 import org.ros.internal.system.Process; 00029 00030 import java.io.IOException; 00031 import java.net.InetSocketAddress; 00032 import java.net.URI; 00033 import java.util.concurrent.Callable; 00034 import java.util.concurrent.CountDownLatch; 00035 import java.util.concurrent.TimeUnit; 00036 00042 public class XmlRpcServer { 00043 00044 private static final boolean DEBUG = false; 00045 private static final Log log = LogFactory.getLog(XmlRpcServer.class); 00046 00047 private final WebServer server; 00048 private final AdvertiseAddress advertiseAddress; 00049 private final CountDownLatch startLatch; 00050 00051 public XmlRpcServer(BindAddress bindAddress, AdvertiseAddress advertiseAddress) { 00052 InetSocketAddress address = bindAddress.toInetSocketAddress(); 00053 server = new WebServer(address.getPort(), address.getAddress()); 00054 this.advertiseAddress = advertiseAddress; 00055 this.advertiseAddress.setPortCallable(new Callable<Integer>() { 00056 @Override 00057 public Integer call() throws Exception { 00058 return server.getPort(); 00059 } 00060 }); 00061 startLatch = new CountDownLatch(1); 00062 } 00063 00073 public <T extends org.ros.internal.node.xmlrpc.XmlRpcEndpoint> void start(Class<T> instanceClass, 00074 T instance) { 00075 org.apache.xmlrpc.server.XmlRpcServer xmlRpcServer = server.getXmlRpcServer(); 00076 PropertyHandlerMapping phm = new PropertyHandlerMapping(); 00077 phm.setRequestProcessorFactoryFactory(new NodeRequestProcessorFactoryFactory<T>(instance)); 00078 try { 00079 phm.addHandler("", instanceClass); 00080 } catch (XmlRpcException e) { 00081 throw new RosRuntimeException(e); 00082 } 00083 xmlRpcServer.setHandlerMapping(phm); 00084 XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig(); 00085 serverConfig.setEnabledForExtensions(false); 00086 serverConfig.setContentLengthOptional(false); 00087 try { 00088 server.start(); 00089 } catch (IOException e) { 00090 throw new RosRuntimeException(e); 00091 } 00092 if (DEBUG) { 00093 log.info("Bound to: " + getUri()); 00094 } 00095 startLatch.countDown(); 00096 } 00097 00101 public void shutdown() { 00102 server.shutdown(); 00103 } 00104 00108 public URI getUri() { 00109 return advertiseAddress.toUri("http"); 00110 } 00111 00112 public InetSocketAddress getAddress() { 00113 return advertiseAddress.toInetSocketAddress(); 00114 } 00115 00116 public AdvertiseAddress getAdvertiseAddress() { 00117 return advertiseAddress; 00118 } 00119 00120 public void awaitStart() throws InterruptedException { 00121 startLatch.await(); 00122 } 00123 00124 public boolean awaitStart(long timeout, TimeUnit unit) throws InterruptedException { 00125 return startLatch.await(timeout, unit); 00126 } 00127 00132 public int getPid() { 00133 return Process.getPid(); 00134 } 00135 }