/* * Copyright (C) 2012 Facebook, 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 com.facebook.data.types; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.List; import java.util.Map; /** * utility methods for operating on Datums */ public class DatumUtils { /** * recursively converts the mapDatum into a valid JSONObject * * @param mapDatum * @return JSONObject */ public static JSONObject buildJSON(MapDatum mapDatum) { JSONObject jsonObject = new JSONObject(); Map<Datum, Datum> map = mapDatum.getMap(); try { for (Map.Entry<Datum, Datum> entry : map.entrySet()) { String key = entry.getKey().asString(); DatumType valueDatumType = entry.getValue().getType(); if (valueDatumType == DatumType.LIST) { jsonObject.put(key, buildJSON((ListDatum) entry.getValue())); } else if (valueDatumType == DatumType.MAP) { jsonObject.put(key, buildJSON((MapDatum) entry.getValue())); } else { jsonObject.put(key, entry.getValue().asRaw()); } } return jsonObject; } catch (JSONException e) { throw new RuntimeException("error converting json object to string", e); } } /** * recursively converts contained Datums into a valid JSONArray. * * @param listDatum * @return JSONArray */ public static JSONArray buildJSON(ListDatum listDatum) { JSONArray jsonArray = new JSONArray(); List<Datum> datumList = listDatum.asList(); try { int i = 0; for (Datum datum : datumList) { DatumType datumType = datum.getType(); if (datumType == DatumType.LIST) { jsonArray.put(i, buildJSON((ListDatum) datum)); } else if (datumType == DatumType.MAP) { jsonArray.put(i, buildJSON((MapDatum) datum)); } else { jsonArray.put(i, datum.asRaw()); } i++; } return jsonArray; } catch (JSONException e) { throw new RuntimeException( "some element did not conform to JSON format: " + datumList, e ); } } /** * {impressionTimestamp, adId} * <p/> * and creates JSON with * <pre> * * { * keyNames[0] : rawTuple[0], * keyNames[1] : rawTuple[1], * ... * keyNames[n] : rawTuple[n], * } * </pre> * * @param rawTuple - impressionTimestamp, adId * @return */ public static MapDatum toMapDatum(LongDatum[] rawTuple, StringDatum[] keyNames) { assert rawTuple.length == keyNames.length; Map<Datum, Datum> datumMap = new HashMap<Datum, Datum>(rawTuple.length); for (int i = 0; i < rawTuple.length; i++) { datumMap.put(keyNames[i], rawTuple[i]); } return new MapDatum(datumMap); } /** * @param value byte, short, int, long to translate big-endian to an array * @param numBytes 1 = byte, 2 short, 4 = int, 8 = long. or try 5 for the heck of it. * @return */ public static byte[] toBytes(long value, int numBytes) { byte[] bytes = new byte[numBytes]; for (int i = numBytes-1; i > 0; i--) { bytes[i] = (byte) value; value >>>= 8; } bytes[0] = (byte) value; return bytes; } }