package com.gvaneyck.rtmp.encoding; import java.util.regex.Pattern; /** * A map that has a type, used to represent an object * * @author Gabriel Van Eyck */ public class TypedObject extends ObjectMap { private static final long serialVersionUID = 1244827787088018807L; private static Pattern linePattern = Pattern.compile("^", Pattern.MULTILINE); public String type; /** * Creates a typed object that is simply a map (null type) */ public TypedObject() { this.type = null; } /** * Initializes the type of the object, null type implies a dynamic class * (used for headers and some other things) * * @param type The type of the object */ public TypedObject(String type) { this.type = type; } /** * Creates a TypedObject from an ObjectMap * * @param data */ public TypedObject(ObjectMap data) { this.type = null; this.putAll(data); } /** * Creates a flex.messaging.io.ArrayCollection in the structure that the * encoder expects * * @param data The data for the ArrayCollection * @return */ public static TypedObject makeArrayCollection(Object[] data) { TypedObject ret = new TypedObject("flex.messaging.io.ArrayCollection"); ret.put("array", data); return ret; } /** * Convenience for going through object hierarchy * * @param key The key of the TypedObject * @return The TypedObject */ public TypedObject getTO(String key) { return (TypedObject)get(key); } /** * Convenience for retrieving object arrays * Also handles flex.messaging.io.ArrayCollection * * @param key The key of the object array * @return The object array */ public Object[] getArray(String key) { if (get(key) instanceof TypedObject && getTO(key).type.equals("flex.messaging.io.ArrayCollection")) return (Object[])getTO(key).get("array"); else return (Object[])get(key); } public String toString() { StringBuilder buff = new StringBuilder(); buff.append("{"); for (String key : keySet()) { buff.append(key); buff.append('='); if (key.equals("array")) { buff.append('['); for (Object o : getArray(key)) { buff.append(o.toString()); buff.append(", "); } buff.append(']'); } else if (get(key) instanceof Double) { buff.append(((Double)get(key)).longValue()); } else buff.append(get(key)); buff.append(", "); } buff.append("}"); return buff.toString(); } /** * Makes a pretty (indented) human readable form of this object * * @return A pretty string */ public String toPrettyString() { String[] keys = keySet().toArray(new String[0]); if (keys.length == 0) return "{ }\n"; StringBuilder buff = new StringBuilder(); buff.append("{\n"); for (int i = 0; i < keys.length; i++) { String key = keys[i]; if (key.equals("array")) buff.append(indent(arrayToString(getArray(key)))); else if (get(key) instanceof Object[]) buff.append(indent(arrayToString((Object[])get(key)))); else if (get(key) == null) { buff.append(" "); buff.append(key); buff.append("=null"); } else if (get(key) instanceof Double) { buff.append(" "); buff.append(key); buff.append('='); buff.append(((Double)get(key)).longValue()); } else if (get(key) instanceof TypedObject) buff.append(indent(key + '=' + ((TypedObject)get(key)).toPrettyString())); else buff.append(indent(key + '=' + get(key).toString())); if (i < keys.length - 1) buff.append(",\n"); } buff.append("\n}\n"); return buff.toString(); } /** * Turns an array into a pretty string * * @param array The array to transform * @return A pretty string */ private String arrayToString(Object[] array) { if (array.length == 0) return "[ ]\n"; StringBuilder buff = new StringBuilder(); buff.append("[\n"); for (int i = 0; i < array.length; i++) { if (array[i] == null) buff.append(" null"); else if (array[i] instanceof TypedObject) buff.append(indent(((TypedObject)array[i]).toPrettyString())); else buff.append(indent(array[i].toString())); if (i < array.length - 1) buff.append(",\n"); } buff.append("\n]\n"); return buff.toString(); } /** * Indents some text * * @param data The text to indent * @return Indented text */ private String indent(String data) { return linePattern.matcher(data.trim()).replaceAll(" "); } }