All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.endreman0.javajson.nodes.ObjectNode Maven / Gradle / Ivy

package io.github.endreman0.javajson.nodes;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * A JSON object node consists of a series of key-value pairs separated by commas, enclosed in curly brackets ({}).
 * The key to each pair must be a string enclosed in double quotes ({@code ""}), and the value can be any node. 
 * @author endreman0
 */
public class ObjectNode extends ParentNode implements Iterable, Map{
	private List fields = new LinkedList();
	/**
	 * Create an empty object node.
	 */
	public ObjectNode(){super();}
	/**
	 * Create an object node with the given key-value pairs as children.
	 * @param fields The string-node pairs to add as children
	 */
	public ObjectNode(Iterable fields){this(); putAll(fields);}
	public ObjectNode(Field... fields){this(); putAll(fields);}
	/**
	 * Assign the given node to the value of the given key.
	 * If another node was already assigned to the given key, it will be removed from this node. 
	 * @param key The key to assign to...
	 * @param value ...this node
	 * @return {@code this}, for chaining
	 */
	public ObjectNode put(String key, Node value){
		boolean isSet = false;
		for(Field field : fields){
			if(field.getKey().equals(key)){
				field.setValue(value);
				isSet = true;
				break;
			}
		}
		if(!isSet) fields.add(new Field(key, value));
		value.parent = this;
		return this;
	}
	/**
	 * Add the given field to this object.
	 * If the field's key is already assigned, the value will be replaced.
	 * @param field The field to add
	 * @return {@code this}, for chaining
	 */
	public ObjectNode put(Field field){return put(field.getKey(), field.getValue());}
	/**
	 * Add all of the given key-value pairs to this node's children.
	 * @param fields The string-node pairs to add
	 * @return {@code this}, for chaining
	 */
	public ObjectNode putAll(Field[] fields){
		for(Field field : fields) put(field.getKey(), field.getValue());
		return this;
	}
	/**
	 * Add all of the given key-value pairs to this node's children.
	 * @param fields The string-node pairs to add
	 * @return {@code this}, for chaining
	 */
	public ObjectNode putAll(Iterable fields){
		for(Field field : fields) put(field.getKey(), field.getValue());
		return this;
	}
	/**
	 * Get the node assigned to the provided key.
	 * @param key The key to search for
	 * @return The node assigned to that key, or {@code null} if no node was found
	 */
	public Node get(String key){
		for(Field field : fields)
			if(field.getKey().equals(key)) return field.getValue();
		return null;
	}
	/**
	 * Get the node assigned to the provided key, if it is an array node.
	 * This method gets the node assigned to the provided key and tests if it is an array node.
	 * If it is, the node is returned. If not, {@code null} is returned.
	 * @param key The key to search for
	 * @return The node assigned to the specified key, if it is an array node; {@code null} otherwise
	 */
	public ArrayNode getArray(String key){
		Node node = get(key);
		if(node instanceof ArrayNode) return (ArrayNode)node; else return null;
	}
	/**
	 * Get the node assigned to the provided key, if it is a boolean node.
	 * This method gets the node assigned to the provided key and tests if it is a boolean node.
	 * If it is, the node is returned. If not, {@code null} is returned.
	 * @param key The key to search for
	 * @return The node assigned to the specified key, if it is a boolean node; {@code null} otherwise
	 */
	public BooleanNode getBoolean(String key){
		Node node = get(key);
		if(node instanceof BooleanNode) return (BooleanNode)node; else return null;
	}
	/**
	 * Get the node assigned to the provided key, if it is a number node.
	 * This method gets the node assigned to the provided key and tests if it is a number node.
	 * If it is, the node is returned. If not, {@code null} is returned.
	 * @param key The key to search for
	 * @return The node assigned to the specified key, if it is a number node; {@code null} otherwise
	 */
	public NumberNode getNumber(String key){
		Node node = get(key);
		if(node instanceof NumberNode) return (NumberNode)node; else return null;
	}
	/**
	 * Get the node assigned to the provided key, if it is an object node.
	 * This method gets the node assigned to the provided key and tests if it is an object node.
	 * If it is, the node is returned. If not, {@code null} is returned.
	 * @param key The key to search for
	 * @return The node assigned to the specified key, if it is an object node; {@code null} otherwise
	 */
	public ObjectNode getObject(String key){
		Node node = get(key);
		if(node instanceof ObjectNode) return (ObjectNode)node; else return null;
	}
	/**
	 * Get the node assigned to the provided key, if it is a string node.
	 * This method gets the node assigned to the provided key and tests if it is a string node.
	 * If it is, the node is returned. If not, {@code null} is returned.
	 * @param key The key to search for
	 * @return The node assigned to the specified key, if it is a string node; {@code null} otherwise
	 */
	public StringNode getString(String key){
		Node node = get(key);
		if(node instanceof StringNode) return (StringNode)node; else return null;
	}
	/**
	 * Get the key that the given node is assigned to.
	 * If the node is not assigned to any key, {@code null} is returned.
	 * @param value The node to search for
	 * @return The key of the specified node, or {@code null} if not found
	 */
	public String keyOf(Node value){
		for(Field field : fields)
			if(field.getValue().equals(value)) return field.getKey();
		return null;
	}
	@Override public int size(){return fields.size();}
	/**
	 * Get whether any node is assigned to the given key.
	 * @param key The key to check for
	 * @return {@code true} if the key has an assigned value, {@code false} otherwise
	 */
	public boolean contains(String key){return get(key) != null;}
	@Override public boolean contains(Node value){return keyOf(value) != null;}
	/**
	 * Remove the key-value pair with the given key.
	 * @param key The key to remove
	 * @return The removed pair's value, or {@code null} if the key was not found
	 */
	public Node remove(String key){
		for(Field field : fields){
			if(field.getKey().equals(key)){
				fields.remove(field);
				return field.getValue();
			}
		}
		return null;
	}
	@Override
	public boolean remove(Node value){
		for(Field field : fields){
			if(field.getValue().equals(value)){
				fields.remove(field);
				return true;
			}
		}
		return false;
	}
	@Override
	public void removeAll(){
		for(Field field : fields) field.getValue().parent = null;
		fields.clear();
	}
	@Override public Iterator iterator(){return fields.iterator();}
	@Override 
	public boolean equals(Object obj){
		if(!(obj instanceof ObjectNode)) return false;
		ObjectNode node = (ObjectNode)obj;
		if(size() != node.size()) return false;
		for(Iterator i1=iterator(), i2=node.iterator(); i1.hasNext() && i2.hasNext();)//For-each over both nodes
			if(!i1.next().equals(i2.next())) return false;
		return true;
	}
	@Override
	public int hashCode(){
		int hashCode = 0;
		boolean add = true;
		for(Map.Entry entry : this)
			if(add = !add) hashCode += entry.hashCode(); else hashCode -= entry.hashCode();//Add or subtract, and toggle for the next iteration
		return hashCode;
	}
	@Override
	public String json(){
		return "{\r\n " + innerJSON().replace("\n", "\n ") + "\r\n}";
	}
	@Override
	public String innerJSON(){
		StringBuilder sb = new StringBuilder();
		for(Iterator i=iterator(); i.hasNext();){
			sb.append(i.next());
			if(i.hasNext()) sb.append(",\r\n");//If this isn't the last entry, add a comma and a new line
		}
		return sb.toString();
	}
	@Override public boolean isEmpty(){return fields.isEmpty();}
	@Override public boolean containsKey(Object key){return get(key) != null;}
	@Override public boolean containsValue(Object value){return value instanceof Node ? keyOf((Node)value) != null : false;}
	@Override public Node get(Object key){return key instanceof String ? get((String)key) : null;}
	@Override public Node remove(Object key){return key instanceof String ? remove((String)key) : null;}
	@Override public void putAll(Map m){for(Map.Entry entry : m.entrySet()) put(entry.getKey(), entry.getValue());}
	@Override public void clear(){removeAll();}
	@Override
	public Set keySet(){
		Set set = new HashSet();
		for(Field field : fields) set.add(field.getKey());
		return set;
	}
	@Override
	public Collection values(){
		Collection c = new HashSet();
		for(Field field : fields) c.add(field.getValue());
		return c;
	}
	@Override
	public Set> entrySet(){
		Set> set = new HashSet>();
		for(Field field : fields) set.add(field);
		return set;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy