/* * Copyright (C) 2011 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package org.ros.internal.node.response; import com.google.common.collect.Lists; import org.ros.exception.RemoteException; import org.ros.exception.RosRuntimeException; import java.util.List; /** * The response from an XML-RPC call. * * @author damonkohler@google.com (Damon Kohler) * * @param <T> */ public class Response<T> { private final StatusCode statusCode; private final String statusMessage; private final T result; public static <T> Response<T> newError(String message, T value) { return new Response<T>(StatusCode.ERROR, message, value); } public static <T> Response<T> newFailure(String message, T value) { return new Response<T>(StatusCode.FAILURE, message, value); } public static <T> Response<T> newSuccess(String message, T value) { return new Response<T>(StatusCode.SUCCESS, message, value); } /** * Creates a {@link Response} from the {@link List} of {@link Object}s * returned from an XML-RPC call. Throws {@link RemoteException} if the * {@link StatusCode} is StatusCode.FAILURE. * * @param <T> * @param response * the {@link List} of {@link Object}s returned from the XML-RPC call * @param resultFactory * a {@link ResultFactory} that creates a result from the third * {@link Object} in the {@link Response} * @return a {@link Response} using the specified {@link ResultFactory} to * generate the result * @throws RemoteException * if the {@link Response}'s {@link StatusCode} indicates * StatusCode.FAILURE. */ public static <T> Response<T> fromListCheckedFailure(List<Object> response, ResultFactory<T> resultFactory) throws RemoteException { StatusCode statusCode; String message; try { statusCode = StatusCode.fromInt((Integer) response.get(0)); message = (String) response.get(1); if (statusCode == StatusCode.FAILURE) { throw new RemoteException(statusCode, message); } } catch (ClassCastException e) { throw new RosRuntimeException( "Remote side did not return correct type (status code/message).", e); } try { return new Response<T>(statusCode, message, resultFactory.newFromValue(response.get(2))); } catch (ClassCastException e) { throw new RosRuntimeException("Remote side did not return correct value type.", e); } } /** * Creates a {@link Response} from the {@link List} of {@link Object}s * returned from an XML-RPC call. Throws {@link RemoteException} if the * {@link StatusCode} is not a success. * * @param <T> * @param response * the {@link List} of {@link Object}s returned from the XML-RPC call * @param resultFactory * a {@link ResultFactory} that creates a result from the third * {@link Object} in the {@link Response} * @return a {@link Response} using the specified {@link ResultFactory} to * generate the result * @throws RemoteException * if the {@link Response}'s {@link StatusCode} does not indicate * success */ public static <T> Response<T> fromListChecked(List<Object> response, ResultFactory<T> resultFactory) throws RemoteException { StatusCode statusCode; String message; try { statusCode = StatusCode.fromInt((Integer) response.get(0)); message = (String) response.get(1); if (statusCode != StatusCode.SUCCESS) { throw new RemoteException(statusCode, message); } } catch (ClassCastException e) { throw new RosRuntimeException( "Remote side did not return correct type (status code/message).", e); } try { return new Response<T>(statusCode, message, resultFactory.newFromValue(response.get(2))); } catch (ClassCastException e) { throw new RosRuntimeException("Remote side did not return correct value type.", e); } } public Response(int statusCode, String statusMessage, T value) { this(StatusCode.fromInt(statusCode), statusMessage, value); } public Response(StatusCode statusCode, String statusMessage, T value) { this.statusCode = statusCode; this.statusMessage = statusMessage; this.result = value; } public List<Object> toList() { return Lists.newArrayList(statusCode.toInt(), statusMessage, result == null ? "null" : result); } public StatusCode getStatusCode() { return statusCode; } public String getStatusMessage() { return statusMessage; } public T getResult() { return result; } @Override public String toString() { return "Response<" + statusCode + ", " + statusMessage + ", " + result + ">"; } public boolean isSuccess() { return statusCode == StatusCode.SUCCESS; } }