/* * %CopyrightBegin% * * Copyright Ericsson AB 2000-2013. All Rights Reserved. * * 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. * * %CopyrightEnd% */ package com.ericsson.otp.erlang; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /** * Provides a Java representation of Erlang maps. Maps are created from one or * more arbitrary Erlang terms. *
*
* The arity of the map is the number of elements it contains. The keys and
* values can be retrieved as arrays and the value for a key can be queried.
*/
public class OtpErlangMap extends OtpErlangObject {
// don't change this!
private static final long serialVersionUID = -6410770117696198497L;
private OtpMap map;
/**
* Create an empty map.
*/
public OtpErlangMap() {
map = new OtpMap();
}
/**
* Create a map from an array of keys and an array of values.
*
* @param keys the array of terms to create the map keys from.
* @param values the array of terms to create the map values from.
* @throws java.lang.IllegalArgumentException if any array is empty (null) or contains null elements.
*/
public OtpErlangMap(final OtpErlangObject[] keys,
final OtpErlangObject[] values) {
this(keys, 0, keys.length, values, 0, values.length);
}
/**
* Create a map from an array of terms.
*
* @param keys the array of terms to create the map from.
* @param kstart the offset of the first key to insert.
* @param kcount the number of keys to insert.
* @param values the array of values to create the map from.
* @param vstart the offset of the first value to insert.
* @param vcount the number of values to insert.
* @throws java.lang.IllegalArgumentException if any array is empty (null) or contains null elements.
* @throws java.lang.IllegalArgumentException if kcount and vcount differ.
*/
public OtpErlangMap(final OtpErlangObject[] keys, final int kstart,
final int kcount, final OtpErlangObject[] values, final int vstart,
final int vcount) {
if (keys == null || values == null) {
throw new java.lang.IllegalArgumentException(
"Map content can't be null");
} else if (kcount != vcount) {
throw new java.lang.IllegalArgumentException(
"Map keys and values must have same arity");
}
map = new OtpMap();
OtpErlangObject key, val;
for (int i = 0; i < vcount; i++) {
if ((key = keys[kstart + i]) == null) {
throw new java.lang.IllegalArgumentException(
"Map key cannot be null (element" + (kstart + i) + ")");
}
if ((val = values[vstart + i]) == null) {
throw new java.lang.IllegalArgumentException(
"Map value cannot be null (element" + (vstart + i)
+ ")");
}
put(key, val);
}
}
/**
* Create a map from a stream containing a map encoded in Erlang external
* format.
*
* @param buf the stream containing the encoded map.
* @throws OtpErlangDecodeException if the buffer does not contain a valid external
* representation of an Erlang map.
*/
public OtpErlangMap(final OtpInputStream buf)
throws OtpErlangDecodeException {
final int arity = buf.read_map_head();
if (arity > 0) {
map = new OtpMap();
for (int i = 0; i < arity; i++) {
OtpErlangObject key, val;
key = buf.read_any();
val = buf.read_any();
put(key, val);
}
} else {
map = new OtpMap();
}
}
/**
* Get the arity of the map.
*
* @return the number of elements contained in the map.
*/
public int arity() {
return map.size();
}
/**
* Put value corresponding to key into the map. For detailed behavior
* description see {@link Map#put(Object, Object)}.
*
* @param key key to associate value with
* @param value value to associate with key
* @return previous value associated with key or null
*/
public OtpErlangObject put(final OtpErlangObject key,
final OtpErlangObject value) {
return map.put(key, value);
}
/**
* removes mapping for the key if present.
*
* @param key key for which mapping is to be remove
* @return value associated with key or null
*/
public OtpErlangObject remove(final OtpErlangObject key) {
return map.remove(key);
}
/**
* Get the specified value from the map.
*
* @param key the key of the requested value.
* @return the requested value, of null if key is not a valid key.
*/
public OtpErlangObject get(final OtpErlangObject key) {
return map.get(key);
}
/**
* Get all the keys from the map as an array.
*
* @return an array containing all of the map's keys.
*/
public OtpErlangObject[] keys() {
return map.keySet().toArray(new OtpErlangObject[arity()]);
}
/**
* Get all the values from the map as an array.
*
* @return an array containing all of the map's values.
*/
public OtpErlangObject[] values() {
return map.values().toArray(new OtpErlangObject[arity()]);
}
/**
* make Set view of the map key-value pairs
*
* @return a set containing key-value pairs
*/
public Set