
net.jangaroo.extxml.json.JsonObject Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of ext-xml Show documentation
Show all versions of ext-xml Show documentation
Allows a declarative description of UI components
The newest version!
package net.jangaroo.extxml.json;
import net.jangaroo.extxml.ComponentSuiteRegistry;
import net.jangaroo.extxml.model.ComponentClass;
import net.jangaroo.utils.log.Log;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
public class JsonObject implements Json {
private Map properties = new LinkedHashMap();
private String typePropertyName;
public String getTypePropertyName() {
return typePropertyName;
}
public void setTypePropertyName(String typePropertyName) {
this.typePropertyName = typePropertyName;
}
public String getType() {
return (String)get(getTypePropertyName());
}
public void setType(String type) {
set(getTypePropertyName(), type);
}
public boolean isEmpty() {
return properties.isEmpty();
}
@Override
public String toString() {
return toString(0);
}
/**
* Make a prettyprinted JSON text of this JSONObject.
*
* Warning: This method assumes that the data structure is acyclical.
*
* @param indentFactor The number of spaces to add to each level of
* indentation.
* @return a printable, displayable, portable, transmittable
* representation of the object, beginning
* with {
(left brace) and ending
* with }
(right brace).
*/
public String toString(int indentFactor) {
return toString(indentFactor, 0);
}
/**
* Produce a string in double quotes with backslash sequences in all the
* right places. A backslash will be inserted within , allowing JSON
* text to be delivered in HTML. In JSON text, a string cannot contain a
* control character or an unescaped quote or backslash.
*
* @param string A String
* @return A String correctly formatted for insertion in a JSON text.
*/
public static String quote(String string) {
if (string == null || string.length() == 0) {
return "\"\"";
}
char b;
char c = 0;
int i;
int len = string.length();
StringBuilder sb = new StringBuilder(len + 4);
String t;
sb.append('"');
for (i = 0; i < len; i += 1) {
b = c;
c = string.charAt(i);
switch (c) {
case '\\':
case '"':
sb.append('\\');
sb.append(c);
break;
case '/':
if (b == '<') {
sb.append('\\');
}
sb.append(c);
break;
case '\b':
sb.append("\\b");
break;
case '\t':
sb.append("\\t");
break;
case '\n':
sb.append("\\n");
break;
case '\f':
sb.append("\\f");
break;
case '\r':
sb.append("\\r");
break;
default:
if (c < ' ' || (c >= '\u0080' && c < '\u00a0') ||
(c >= '\u2000' && c < '\u2100')) {
t = "000" + Integer.toHexString(c);
sb.append("\\u").append(t.substring(t.length() - 4));
} else {
sb.append(c);
}
}
}
sb.append('"');
return sb.toString();
}
/**
* Make a prettyprinted JSON text of an object value.
*
* Warning: This method assumes that the data structure is acyclic.
*
* @param key The key of the value.
* @param value The value to be serialized.
* @param indentFactor The number of spaces to add to each level of
* indentation.
* @param indent The indentation of the top level.
* @return a printable, displayable, transmittable
* representation of the object, beginning
* with {
(left brace) and ending
* with }
(right brace).
*/
static String valueToString(String key, Object value, int indentFactor, int indent) {
if (value == null) {
return "null";
}
if (value instanceof Number
|| value instanceof Boolean) {
return (value.toString());
} else if (value instanceof JsonObject) {
JsonObject jsonObject = (JsonObject)value;
return jsonObject.toString(indentFactor, indent);
} else if (value instanceof JsonArray) {
return ((JsonArray) value).toString(indentFactor, indent);
} else if ("xtype".equals(key) || "ptype".equals(key) || "type".equals(key)) {
String xtype = (String) value;
if ("type".equals(key) && xtype.endsWith("layout")) {
// by convention, layout "type"s have a "layout" postfix in EXML that has to be cut off again:
xtype = xtype.substring(0, xtype.length() - "layout".length());
}
ComponentClass compClazz = ComponentSuiteRegistry.getInstance().findComponentClassByXtype(xtype);
if (compClazz != null && !compClazz.getFullClassName().startsWith("ext.")) {
//Log.getLogHandler().info(String.format("Using compontent class '%s' for xtype '%s'", compClazz, value));
return (compClazz.getFullClassName())+ (".") + (key);
} else {
return ("\"") + (xtype) + ("\"");
}
} else if (((String) value).startsWith("{") && ((String) value).endsWith("}")) {
return (((String) value).substring(1, ((String) value).lastIndexOf("}")));
}
return quote(value.toString());
}
/**
* Make a prettyprinted JSON text of this JSONObject.
*
* Warning: This method assumes that the data structure is acyclical.
*
* @param indentFactor The number of spaces to add to each level of
* indentation.
* @param indent The indentation of the top level.
* @return a printable, displayable, transmittable
* representation of the object, beginning
* with {
(left brace) and ending
* with }
(right brace).
*/
public String toString(int indentFactor, int indent) {
Set keySet = this.properties.keySet();
// special handling for "atype":
ComponentClass actionClass = null;
Object atype = get("atype");
if (atype instanceof String) {
actionClass = ComponentSuiteRegistry.getInstance().findComponentClassByXtype((String)atype);
if (actionClass == null) {
Log.e("No Action found for atype '" + atype + "'.");
} else {
// "atype" property is not rendered, because it is replaced by "new ...Action({...})
keySet = new LinkedHashSet(keySet); // copy, keySet is not modifiable!
keySet.remove("atype");
}
}
StringBuilder sb = new StringBuilder("{");
int newindent = indent + indentFactor;
int n = keySet.size();
Iterator keys = keySet.iterator();
if (n == 1) {
writeKeyValue(keys.next(), indentFactor, indent, sb);
} else if (n > 1) {
while (keys.hasNext()) {
if (sb.length() > 1) {
sb.append(",");
}
newlineAndIndent(sb, newindent);
writeKeyValue(keys.next(), indentFactor, newindent, sb);
}
if (sb.length() > 1) {
newlineAndIndent(sb, indent);
}
}
sb.append('}');
return actionClass == null
? sb.toString()
: String.format("new %s(%s)", actionClass.getFullClassName(), sb.toString());
}
private void newlineAndIndent(StringBuilder sb, int indent) {
sb.append('\n');
for (int i = 0; i < indent; i++) {
sb.append(' ');
}
}
private void writeKeyValue(String key, int indentFactor, int indent, StringBuilder sb) {
sb.append(key);
sb.append(": ");
sb.append(valueToString(key, this.properties.get(key), indentFactor, indent));
}
public Object get(String property) {
return properties.get(property);
}
public void set(String property, Object value) {
this.properties.put(property, value);
}
public Object remove(String property) {
return this.properties.remove(property);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy