aboutsummaryrefslogtreecommitdiffstats
path: root/lib/jinterface/java_src/com/ericsson/otp
diff options
context:
space:
mode:
authorZandra Hird <[email protected]>2015-04-29 14:41:39 +0200
committerZandra Hird <[email protected]>2015-04-29 14:41:39 +0200
commitde6ef63b143557558436b5c0213030a27d78da0d (patch)
treed84847fe669fd707d1e3039507906908834f6513 /lib/jinterface/java_src/com/ericsson/otp
parent65cd6574a37af1dfcc01fc4cc9681b4b758f1284 (diff)
parent2fdc3d313485a76b6acf12154b8f3bd3e1ceb2ca (diff)
downloadotp-de6ef63b143557558436b5c0213030a27d78da0d.tar.gz
otp-de6ef63b143557558436b5c0213030a27d78da0d.tar.bz2
otp-de6ef63b143557558436b5c0213030a27d78da0d.zip
Merge branch 'x0id/jinterface_generic_match'
* x0id/jinterface_generic_match: jinterface: match/bind added to OtpErlangObject fix typo error from recent merge OTP-12691
Diffstat (limited to 'lib/jinterface/java_src/com/ericsson/otp')
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java48
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java207
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java26
-rw-r--r--lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java29
4 files changed, 237 insertions, 73 deletions
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
index 990e50ddcd..268261ec10 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangList.java
@@ -297,6 +297,54 @@ public class OtpErlangList extends OtpErlangObject implements
return getLastTail().equals(l.getLastTail());
}
+ @Override
+ public <T> boolean match(final OtpErlangObject term, final T bindings) {
+ if (!(term instanceof OtpErlangList)) {
+ return false;
+ }
+ final OtpErlangList that = (OtpErlangList) term;
+
+ final int thisArity = this.arity();
+ final int thatArity = that.arity();
+ final OtpErlangObject thisTail = this.getLastTail();
+ final OtpErlangObject thatTail = that.getLastTail();
+
+ if (thisTail == null) {
+ if (thisArity != thatArity || thatTail != null) {
+ return false;
+ }
+ } else {
+ if (thisArity > thatArity) {
+ return false;
+ }
+ }
+ for (int i = 0; i < thisArity; i++) {
+ if (!elementAt(i).match(that.elementAt(i), bindings)) {
+ return false;
+ }
+ }
+ if (thisTail == null) {
+ return true;
+ }
+ return thisTail.match(that.getNthTail(thisArity), bindings);
+ }
+
+ @Override
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ final OtpErlangList list = (OtpErlangList) this.clone();
+
+ final int a = list.elems.length;
+ for (int i = 0; i < a; i++) {
+ list.elems[i] = list.elems[i].bind(binds);
+ }
+
+ if (list.lastTail != null) {
+ list.lastTail = list.lastTail.bind(binds);
+ }
+
+ return list;
+ }
+
public OtpErlangObject getLastTail() {
return lastTail;
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
index 7f2621923a..a8cd9d5392 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangMap.java
@@ -18,6 +18,11 @@
*/
package com.ericsson.otp.erlang;
+import java.util.HashMap;
+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.
@@ -31,10 +36,14 @@ public class OtpErlangMap extends OtpErlangObject {
// don't change this!
private static final long serialVersionUID = -6410770117696198497L;
- private static final OtpErlangObject[] NO_ELEMENTS = new OtpErlangObject[0];
+ private HashMap<OtpErlangObject, OtpErlangObject> map;
- private OtpErlangObject[] keys = NO_ELEMENTS;
- private OtpErlangObject[] values = NO_ELEMENTS;
+ /**
+ * Create an empty map.
+ */
+ public OtpErlangMap() {
+ map = new HashMap<OtpErlangObject, OtpErlangObject>();
+ }
/**
* Create a map from an array of keys and an array of values.
@@ -82,30 +91,20 @@ public class OtpErlangMap extends OtpErlangObject {
} else if (kcount != vcount) {
throw new java.lang.IllegalArgumentException(
"Map keys and values must have same arity");
- } else if (vcount < 1) {
- this.keys = NO_ELEMENTS;
- this.values = NO_ELEMENTS;
- } else {
- this.keys = new OtpErlangObject[vcount];
- for (int i = 0; i < vcount; i++) {
- if (keys[kstart + i] != null) {
- this.keys[i] = keys[kstart + i];
- } else {
- throw new java.lang.IllegalArgumentException(
- "Map key cannot be null (element" + (kstart + i)
- + ")");
- }
+ }
+ map = new HashMap<OtpErlangObject, OtpErlangObject>(vcount);
+ 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) + ")");
}
- this.values = new OtpErlangObject[vcount];
- for (int i = 0; i < vcount; i++) {
- if (values[vstart + i] != null) {
- this.values[i] = values[vstart + i];
- } else {
- throw new java.lang.IllegalArgumentException(
- "Map value cannot be null (element" + (vstart + i)
- + ")");
- }
+ if ((val = values[vstart + i]) == null) {
+ throw new java.lang.IllegalArgumentException(
+ "Map value cannot be null (element" + (vstart + i)
+ + ")");
}
+ put(key, val);
}
}
@@ -125,16 +124,15 @@ public class OtpErlangMap extends OtpErlangObject {
final int arity = buf.read_map_head();
if (arity > 0) {
- keys = new OtpErlangObject[arity];
- values = new OtpErlangObject[arity];
-
+ map = new HashMap<OtpErlangObject, OtpErlangObject>(arity);
for (int i = 0; i < arity; i++) {
- keys[i] = buf.read_any();
- values[i] = buf.read_any();
+ OtpErlangObject key, val;
+ key = buf.read_any();
+ val = buf.read_any();
+ put(key, val);
}
} else {
- keys = NO_ELEMENTS;
- values = NO_ELEMENTS;
+ map = new HashMap<OtpErlangObject, OtpErlangObject>();
}
}
@@ -144,7 +142,33 @@ public class OtpErlangMap extends OtpErlangObject {
* @return the number of elements contained in the map.
*/
public int arity() {
- return keys.length;
+ 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);
}
/**
@@ -156,15 +180,7 @@ public class OtpErlangMap extends OtpErlangObject {
* @return the requested value, of null if key is not a valid key.
*/
public OtpErlangObject get(final OtpErlangObject key) {
- if (key == null) {
- return null;
- }
- for (int i = 0; i < keys.length; i++) {
- if (key.equals(keys[i])) {
- return values[i];
- }
- }
- return null;
+ return map.get(key);
}
/**
@@ -173,9 +189,7 @@ public class OtpErlangMap extends OtpErlangObject {
* @return an array containing all of the map's keys.
*/
public OtpErlangObject[] keys() {
- final OtpErlangObject[] res = new OtpErlangObject[arity()];
- System.arraycopy(keys, 0, res, 0, res.length);
- return res;
+ return map.keySet().toArray(new OtpErlangObject[arity()]);
}
/**
@@ -184,9 +198,16 @@ public class OtpErlangMap extends OtpErlangObject {
* @return an array containing all of the map's values.
*/
public OtpErlangObject[] values() {
- final OtpErlangObject[] res = new OtpErlangObject[arity()];
- System.arraycopy(values, 0, res, 0, res.length);
- return res;
+ 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<Entry<OtpErlangObject, OtpErlangObject>> entrySet() {
+ return map.entrySet();
}
/**
@@ -196,19 +217,20 @@ public class OtpErlangMap extends OtpErlangObject {
*/
@Override
public String toString() {
- int i;
final StringBuffer s = new StringBuffer();
- final int arity = values.length;
s.append("#{");
- for (i = 0; i < arity; i++) {
- if (i > 0) {
+ boolean first = true;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ if (first) {
+ first = false;
+ } else {
s.append(",");
}
- s.append(keys[i].toString());
+ s.append(e.getKey().toString());
s.append(" => ");
- s.append(values[i].toString());
+ s.append(e.getValue().toString());
}
s.append("}");
@@ -224,13 +246,13 @@ public class OtpErlangMap extends OtpErlangObject {
*/
@Override
public void encode(final OtpOutputStream buf) {
- final int arity = values.length;
+ final int arity = arity();
buf.write_map_head(arity);
- for (int i = 0; i < arity; i++) {
- buf.write_any(keys[i]);
- buf.write_any(values[i]);
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ buf.write_any(e.getKey());
+ buf.write_any(e.getValue());
}
}
@@ -256,15 +278,46 @@ public class OtpErlangMap extends OtpErlangObject {
if (a != t.arity()) {
return false;
}
+ if (a == 0) {
+ return true;
+ }
- for (int i = 0; i < a; i++) {
- if (!keys[i].equals(t.keys[i])) {
- return false; // early exit
+ OtpErlangObject key, val;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ key = e.getKey();
+ val = e.getValue();
+ final OtpErlangObject v = t.get(key);
+ if (v == null || !val.equals(v)) {
+ return false;
}
}
- for (int i = 0; i < a; i++) {
- if (!values[i].equals(t.values[i])) {
- return false; // early exit
+
+ return true;
+ }
+
+ @Override
+ public <T> boolean match(final OtpErlangObject term, final T binds) {
+ if (!(term instanceof OtpErlangMap)) {
+ return false;
+ }
+
+ final OtpErlangMap t = (OtpErlangMap) term;
+ final int a = arity();
+
+ if (a > t.arity()) {
+ return false;
+ }
+ if (a == 0) {
+ return true;
+ }
+
+ OtpErlangObject key, val;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ key = e.getKey();
+ val = e.getValue();
+ final OtpErlangObject v = t.get(key);
+ if (v == null || !val.match(v, binds)) {
+ return false;
}
}
@@ -272,23 +325,31 @@ public class OtpErlangMap extends OtpErlangObject {
}
@Override
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ final OtpErlangMap ret = new OtpErlangMap();
+
+ OtpErlangObject key, val;
+ for (final Map.Entry<OtpErlangObject, OtpErlangObject> e : entrySet()) {
+ key = e.getKey();
+ val = e.getValue();
+ ret.put(key, val.bind(binds));
+ }
+
+ return ret;
+ }
+
+ @Override
protected int doHashCode() {
final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(9);
- final int a = arity();
- hash.combine(a);
- for (int i = 0; i < a; i++) {
- hash.combine(keys[i].hashCode());
- }
- for (int i = 0; i < a; i++) {
- hash.combine(values[i].hashCode());
- }
+ hash.combine(map.hashCode());
return hash.valueOf();
}
@Override
+ @SuppressWarnings("unchecked")
public Object clone() {
final OtpErlangMap newMap = (OtpErlangMap) super.clone();
- newMap.values = values.clone();
+ newMap.map = (HashMap<OtpErlangObject, OtpErlangObject>) map.clone();
return newMap;
}
}
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
index 7ab160bcdd..9339d3749b 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangObject.java
@@ -80,6 +80,32 @@ public abstract class OtpErlangObject implements Serializable, Cloneable {
@Override
public abstract boolean equals(Object o);
+ /**
+ * Perform match operation against given term.
+ *
+ * @param term
+ * the object to match
+ * @param binds
+ * variable bindings
+ * @return true if match succeeded
+ */
+ public <T> boolean match(final OtpErlangObject term, final T binds) {
+ return equals(term);
+ }
+
+ /**
+ * Make new Erlang term replacing variables with the respective values from
+ * bindings argument(s).
+ *
+ * @param binds
+ * variable bindings
+ * @return new term
+ * @throws OtpErlangException
+ */
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ return this;
+ }
+
@Override
public int hashCode() {
if (hashCodeValue == 0) {
diff --git a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
index af2559e62e..ef0a453de1 100644
--- a/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
+++ b/lib/jinterface/java_src/com/ericsson/otp/erlang/OtpErlangTuple.java
@@ -236,6 +236,35 @@ public class OtpErlangTuple extends OtpErlangObject {
}
@Override
+ public <T> boolean match(final OtpErlangObject term, final T bindings) {
+ if (!(term instanceof OtpErlangTuple)) {
+ return false;
+ }
+ final OtpErlangTuple t = (OtpErlangTuple) term;
+ final int a = elems.length;
+ if (a != t.elems.length) {
+ return false;
+ }
+ for (int i = 0; i < a; i++) {
+ if (!elems[i].match(t.elems[i], bindings)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public <T> OtpErlangObject bind(final T binds) throws OtpErlangException {
+ final OtpErlangTuple tuple = (OtpErlangTuple) this.clone();
+ final int a = tuple.elems.length;
+ for (int i = 0; i < a; i++) {
+ final OtpErlangObject e = tuple.elems[i];
+ tuple.elems[i] = e.bind(binds);
+ }
+ return tuple;
+ }
+
+ @Override
protected int doHashCode() {
final OtpErlangObject.Hash hash = new OtpErlangObject.Hash(9);
final int a = arity();