diff options
Diffstat (limited to 'lib/jinterface/java_src')
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(); | 
