Package loop.lang

Source Code of loop.lang.ImmutableLoopObject

package loop.lang;

import loop.LoopExecutionException;

import java.util.Collection;
import java.util.IdentityHashMap;
import java.util.Map;

/**
* The root object of all immutable object instances in loop. Actually this is the
* Java class that backs all instances of immutable loop types.
*
* @author dhanji@gmail.com (Dhanji R. Prasanna)
*/
public class ImmutableLoopObject extends LoopObject implements Immutable {
  static final String IMMUTABILITY_ERROR =
      "Illegal attempt to create an object oriented language!";

  public ImmutableLoopObject(LoopClass type, Map<Object, Object> source) {
    super(type);

    IdentityHashMap<Object, Object> cyclesCheck = new IdentityHashMap<Object, Object>();
    cyclesCheck.put(source, this);

    deepCopy(cyclesCheck, source);
  }

  public ImmutableLoopObject(LoopClass type,
                             Map<Object, Object> source,
                             IdentityHashMap<Object, Object> cyclesCheck) {
    super(type);
    deepCopy(cyclesCheck, source);
  }

  @SuppressWarnings("unchecked")
  private void deepCopy(IdentityHashMap<Object, Object> cyclesCheck, Map<Object, Object> source) {
    for (Map.Entry<Object, Object> entry : source.entrySet()) {
      Object value = entry.getValue();

      // Make immutable copy of value if necessary.
      if (value instanceof Map) {
        Object previouslyCopied = cyclesCheck.get(value);

        if (previouslyCopied != null)
          value = previouslyCopied;
        else {
          ImmutableLoopObject copied =
              new ImmutableLoopObject(LoopClass.IMMUTABLE_MAP, (Map<Object, Object>) value, cyclesCheck);
          cyclesCheck.put(value, copied);
          value = copied;
        }
      } else if (value instanceof Collection) {
        Object previouslyCopied = cyclesCheck.get(value);

        if (previouslyCopied != null)
          value = previouslyCopied;
        else {
          ImmutableList copied = new ImmutableList((Collection<?>) value, cyclesCheck);
          cyclesCheck.put(value, copied);
          value = copied;
        }
      }

      // Ensure immutability.
      if (!isImmutable(value))
        throw new LoopExecutionException("Cannot add a mutable value to an immutable object");

      super.put(entry.getKey(), value);
    }
  }

  static boolean isImmutable(Object value) {
    return value instanceof Immutable
        || value instanceof String
        || value instanceof Number;
  }

  @Override public Object put(Object o, Object o1) {
    throw new LoopExecutionException(IMMUTABILITY_ERROR);
  }

  @Override public void putAll(Map<?, ?> map) {
    throw new LoopExecutionException(IMMUTABILITY_ERROR);
  }

  @Override public void clear() {
    throw new LoopExecutionException(IMMUTABILITY_ERROR);
  }

  @Override public Object remove(Object o) {
    throw new LoopExecutionException(IMMUTABILITY_ERROR);
  }
}
TOP

Related Classes of loop.lang.ImmutableLoopObject

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.