$search
00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Copyright (c) 2008, Willow Garage, Inc. 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions 00009 * are met: 00010 * 00011 * * Redistributions of source code must retain the above copyright 00012 * notice, this list of conditions and the following disclaimer. 00013 * * Redistributions in binary form must reproduce the above 00014 * copyright notice, this list of conditions and the following 00015 * disclaimer in the documentation and/or other materials provided 00016 * with the distribution. 00017 * * Neither the name of Willow Garage, Inc. nor the names of its 00018 * contributors may be used to endorse or promote products derived 00019 * from this software without specific prior written permission. 00020 * 00021 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00022 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00023 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00024 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00025 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00026 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00027 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00028 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00029 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00030 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00031 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 */ 00034 00035 // author: Jason Wolfe 00036 00037 00038 package ros.roscpp; 00039 00040 import java.util.Map; 00041 import java.util.concurrent.Callable; 00042 import java.util.concurrent.ExecutionException; 00043 import java.util.concurrent.ExecutorService; 00044 import java.util.concurrent.Executors; 00045 import java.util.concurrent.FutureTask; 00046 00047 import ros.RosException; 00048 import ros.ServiceClient; 00049 import ros.communication.Message; 00050 import ros.communication.Service; 00051 00052 public class CppServiceClient<Q extends Message, A extends Message, S extends Service<Q, A> > implements ServiceClient<Q, A, S> { 00053 private CppNodeHandle handle; 00054 private String name; 00055 private S serviceTemplate; 00056 private long cppServiceClient; 00057 private ExecutorService threadPool; 00058 00059 private CppServiceClient() { } 00060 00061 protected static <Q extends Message, A extends Message, S extends Service<Q, A> > CppServiceClient<Q,A,S> 00062 create(CppNodeHandle handle, long cppHandle, String name, S serviceTemplate, boolean isPersistant, Map<String, String> headerValues) { 00063 CppServiceClient<Q, A, S> that = new CppServiceClient<Q, A, S>(); 00064 that.handle = handle; 00065 that.name = name; 00066 that.serviceTemplate = serviceTemplate; 00067 that.cppServiceClient = JNI.serviceClient(cppHandle, name, serviceTemplate.getMD5Sum(), isPersistant, Util.mapToArray(headerValues)); 00068 if (that.cppServiceClient == 0) throw new RuntimeException("Could not create service client " + name + "(should not happen)"); 00069 return that; 00070 } 00071 00072 public String getService() {return name; } 00073 00074 public A call(Q request) throws RosException { 00075 A response = serviceTemplate.createResponse(); 00076 if (!JNI.callService(cppServiceClient, request, response, serviceTemplate.getMD5Sum())) throw new RosException("Service call failed!"); 00077 return response; 00078 } 00079 00080 public FutureTask<A> callAsync(final Q request) throws RosException { 00081 if (threadPool == null) threadPool = Executors.newCachedThreadPool(); 00082 final CppServiceClient<Q, A, S> that = this; 00083 FutureTask<A> f = new FutureTask<A>(new Callable<A>() { 00084 public A call() throws Exception { 00085 return (A) that.call(request); 00086 } 00087 }); 00088 handle.submitFuture(f); 00089 return f; 00090 } 00091 00092 public A callLocal(Q request) throws RosException { 00093 FutureTask<A> f = callAsync(request); 00094 while(!f.isDone()) { 00095 handle.spinOnce(); 00096 } 00097 try { 00098 return f.get(); 00099 } catch (InterruptedException e) { 00100 throw new RosException("InterruptedException in callLocal", e); 00101 } catch (ExecutionException e) { 00102 throw new RosException("ExecutionException in callLocal", e); 00103 } 00104 } 00105 00106 public boolean isValid() { return (cppServiceClient != 0); } 00107 00108 public void shutdown() { 00109 if (!isValid()) return; 00110 JNI.shutdownServiceClient(cppServiceClient); 00111 cppServiceClient = 0; 00112 } 00113 } 00114