/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.util.rest; import java.io.ByteArrayInputStream; import java.util.List; import java.util.Map.Entry; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.UriBuilder; import javax.ws.rs.core.UriInfo; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.StringUtils; import org.fudgemsg.FudgeContext; import org.fudgemsg.FudgeField; import org.fudgemsg.FudgeMsg; import org.fudgemsg.MutableFudgeMsg; import org.fudgemsg.mapping.FudgeDeserializer; import com.opengamma.util.fudgemsg.OpenGammaFudgeContext; /** * Utility methods to simplify RESTful work. * <p> * This is a thread-safe static utility class. */ public final class RestUtils { /** * text/csv */ public static final String TEXT_CSV = "text/csv"; /** * text/csv type */ public static final MediaType TEXT_CSV_TYPE = new MediaType("text", "csv"); /** * Restricted constructor. */ private RestUtils() { } //------------------------------------------------------------------------- /** * Encodes an object into base-64 suitable for a URI. * <p> * The conversion uses Fudge, thus the object must be convertible to/from Fudge. * * @param object the object to encode, not null * @return the encoded version of the object, not null */ public static String encodeBase64(final Object object) { FudgeContext context = OpenGammaFudgeContext.getInstance(); FudgeMsg msg = context.toFudgeMsg(object).getMessage(); byte[] byteArray = context.toByteArray(msg); return Base64.encodeBase64URLSafeString(byteArray); } //------------------------------------------------------------------------- /** * Decodes an object from base-64 such as when passed in the URI. * <p> * The conversion uses Fudge, thus the object must be convertible to/from Fudge. * * @param <T> the bean type * @param type the bean type to build, not null * @param msgBase64 the base-64 Fudge message, not null * @return the bean, not null */ public static <T> T decodeBase64(final Class<T> type, final String msgBase64) { if (msgBase64 == null) { try { return type.newInstance(); } catch (InstantiationException ex) { throw new RuntimeException(ex); } catch (IllegalAccessException ex) { throw new RuntimeException(ex); } } byte[] msg = Base64.decodeBase64(msgBase64); FudgeContext context = OpenGammaFudgeContext.getInstance(); FudgeMsg message = context.createMessageReader(new ByteArrayInputStream(msg)).nextMessage(); if (message == null) { return null; } FudgeDeserializer deser = new FudgeDeserializer(context); return deser.fudgeMsgToObject(type, message); } //------------------------------------------------------------------------- /** * Encode an object to query parameters. * <p> * The conversion uses Fudge, thus the object must be convertible to/from Fudge. * * @param bld the URI builder, not null * @param object the object to encode, not null */ public static void encodeQueryParams(UriBuilder bld, Object object) { FudgeContext context = OpenGammaFudgeContext.getInstance(); FudgeMsg msg = context.toFudgeMsg(object).getMessage(); encode(bld, msg, ""); } private static void encode(UriBuilder bld, FudgeMsg msg, String keyPrefix) { for (FudgeField field : msg) { if (field.getName() != null) { String name = keyPrefix + field.getName(); Object value = field.getValue(); if (value instanceof FudgeMsg) { FudgeMsg subMsg = (FudgeMsg) value; encode(bld, subMsg, name + "."); } else { bld.queryParam(name, value.toString()); } } } } //------------------------------------------------------------------------- /** * Decodes query parameters to a bean. * <p> * The conversion uses Fudge, thus the object must be convertible to/from Fudge. * * @param <T> the bean type * @param uriInfo the uri information, not null * @param type the bean type to build, not null * @return the bean, not null */ public static <T> T decodeQueryParams(UriInfo uriInfo, Class<T> type) { FudgeContext context = OpenGammaFudgeContext.getInstance(); MutableFudgeMsg msg = context.newMessage(); for (Entry<String, List<String>> entry : uriInfo.getQueryParameters().entrySet()) { String key = entry.getKey(); List<String> values = entry.getValue(); for (String value : values) { decode(msg, key, value); } } FudgeDeserializer deser = new FudgeDeserializer(context); return deser.fudgeMsgToObject(type, msg); } private static void decode(MutableFudgeMsg msg, String key, String value) { if (key.contains(".")) { String key1 = StringUtils.substringBefore(key, "."); String key2 = StringUtils.substringAfter(key, "."); MutableFudgeMsg subMsg = msg.ensureSubMessage(key1, null); decode(subMsg, key2, value); } else { msg.add(key, value); } } }