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.message; 00018 00019 import com.google.common.base.Preconditions; 00020 00021 import org.ros.internal.message.context.MessageContext; 00022 import org.ros.internal.message.context.MessageContextProvider; 00023 import org.ros.message.MessageDeclaration; 00024 import org.ros.message.MessageFactory; 00025 00026 import java.lang.reflect.Proxy; 00027 import java.util.concurrent.atomic.AtomicInteger; 00028 00032 public class MessageProxyFactory { 00033 00034 // We can't use the constant here since the rosjava_messages package depends 00035 // on rosjava_bootstrap. 00036 private static final String HEADER_MESSAGE_TYPE = "std_msgs/Header"; 00037 private static final String SEQUENCE_FIELD_NAME = "seq"; 00038 private static final AtomicInteger SEQUENCE_NUMBER = new AtomicInteger(0); 00039 00040 private final MessageInterfaceClassProvider messageInterfaceClassProvider; 00041 private final MessageContextProvider messageContextProvider; 00042 00043 public MessageProxyFactory(MessageInterfaceClassProvider messageInterfaceClassProvider, 00044 MessageFactory messageFactory) { 00045 this.messageInterfaceClassProvider = messageInterfaceClassProvider; 00046 messageContextProvider = new MessageContextProvider(messageFactory); 00047 } 00048 00049 @SuppressWarnings("unchecked") 00050 public <T> T newMessageProxy(MessageDeclaration messageDeclaration) { 00051 Preconditions.checkNotNull(messageDeclaration); 00052 MessageContext messageContext = messageContextProvider.get(messageDeclaration); 00053 MessageImpl messageImpl = new MessageImpl(messageContext); 00054 // Header messages are automatically populated with a monotonically 00055 // increasing sequence number. 00056 if (messageImpl.getType().equals(HEADER_MESSAGE_TYPE)) { 00057 messageImpl.setUInt32(SEQUENCE_FIELD_NAME, SEQUENCE_NUMBER.getAndIncrement()); 00058 } 00059 Class<T> messageInterfaceClass = 00060 (Class<T>) messageInterfaceClassProvider.get(messageDeclaration.getType()); 00061 return newProxy(messageInterfaceClass, messageImpl); 00062 } 00063 00072 @SuppressWarnings("unchecked") 00073 private <T> T newProxy(Class<T> interfaceClass, final MessageImpl messageImpl) { 00074 ClassLoader classLoader = messageImpl.getClass().getClassLoader(); 00075 Class<?>[] interfaces = new Class<?>[] { interfaceClass, GetInstance.class }; 00076 MessageProxyInvocationHandler invocationHandler = 00077 new MessageProxyInvocationHandler(messageImpl); 00078 return (T) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler); 00079 } 00080 }