/** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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.apache.blur.command; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; public class BlurObjectSerDe { private static final String SET = "set"; private static final String VALUE = "v"; private static final String KEY = "k"; private static final String MAP = "map"; private static final String LIST = "list"; private static final String TYPE = "serdetype"; // TODO make real unit test // public static <E> void main(String[] args) { // BlurObjectSerDe serde = new BlurObjectSerDe(); // Map<String, Long> m = new HashMap<String, Long>(); // m.put("sub", 100L); // Map<String, Object> map = new HashMap<String, Object>(); // map.put("a", "a"); // map.put("b", Arrays.asList("a", "b", "c")); // map.put("c", m); // // Set<Integer> set = new HashSet<Integer>(); // set.add(3); // set.add(5); // map.put("d", set); // // BlurObject bo1 = serde.serialize(map); // System.out.println(bo1.toString(1)); // // Map<String, ? extends Object> map2 = serde.deserialize(bo1); // System.out.println(map2); // // Set<?> set2 = (Set<?>) map.get("d"); // System.out.println(set2); // } public BlurObject serialize(Map<String, ? extends Object> args) { BlurObject result = new BlurObject(); for (Entry<String, ? extends Object> e : args.entrySet()) { result.put(e.getKey(), toSupportedThriftObject(e.getValue())); } return result; } public Object toSupportedThriftObject(Object o) { if (BlurObject.supportedType(o)) { return o; } else { return convertToSupportedType(o); } } @SuppressWarnings("unchecked") private BlurObject convertToSupportedType(Object o) { if (o instanceof Set) { return toBlurObject((Set<?>) o); } else if (o instanceof Map) { return toBlurObject((Map<Object, Object>) o); } else if (o instanceof List) { return toBlurObject((List<Object>) o); } else { return toBlurObjectFromUnknown(o); } } private BlurObject toBlurObject(Map<Object, Object> o) { BlurObject blurObject = new BlurObject(); blurObject.put(TYPE, MAP); BlurArray blurArray = new BlurArray(); Set<Entry<Object, Object>> entrySet = o.entrySet(); for (Entry<Object, Object> e : entrySet) { BlurObject entry = new BlurObject(); entry.put(KEY, toSupportedThriftObject(e.getKey())); entry.put(VALUE, toSupportedThriftObject(e.getValue())); blurArray.put(entry); } blurObject.put(MAP, blurArray); return blurObject; } private BlurObject toBlurObject(List<Object> o) { BlurObject blurObject = new BlurObject(); blurObject.put(TYPE, LIST); BlurArray blurArray = new BlurArray(); for (Object t : o) { blurArray.put(toSupportedThriftObject(t)); } blurObject.put(LIST, blurArray); return blurObject; } private BlurObject toBlurObject(Set<?> o) { BlurObject blurObject = new BlurObject(); blurObject.put(TYPE, SET); BlurArray blurArray = new BlurArray(); for (Object t : o) { blurArray.put(toSupportedThriftObject(t)); } blurObject.put(SET, blurArray); return blurObject; } private BlurObject toBlurObjectFromUnknown(Object o) { throw new RuntimeException("Not implemented."); } public Map<String, ? extends Object> deserialize(BlurObject blurObject) { Map<String, Object> map = new HashMap<String, Object>(); Iterator<String> keys = blurObject.keys(); while (keys.hasNext()) { String key = keys.next(); map.put(key, fromSupportedThriftObject(blurObject.get(key))); } return map; } public Object fromSupportedThriftObject(Object object) { if (object instanceof BlurObject) { BlurObject bo = (BlurObject) object; if (isCustomObject(bo)) { return convertFromSupportedType(bo); } } return object; } private Object convertFromSupportedType(BlurObject blurObject) { String type = blurObject.getString(TYPE); if (type.equals(LIST)) { return toList(blurObject); } else if (type.equals(MAP)) { return toMap(blurObject); } else if (type.equals(SET)) { return toSet(blurObject); } else { return toUnknownObject(blurObject); } } private Object toSet(BlurObject blurObject) { BlurArray blurArray = blurObject.getBlurArray(SET); Set<Object> set = new HashSet<Object>(); int length = blurArray.length(); for (int i = 0; i < length; i++) { set.add(fromSupportedThriftObject(blurArray.get(i))); } return set; } private Object toUnknownObject(BlurObject blurObject) { throw new RuntimeException("Not implemented."); } private Map<? extends Object, ? extends Object> toMap(BlurObject blurObject) { Map<Object, Object> result = new HashMap<Object, Object>(); BlurArray blurArray = blurObject.getBlurArray(MAP); int length = blurArray.length(); for (int i = 0; i < length; i++) { BlurObject bo = blurArray.getBlurObject(i); Object key = bo.get(KEY); Object value = bo.get(VALUE); result.put(fromSupportedThriftObject(key), fromSupportedThriftObject(value)); } return result; } private List<? extends Object> toList(BlurObject blurObject) { BlurArray blurArray = blurObject.getBlurArray(LIST); List<Object> list = new ArrayList<Object>(); int length = blurArray.length(); for (int i = 0; i < length; i++) { list.add(fromSupportedThriftObject(blurArray.get(i))); } return list; } private boolean isCustomObject(BlurObject bo) { if (bo.hasKey(TYPE)) { return true; } return false; } }