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

com.google.gwt.json.client.JSONObject Maven / Gradle / Ivy

Go to download

A mocked implementation for GWT-2.5.1 that can run in the JVM to allow integration testing

The newest version!
/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed 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 com.google.gwt.json.client;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.JsonUtils;

/**
 * Represents a JSON object. A JSON object consists of a set of properties.
 */
public class JSONObject extends JSONValue {
	
	private Map properties = Maps.newHashMap();
	
	/**
	 * Called from {@link #getUnwrapper()}.
	 */
	private static JavaScriptObject unwrap(JSONObject value) {
		return value.jsObject;
	}
	
	private final JavaScriptObject jsObject;
	
	public JSONObject() {
		this(JavaScriptObject.createObject());
	}
	
	/**
	 * Creates a new JSONObject from the supplied JavaScript value.
	 */
	public JSONObject(JavaScriptObject jsValue) {
		jsObject = jsValue;
	}
	
	/**
	 * Tests whether or not this JSONObject contains the specified property.
	 * 
	 * @param key
	 *           the property to search for
	 * @return true if the JSONObject contains the specified property
	 */
	public native boolean containsKey(String key) /*-{
																	return key in [email protected]::jsObject;
																	}-*/;
	
	/**
	 * Returns true if other is a {@link JSONObject} wrapping the same underlying object.
	 */
	@Override
	public boolean equals(Object other) {
		if (!(other instanceof JSONObject)) {
			return false;
		}
		return jsObject.equals(((JSONObject) other).jsObject);
	}
	
	/**
	 * Gets the JSONValue associated with the specified property.
	 * 
	 * @param key
	 *           the property to access
	 * @return the value of the specified property, or null if the
	 *         property does not exist
	 * @throws NullPointerException
	 *            if key is null
	 */
	public JSONValue get(String key) {
		if (key == null) {
			throw new NullPointerException();
		}
		return get0(key);
	}
	
	/**
	 * Returns the underlying JavaScript object that this object wraps.
	 */
	public JavaScriptObject getJavaScriptObject() {
		return jsObject;
	}
	
	@Override
	public int hashCode() {
		return jsObject.hashCode();
	}
	
	/**
	 * Returns this, as this is a JSONObject.
	 */
	@Override
	public JSONObject isObject() {
		return this;
	}
	
	/**
	 * Returns the set of properties defined on this JSONObject. The returned set
	 * is immutable.
	 */
	public Set keySet() {
		return ImmutableSet.copyOf(properties.keySet());
		// final String[] keys = computeKeys();
		// return new AbstractSet() {
		// @Override
		// public boolean contains(Object o) {
		// return (o instanceof String) && containsKey((String) o);
		// }
		//
		// @Override
		// public Iterator iterator() {
		// return Arrays.asList(keys).iterator();
		// }
		//
		// @Override
		// public int size() {
		// return keys.length;
		// }
		// };
	}
	
	/**
	 * Assign the specified property to the specified value in this JSONObject. If
	 * the property already has an associated value, it is overwritten.
	 * 
	 * @param key
	 *           the property to assign
	 * @param jsonValue
	 *           the value to assign
	 * @return the previous value of the property, or null if the
	 *         property did not exist
	 * @throws NullPointerException
	 *            if key is null
	 */
	public JSONValue put(String key, JSONValue jsonValue) {
		if (key == null) {
			throw new NullPointerException();
		}
		JSONValue previous = get(key);
		put0(key, jsonValue);
		return previous;
	}
	
	/**
	 * Determines the number of properties on this object.
	 */
	public int size() {
		// Must always recheck due to foreign changes. :(
		return computeSize();
	}
	
	/**
	 * Converts a JSONObject into a JSON representation that can be used to
	 * communicate with a JSON service.
	 * 
	 * @return a JSON string representation of this JSONObject instance
	 */
	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("{");
		boolean first = true;
		String[] keys = computeKeys();
		for (String key : keys) {
			if (first) {
				first = false;
			} else {
				sb.append(", ");
			}
			sb.append(JsonUtils.escapeValue(key));
			sb.append(":");
			sb.append(get(key));
		}
		sb.append("}");
		return sb.toString();
	}
	
	@Override
	native JavaScriptObject getUnwrapper() /*-{
														return @com.google.gwt.json.client.JSONObject::unwrap(Lcom/google/gwt/json/client/JSONObject;);
														}-*/;
	
	private void addAllKeys(Collection s) {
		s.addAll(properties.keySet());
	}
	/*-{
	  var jsObject = [email protected]::jsObject;
	  for (var key in jsObject) {
	    if (jsObject.hasOwnProperty(key)) {
	      [email protected]::add(Ljava/lang/Object;)(key);
	    }
	  }
	}-*/;
	
	private String[] computeKeys() {
		if (GWT.isScript()) {
			return computeKeys0(new String[0]);
		} else {
			List result = new ArrayList();
			addAllKeys(result);
			return result.toArray(new String[result.size()]);
		}
	}
	
	private native String[] computeKeys0(String[] result) /*-{
																			var jsObject = [email protected]::jsObject;
																			var i = 0;
																			for (var key in jsObject) {
																			if (jsObject.hasOwnProperty(key)) {
																			result[i++] = key;
																			}
																			}
																			return result;
																			}-*/;
	
	private native int computeSize() /*-{
												var jsObject = [email protected]::jsObject;
												var size = 0;
												for (var key in jsObject) {
												if (jsObject.hasOwnProperty(key)) {
												++size;
												}
												}
												return size;
												}-*/;
	
	private JSONValue get0(String key) {
		return properties.get(key);
		
	}
	/*-{
	  var jsObject = [email protected]::jsObject;
	  var v;
	  // In Firefox, jsObject.hasOwnProperty(key) requires a primitive string
	  key = String(key);       
	  if (jsObject.hasOwnProperty(key)) {
	    v = jsObject[key];
	  }
	  var func = @com.google.gwt.json.client.JSONParser::typeMap[typeof v];
	  var ret = func ? func(v) : @com.google.gwt.json.client.JSONParser::throwUnknownTypeException(Ljava/lang/String;)(typeof v);
	  return ret;
	}-*/;
	
	private void put0(String key, JSONValue value) {
		if (value == null) {
			properties.remove(key);
		} else {
			properties.put(key, value);
		}
	}
	/*-{
	  if (value) {
	    var func = [email protected]::getUnwrapper()();
	    [email protected]::jsObject[key] = func(value);
	  } else {
	    delete [email protected]::jsObject[key];
	  }
	}-*/;
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy