weka.core.json.JSONNode Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of weka-stable Show documentation
Show all versions of weka-stable Show documentation
The Waikato Environment for Knowledge Analysis (WEKA), a machine
learning workbench. This is the stable version. Apart from bugfixes, this version
does not receive any other updates.
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* JSONNode.java
* Copyright (C) 2009-2012 University of Waikato, Hamilton, New Zealand
*/
package weka.core.json;
import java_cup.runtime.DefaultSymbolFactory;
import java_cup.runtime.SymbolFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.BorderLayout;
import java.io.Reader;
/**
* Container class for storing a
* JSON data structure.
*
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 12111 $
*/
public class JSONNode extends DefaultMutableTreeNode {
/** for serialization. */
private static final long serialVersionUID = -3047440914507883491L;
/**
* The type of a node.
*
* @author FracPete (fracpete at waikato dot ac dot nz)
* @version $Revision: 12111 $
*/
public static enum NodeType {
/** a primitive. */
PRIMITIVE, /** an object with nested key-value pairs. */
OBJECT, /** an array. */
ARRAY
}
/** the name of the node. */
protected String m_Name;
/** the value of the node. */
protected Object m_Value;
/** the type of the node. */
protected NodeType m_NodeType;
/**
* Initializes the root container.
*/
public JSONNode() {
this(null, NodeType.OBJECT);
}
/**
* Initializes the primitive container.
*
* @param name the name
* @param value the primitive value
*/
public JSONNode(String name, Boolean value) {
this(name, value, NodeType.PRIMITIVE);
}
/**
* Initializes the primitive container.
*
* @param name the name
* @param value the primitive value
*/
public JSONNode(String name, Integer value) {
this(name, value, NodeType.PRIMITIVE);
}
/**
* Initializes the primitive container.
*
* @param name the name
* @param value the primitive value
*/
public JSONNode(String name, Double value) {
this(name, value, NodeType.PRIMITIVE);
}
/**
* Initializes the primitive container.
*
* @param name the name
* @param value the primitive value
*/
public JSONNode(String name, String value) {
this(name, value, NodeType.PRIMITIVE);
}
/**
* Initializes the object container with null value.
*
* @param name the name
* @param type the node type
*/
protected JSONNode(String name, NodeType type) {
this(name, null, type);
}
/**
* Initializes the container.
*
* @param name the name
* @param value the primitive value
* @param type the type of the node, null for primitives
*/
protected JSONNode(String name, Object value, NodeType type) {
super();
m_Name = name;
m_Value = value;
m_NodeType = type;
}
/**
* Checks whether the node is anonymous.
*
* @return true if no name available
*/
public boolean isAnonymous() {
return (m_Name == null);
}
/**
* Returns the name of the node.
*
* @return the name, null for anonymous nodes
*/
public String getName() {
return m_Name;
}
/**
* Returns the stored value.
*
* @return the stored value, can be null
*/
public Object getValue() {
return getValue(null);
}
/**
* Returns the stored value.
*
* @param defValue the default value, if value is null
* @return the stored value, can be null
*/
public Object getValue(Object defValue) {
if (m_Value == null) {
return defValue;
} else {
if (m_Value instanceof String) {
return unescape(m_Value.toString());
} else {
return m_Value;
}
}
}
/**
* Returns whether the node stores a primitive value or a an array/object.
*
* @return true if a primitive, false in case of an array/object
*/
public boolean isPrimitive() {
return (m_NodeType == NodeType.PRIMITIVE);
}
/**
* Returns wether the node is an array.
*
* @return true if the node is array container
*/
public boolean isArray() {
return (m_NodeType == NodeType.ARRAY);
}
/**
* Returns wether the node is an object.
*
* @return true if the node is object container
*/
public boolean isObject() {
return (m_NodeType == NodeType.OBJECT);
}
/**
* Returns the type of the container.
*
* @return the type
*/
public NodeType getNodeType() {
return m_NodeType;
}
/**
* Adds a "null" child to the object.
*
* @param name the name of the null value
* @return the new node, or null if none added
*/
public JSONNode addNull(String name) {
return add(name, null, NodeType.PRIMITIVE);
}
/**
* Adds a key-value child to the object.
*
* @param name the name of the pair
* @param value the value
* @return the new node, or null if none added
*/
public JSONNode addPrimitive(String name, Boolean value) {
return add(name, value, NodeType.PRIMITIVE);
}
/**
* Adds a key-value child to the object.
*
* @param name the name of the pair
* @param value the value
* @return the new node, or null if none added
*/
public JSONNode addPrimitive(String name, Integer value) {
return add(name, value, NodeType.PRIMITIVE);
}
/**
* Adds a key-value child to the object.
*
* @param name the name of the pair
* @param value the value
* @return the new node, or null if none added
*/
public JSONNode addPrimitive(String name, Double value) {
return add(name, value, NodeType.PRIMITIVE);
}
/**
* Adds a key-value child to the object.
*
* @param name the name of the pair
* @param value the value
* @return the new node, or null if none added
*/
public JSONNode addPrimitive(String name, String value) {
return add(name, value, NodeType.PRIMITIVE);
}
/**
* Adds an array child to the object.
*
* @param name the name of the pair
* @return the new node, or null if none added
*/
public JSONNode addArray(String name) {
return add(name, null, NodeType.ARRAY);
}
/**
* Adds a null array element child to the array.
*
* @return the new node, or null if none added
*/
public JSONNode addNullArrayElement() {
return add(null, null, NodeType.PRIMITIVE);
}
/**
* Add a key-value object child into the array
*
* @return the newly added node
*/
public JSONNode addObjectArrayElement() {
return add(null, null, NodeType.OBJECT);
}
/**
* Adds an array element child to the array.
*
* @param value the value of the element array
* @return the new node, or null if none added
*/
public JSONNode addArrayElement(Object value) {
NodeType type;
if (getNodeType() != NodeType.ARRAY) {
return null;
}
type = null;
if (value != null) {
if (value instanceof Boolean) {
type = NodeType.PRIMITIVE;
} else if (value instanceof Integer) {
type = NodeType.PRIMITIVE;
} else if (value instanceof Double) {
type = NodeType.PRIMITIVE;
} else if (value instanceof String) {
type = NodeType.PRIMITIVE;
} else if (value.getClass().isArray()) {
type = NodeType.ARRAY;
} else {
type = NodeType.OBJECT;
}
}
return add(null, value, type);
}
/**
* Adds an object child to the object.
*
* @param name the name of the pair
* @return the new node, or null if none added
*/
public JSONNode addObject(String name) {
return add(name, null, NodeType.OBJECT);
}
/**
* Adds a key-value child to the object.
*
* @param name the name of the pair
* @param value the value
* @param type the node type, null for primitives
* @return the new node, or null if none added
*/
protected JSONNode add(String name, Object value, NodeType type) {
JSONNode child;
if (isPrimitive()) {
return null;
}
child = new JSONNode(name, value, type);
add(child);
return child;
}
/**
* Checks whether the node has a child with the given name.
*
* @param name the name of the child
* @return true if child with that name is available
*/
public boolean hasChild(String name) {
return (getChild(name) != null);
}
/**
* Returns the child with the given name.
*
* @param name the name of the child
* @return the child if available, null otherwise
*/
public JSONNode getChild(String name) {
JSONNode result;
JSONNode node;
int i;
result = null;
for (i = 0; i < getChildCount(); i++) {
node = (JSONNode) getChildAt(i);
if (!node.isAnonymous() && node.getName().equals(name)) {
result = node;
break;
}
}
return result;
}
/**
* Generates the indentation string.
*
* @param level the level
* @return the indentation string (tabs)
*/
protected String getIndentation(int level) {
StringBuffer result;
int i;
result = new StringBuffer();
for (i = 0; i < level; i++) {
result.append("\t");
}
return result.toString();
}
/**
* Escapes ", \, /, \b, \f, \n, \r, \t in strings.
*
* @param o the object to process (only strings get processed)
* @return the processed object
*/
protected Object escape(Object o) {
if (o instanceof String) {
return escape((String) o);
} else {
return o;
}
}
/**
* Escapes ", /, \b, \f, \n, \r, \t.
*
* @param s the string to process
* @return the processed
*/
protected String escape(String s) {
StringBuffer result;
int i;
char c;
// take care of already escaped characters first (like
// \n in string literals
// kind of ugly - probably a better way of handling this
// somehow.
s = s.replace("\\n", "@@-@@n").replace("\\r", "@@-@@r")
.replace("\\t", "@@-@@t").replace("\\b", "@@-@@b")
.replace("\\f", "@@-@@f");
if ((s.indexOf('\"') > -1) || (s.indexOf('\\') > -1)
|| (s.indexOf('\b') > -1) || (s.indexOf('\f') > -1)
|| (s.indexOf('\n') > -1) || (s.indexOf('\r') > -1)
|| (s.indexOf('\t') > -1)) {
result = new StringBuffer();
for (i = 0; i < s.length(); i++) {
c = s.charAt(i);
if (c == '\"') {
result.append("\\\"");
} else if (c == '\\') {
result.append("\\\\");
} else if (c == '\b') {
result.append("\\b");
} else if (c == '\f') {
result.append("\\f");
} else if (c == '\n') {
result.append("\\n");
} else if (c == '\r') {
result.append("\\r");
} else if (c == '\t') {
result.append("\\t");
} else {
result.append(c);
}
}
} else {
result = new StringBuffer(s);
}
return result.toString();
}
/**
* Un-escapes ", /, \b, \f, \n, \r, \t.
*
* @param s the string to process
* @return the processed string
*/
protected String unescape(String s) {
StringBuilder newStringBuffer;
int index;
// replace each of the following characters with the backquoted version
String charsFind[] = { "\\\\", "\\'", "\\t", "\\n", "\\r", "\\b", "\\f",
"\\\"", "\\%", "\\u001E" };
char charsReplace[] =
{ '\\', '\'', '\t', '\n', '\r', '\b', '\f', '"', '%', '\u001E' };
int pos[] = new int[charsFind.length];
int curPos;
String str = new String(s);
newStringBuffer = new StringBuilder();
while (str.length() > 0) {
// get positions and closest character to replace
curPos = str.length();
index = -1;
for (int i = 0; i < pos.length; i++) {
pos[i] = str.indexOf(charsFind[i]);
if ((pos[i] > -1) && (pos[i] < curPos)) {
index = i;
curPos = pos[i];
}
}
// replace character if found, otherwise finished
if (index == -1) {
newStringBuffer.append(str);
str = "";
} else {
newStringBuffer.append(str.substring(0, pos[index]));
newStringBuffer.append(charsReplace[index]);
str = str.substring(pos[index] + charsFind[index].length());
}
}
return newStringBuffer.toString().replace("@@-@@", "\\");
}
/**
* Dumps the node structure into JSON format.
*
* @param buffer the buffer to add the data to
*/
public void toString(StringBuffer buffer) {
int level;
boolean isLast;
String indent;
int i;
level = getLevel();
isLast = (getNextSibling() == null);
indent = getIndentation(level);
buffer.append(indent);
if (m_Name != null) {
buffer.append("\"");
buffer.append(escape(m_Name));
buffer.append("\" : ");
}
if (isObject()) {
buffer.append("{\n");
for (i = 0; i < getChildCount(); i++) {
((JSONNode) getChildAt(i)).toString(buffer);
}
buffer.append(indent);
buffer.append("}");
} else if (isArray()) {
buffer.append("[\n");
for (i = 0; i < getChildCount(); i++) {
((JSONNode) getChildAt(i)).toString(buffer);
}
buffer.append(indent);
buffer.append("]");
} else {
if (m_Value == null) {
buffer.append("null");
} else if (m_Value instanceof String) {
buffer.append("\"");
buffer.append(escape((String) m_Value));
buffer.append("\"");
} else {
buffer.append(m_Value.toString());
}
}
if (!isLast) {
buffer.append(",");
}
buffer.append("\n");
}
/**
* Returns a string representation of the node.
*
* @return the string representation
*/
@Override
public String toString() {
String result;
result = null;
if (isObject()) {
if (isRoot()) {
result = "JSON";
} else if (m_Name == null) {
result = "