/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
package com.facebook.react.bridge;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* Java {@link HashMap} backed impementation of {@link ReadableMap} and {@link WritableMap}
* Instances of this class SHOULD NOT be used for communication between java and JS, use instances
* of {@link WritableNativeMap} created via {@link Arguments#createMap} or just {@link ReadableMap}
* interface if you want your "native" module method to take a map from JS as an argument.
*
* Main purpose for this class is to be used in java-only unit tests, but could also be used outside
* of tests in the code that operates only in java and needs to communicate with RN modules via
* their JS-exposed API.
*/
public class JavaOnlyMap implements ReadableMap, WritableMap {
private final Map mBackingMap;
public static JavaOnlyMap of(Object... keysAndValues) {
return new JavaOnlyMap(keysAndValues);
}
/**
* @param keysAndValues keys and values, interleaved
*/
private JavaOnlyMap(Object... keysAndValues) {
if (keysAndValues.length % 2 != 0) {
throw new IllegalArgumentException("You must provide the same number of keys and values");
}
mBackingMap = new HashMap();
for (int i = 0; i < keysAndValues.length; i += 2) {
mBackingMap.put(keysAndValues[i], keysAndValues[i + 1]);
}
}
public JavaOnlyMap() {
mBackingMap = new HashMap();
}
@Override
public boolean hasKey(String name) {
return mBackingMap.containsKey(name);
}
@Override
public boolean isNull(String name) {
return mBackingMap.get(name) == null;
}
@Override
public boolean getBoolean(String name) {
return (Boolean) mBackingMap.get(name);
}
@Override
public double getDouble(String name) {
return (Double) mBackingMap.get(name);
}
@Override
public int getInt(String name) {
return (Integer) mBackingMap.get(name);
}
@Override
public String getString(String name) {
return (String) mBackingMap.get(name);
}
@Override
public JavaOnlyMap getMap(String name) {
return (JavaOnlyMap) mBackingMap.get(name);
}
@Override
public JavaOnlyArray getArray(String name) {
return (JavaOnlyArray) mBackingMap.get(name);
}
@Override
public ReadableType getType(String name) {
Object value = mBackingMap.get(name);
if (value == null) {
return ReadableType.Null;
} else if (value instanceof Number) {
return ReadableType.Number;
} else if (value instanceof String) {
return ReadableType.String;
} else if (value instanceof Boolean) {
return ReadableType.Boolean;
} else if (value instanceof ReadableMap) {
return ReadableType.Map;
} else if (value instanceof ReadableArray) {
return ReadableType.Array;
} else {
throw new IllegalArgumentException("Invalid value " + value.toString() + " for key " + name +
"contained in JavaOnlyMap");
}
}
@Override
public ReadableMapKeySetIterator keySetIterator() {
return new ReadableMapKeySetIterator() {
Iterator<String> mIterator = mBackingMap.keySet().iterator();
@Override
public boolean hasNextKey() {
return mIterator.hasNext();
}
@Override
public String nextKey() {
return mIterator.next();
}
};
}
@Override
public void putBoolean(String key, boolean value) {
mBackingMap.put(key, value);
}
@Override
public void putDouble(String key, double value) {
mBackingMap.put(key, value);
}
@Override
public void putInt(String key, int value) {
mBackingMap.put(key, value);
}
@Override
public void putString(String key, String value) {
mBackingMap.put(key, value);
}
@Override
public void putNull(String key) {
mBackingMap.put(key, null);
}
@Override
public void putMap(String key, WritableMap value) {
mBackingMap.put(key, value);
}
@Override
public void merge(ReadableMap source) {
mBackingMap.putAll(((JavaOnlyMap) source).mBackingMap);
}
@Override
public void putArray(String key, WritableArray value) {
mBackingMap.put(key, value);
}
@Override
public String toString() {
return mBackingMap.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
JavaOnlyMap that = (JavaOnlyMap) o;
if (mBackingMap != null ? !mBackingMap.equals(that.mBackingMap) : that.mBackingMap != null)
return false;
return true;
}
@Override
public int hashCode() {
return mBackingMap != null ? mBackingMap.hashCode() : 0;
}
}