/******************************************************************************** * * JOrocos Library * * Copyright (c) 2011 * All rights reserved. * * Luca Gherardi * University of Bergamo * Dept. of Information Technology and Mathematics * * ------------------------------------------------------------------------------- * * File: CorbaOrocosService.java * Created: Jul 27, 2011 * * Author: <A HREF="mailto:luca.gherardi@unibg.it">Luca Gherardi</A> * * Supervised by: <A HREF="mailto:brugali@unibg.it">Davide Brugali</A> * * In cooperation with: <A HREF="mailto:herman.bruyninckx@mech.kuleuven.be">Herman Bruyninckx</A> * * ------------------------------------------------------------------------------- * * This software is published under a dual-license: GNU Lesser General Public * License LGPL 2.1 and BSD license. The dual-license implies that users of this * code may choose which terms they prefer. * * ------------------------------------------------------------------------------- * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - Neither the name of the University of Bergamo nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License LGPL as * published by the Free Software Foundation, either version 2.1 of the * License, or (at your option) any later version or the BSD license. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License LGPL and the BSD license for more details. * * You should have received a copy of the GNU Lesser General Public * License LGPL and BSD license along with this program. * *******************************************************************************/ package it.unibg.robotics.jorocos.corba; import it.unibg.robotics.jorocos.core.AbstractOrocosService; import it.unibg.robotics.jorocos.core.OrocosOperation; import it.unibg.robotics.jorocos.core.OrocosProperty; import it.unibg.robotics.jorocos.exceptions.OrocosPropertyNotExistException; import it.unibg.robotics.jorocos.exceptions.OrocosServiceNotExistException; import it.unibg.robotics.jorocos.interfaces.CallbackListener; import org.omg.CORBA.Any; import RTT.corba.CAnyArgumentsHolder; import RTT.corba.CCallInterrupted; import RTT.corba.CNoSuchNameException; import RTT.corba.CSendHandle; import RTT.corba.CSendStatus; import RTT.corba.CService; import RTT.corba.CWrongNumbArgException; import RTT.corba.CWrongTypeArgException; /** * The class CorbaOrocosService is a specialization of AbstractOrocosService * defined for the CORBA transport. * * @author <A HREF="mailto:luca.gherardi@unibg.it">Luca Gherardi</A> * @version 1.0 * @since August 2011 */ public class CorbaOrocosService extends AbstractOrocosService{ /** * Instantiates a new Corba Orocos service. * * @param service a pointer to the service that has to be modeled * @param introspect if true the constructor will introspect the service and store * all the information about its services, operation and properties. * This information can be retrieved by using the methods {@link #getServices()}, * {@link #getOperations()} and {@link #getProperties()}. */ public CorbaOrocosService(CService service, boolean introspect) { super(service, introspect); } /** * @see AbstractOrocosService#callOperationSynchronously(String, Object...) */ @Override public Object callOperationSynchronously(String operationName, Object... arguments){ OrocosOperation operation = getOperation(operationName); Any[] anyArguments = castOperationArguments(operation, arguments); CAnyArgumentsHolder holder = new CAnyArgumentsHolder(anyArguments); try { Any result = getCService().callOperation(operationName, holder); if(operation.getReturnType().equals("void")){ return null; } return AnyObjectCast.anyToObject(result); } catch (CNoSuchNameException e) { e.printStackTrace(); } catch (CWrongNumbArgException e) { logger.error("The number of the arguments passed to the operation is wrong."); e.printStackTrace(); } catch (CWrongTypeArgException e) { logger.error("At least one of the arguments passed to the operation belong to a wrong type."); e.printStackTrace(); } catch (CCallInterrupted e) { e.printStackTrace(); } return null; } /** * @see AbstractOrocosService#callOperationAsynchronously(String, CallbackListener, int, Object...) */ @Override public void callOperationAsynchronously(final String operationName, final CallbackListener listener, final int periodMs, final Object... arguments) { final String serviceName = getName(); Thread thread = new Thread() { public void run() { try { OrocosOperation operation = getOperation(operationName); Any[] anyArguments = castOperationArguments(operation, arguments); CAnyArgumentsHolder holder = new CAnyArgumentsHolder(anyArguments); CSendHandle handler = getCService().sendOperation(operationName, anyArguments); CSendStatus sendStatus = handler.collectIfDone(holder); while(sendStatus == CSendStatus.CSendNotReady){ sendStatus = handler.collectIfDone(holder); // System.out.println("SendStatus: " + sendStatus.value()); Thread.sleep(periodMs); } if(sendStatus == CSendStatus.CSendSuccess){ Object returnValue = AnyObjectCast.anyToObject(handler.ret()); listener.callback(serviceName, operationName, returnValue); }else if(sendStatus == CSendStatus.CSendFailure){ listener.callback(serviceName, operationName, null); logger.error("The asynchornous call to the operation '" + operationName + "' fails."); } } catch (CNoSuchNameException e) { e.printStackTrace(); } catch (CWrongNumbArgException e) { logger.error("The number of the arguments passed to the operation is wrong."); e.printStackTrace(); } catch (CWrongTypeArgException e) { logger.error("At least one of the arguments passed to the operation belong to a wrong type."); e.printStackTrace(); } catch (CCallInterrupted e) { e.printStackTrace(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }; thread.start(); } /** * @see AbstractOrocosService#introspectService(String, boolean) */ @Override protected AbstractOrocosService introspectService(String name, boolean introspect) throws OrocosServiceNotExistException{ CService service = getCService().getService(name); if(service == null){ logger.error("The required Orocos service (name: " + name + ") does not exist."); throw new OrocosServiceNotExistException(name); } AbstractOrocosService orocosService = new CorbaOrocosService(service,introspect); return orocosService; } /** * Cast the arguments of an operation from a list of {@link java.lang.Object} to * an array of {@link org.omg.CORBA.Any} * @param operation the name of the operation * @param arguments the list of the operation arguments that have to be casted * @return the array of casted operation arguments */ private Any[] castOperationArguments(OrocosOperation operation, Object... arguments){ Any[] anyArguments = new Any[arguments.length]; for (int i = 0; i < arguments.length; i++) { anyArguments[i] = AnyObjectCast.objectToAny(arguments[i],operation.getArguments().get(i).getDataType().toLowerCase()); } return anyArguments; } /** * @see AbstractOrocosService#getPropertyValue(String) */ @Override public Object getPropertyValue(String propertyName) throws OrocosPropertyNotExistException { OrocosProperty property = getProperty(propertyName); // Check if the property exists return AnyObjectCast.anyToObject(getCService().getProperty(property.getName())); } /** * @see AbstractOrocosService#setPropertyValue(String, Object) */ @Override public void setPropertyValue(String propertyName, Object value) throws OrocosPropertyNotExistException { getCService().setProperty(propertyName, AnyObjectCast.objectToAny(value, getProperty(propertyName).getDataType())); } }