/*
 ******************************************************************************
 * Copyright (C) 2005-2014, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                               *
 ******************************************************************************
*/
package com.ibm.icu.util;

/**
 * Provides a flexible mechanism for controlling access, without requiring that
 * a class be immutable. Once frozen, an object can never be unfrozen, so it is
 * thread-safe from that point onward. Once the object has been frozen, 
 * it must guarantee that no changes can be made to it. Any attempt to alter 
 * it must raise an UnsupportedOperationException exception. This means that when 
 * the object returns internal objects, or if anyone has references to those internal
 * objects, that those internal objects must either be immutable, or must also
 * raise exceptions if any attempt to modify them is made. Of course, the object
 * can return clones of internal objects, since those are safe.
 * <h2>Background</h2>
 * <p>
 * There are often times when you need objects to be objects 'safe', so that
 * they can't be modified. Examples are when objects need to be thread-safe, or
 * in writing robust code, or in caches. If you are only creating your own
 * objects, you can guarantee this, of course -- but only if you don't make a
 * mistake. If you have objects handed into you, or are creating objects using
 * others handed into you, it is a different story. It all comes down to whether
 * you want to take the Blanche Dubois approach (&quot;depend on the kindness of
 * strangers&quot;) or the Andy Grove approach (&quot;Only the Paranoid
 * Survive&quot;).
 * </p>
 * <p>
 * For example, suppose we have a simple class:
 * </p>
 * 
 * <pre>
 * public class A {
 *      protected Collection b;
 * 
 *      protected Collection c;
 * 
 *      public Collection get_b() {
 *              return b;
 *      }
 * 
 *      public Collection get_c() {
 *              return c;
 *      }
 * 
 *      public A(Collection new_b, Collection new_c) {
 *              b = new_b;
 *              c = new_c;
 *      }
 * }
 * </pre>
 * 
 * <p>
 * Since the class doesn't have any setters, someone might think that it is
 * immutable. You know where this is leading, of course; this class is unsafe in
 * a number of ways. The following illustrates that.
 * </p>
 * 
 * <pre>
 *  public test1(SupposedlyImmutableClass x, SafeStorage y) {
 *    // unsafe getter
 *    A a = x.getA();
 *    Collection col = a.get_b();
 *    col.add(something); // a has now been changed, and x too
 *
 *    // unsafe constructor
 *    a = new A(col, col);
 *    y.store(a);
 *    col.add(something); // a has now been changed, and y too
 *  }
 * </pre>
 * 
 * <p>
 * There are a few different techniques for having safe classes.
 * </p>
 * <ol>
 * <li>Const objects. In C++, you can declare parameters const.</li>
 * <li>Immutable wrappers. For example, you can put a collection in an
 * immutable wrapper.</li>
 * <li>Always-Immutable objects. Java uses this approach, with a few
 * variations. Examples:
 * <ol>
 * <li>Simple. Once a Color is created (eg from R, G, and B integers) it is
 * immutable.</li>
 * <li>Builder Class. There is a separate 'builder' class. For example,
 * modifiable Strings are created using StringBuffer (which doesn't have the
 * full String API available). Once you want an immutable form, you create one
 * with toString().</li>
 * <li>Primitives. These are always safe, since they are copied on input/output
 * from methods.</li>
 * </ol>
 * </li>
 * <li>Cloning. Where you need an object to be safe, you clone it.</li>
 * </ol>
 * <p>
 * There are advantages and disadvantages of each of these.
 * </p>
 * <ol>
 * <li>Const provides a certain level of protection, but since const can be and
 * is often cast away, it only protects against most inadvertent mistakes. It
 * also offers no threading protection, since anyone who has a pointer to the
 * (unconst) object in another thread can mess you up.</li>
 * <li>Immutable wrappers are safer than const in that the constness can't be
 * cast away. But other than that they have all the same problems: not safe if
 * someone else keeps hold of the original object, or if any of the objects
 * returned by the class are mutable.</li>
 * <li>Always-Immutable Objects are safe, but usage can require excessive
 * object creation.</li>
 * <li>Cloning is only safe if the object truly has a 'safe' clone; defined as
 * one that <i>ensures that no change to the clone affects the original</i>.
 * Unfortunately, many objects don't have a 'safe' clone, and always cloning can
 * require excessive object creation.</li>
 * </ol>
 * <h2>Freezable Model</h2>
 * <p>
 * The <code>Freezable</code> model supplements these choices by giving you
 * the ability to build up an object by calling various methods, then when it is
 * in a final state, you can <i>make</i> it immutable. Once immutable, an
 * object cannot <i>ever </i>be modified, and is completely thread-safe: that
 * is, multiple threads can have references to it without any synchronization.
 * If someone needs a mutable version of an object, they can use
 * <code>cloneAsThawed()</code>, and modify the copy. This provides a simple,
 * effective mechanism for safe classes in circumstances where the alternatives
 * are insufficient or clumsy. (If an object is shared before it is immutable,
 * then it is the responsibility of each thread to mutex its usage (as with
 * other objects).)
 * </p>
 * <p>
 * Here is what needs to be done to implement this interface, depending on the
 * type of the object.
 * </p>
 * <h3><b>Immutable Objects</b></h3>
 * <p>
 * These are the easiest. You just use the interface to reflect that, by adding
 * the following:
 * </p>
 * 
 * <pre>
 *  public class A implements Freezable<A> {
 *   ...
 *   public final boolean isFrozen() {return true;}
 *   public final A freeze() {return this;}
 *   public final A cloneAsThawed() { return this; }
 *   }
 * </pre>
 * 
 * <p>
 * These can be final methods because subclasses of immutable objects must
 * themselves be immutable. (Note: <code>freeze</code> is returning
 * <code>this</code> for chaining.)
 * </p>
 * <h3><b>Mutable Objects</b></h3>
 * <p>
 * Add a protected 'flagging' field:
 * </p>
 * 
 * <pre>
 * protected volatile boolean frozen; // WARNING: must be volatile
 * </pre>
 * 
 * <p>
 * Add the following methods:
 * </p>
 * 
 * <pre>
 * public final boolean isFrozen() {
 *      return frozen;
 * };
 * 
 * public A freeze() {
 *      frozen = true;  // WARNING: must be final statement before return
 *      return this;
 * }
 * </pre>
 * 
 * <p>
 * Add a <code>cloneAsThawed()</code> method following the normal pattern for
 * <code>clone()</code>, except that <code>frozen=false</code> in the new
 * clone.
 * </p>
 * <p>
 * Then take the setters (that is, any method that can change the internal state
 * of the object), and add the following as the first statement:
 * </p>
 * 
 * <pre>
 * if (isFrozen()) {
 *      throw new UnsupportedOperationException(&quot;Attempt to modify frozen object&quot;);
 * }
 * </pre>
 * 
 * <h4><b>Subclassing</b></h4>
 * <p>
 * Any subclass of a <code>Freezable</code> will just use its superclass's
 * flagging field. It must override <code>freeze()</code> and
 * <code>cloneAsThawed()</code> to call the superclass, but normally does not
 * override <code>isFrozen()</code>. It must then just pay attention to its
 * own getters, setters and fields.
 * </p>
 * <h4><b>Internal Caches</b></h4>
 * <p>
 * Internal caches are cases where the object is logically unmodified, but
 * internal state of the object changes. For example, there are const C++
 * functions that cast away the const on the &quot;this&quot; pointer in order
 * to modify an object cache. These cases are handled by mutexing the internal
 * cache to ensure thread-safety. For example, suppose that UnicodeSet had an
 * internal marker to the last code point accessed. In this case, the field is
 * not externally visible, so the only thing you need to do is to synchronize
 * the field for thread safety.
 * </p>
 * <h4>Unsafe Internal Access</h4>
 * <p>
 * Internal fields are called <i>safe</i> if they are either
 * <code>frozen</code> or immutable (such as String or primitives). If you've
 * never allowed internal access to these, then you are all done. For example,
 * converting UnicodeSet to be <code>Freezable</code> is just accomplished
 * with the above steps. But remember that you <i><b>have</b></i> allowed
 * access to unsafe internals if you have any code like the following, in a
 * getter, setter, or constructor:
 * </p>
 * 
 * <pre>
 * Collection getStuff() {
 *      return stuff;
 * } // caller could keep reference &amp; modify
 * 
 * void setStuff(Collection x) {
 *      stuff = x;
 * } // caller could keep reference &amp; modify
 * 
 * MyClass(Collection x) {
 *      stuff = x;
 * } // caller could keep reference &amp; modify
 * </pre>
 * 
 * <p>
 * These also illustrated in the code sample in <b>Background</b> above.
 * </p>
 * <p>
 * To deal with unsafe internals, the simplest course of action is to do the
 * work in the <code>freeze()</code> function. Just make all of your internal
 * fields frozen, and set the frozen flag. Any subsequent getter/setter will
 * work properly. Here is an example:
 * </p>
 * <p><b>Warning!</b> The 'frozen' boolean MUST be volatile, and must be set as the last statement
 * in the method.</p>
 * <pre>
 * public A freeze() {
 *      if (!frozen) {
 *              foo.freeze();
 *              frozen = true;
 *      }
 *      return this;
 * }
 * </pre>
 * 
 * <p>
 * If the field is a <code>Collection</code> or <code>Map</code>, then to
 * make it frozen you have two choices. If you have never allowed access to the
 * collection from outside your object, then just wrap it to prevent future
 * modification.
 * </p>
 * 
 * <pre>
 * zone_to_country = Collections.unmodifiableMap(zone_to_country);
 * </pre>
 * 
 * <p>
 * If you have <i>ever</i> allowed access, then do a <code>clone()</code>
 * before wrapping it.
 * </p>
 * 
 * <pre>
 * zone_to_country = Collections.unmodifiableMap(zone_to_country.clone());
 * </pre>
 * 
 * <p>
 * If a collection <i>(or any other container of objects)</i> itself can
 * contain mutable objects, then for a safe clone you need to recurse through it
 * to make the entire collection immutable. The recursing code should pick the
 * most specific collection available, to avoid the necessity of later
 * downcasing.
 * </p>
 * <blockquote>
 * <p>
 * <b>Note: </b>An annoying flaw in Java is that the generic collections, like
 * <code>Map</code> or <code>Set</code>, don't have a <code>clone()</code>
 * operation. When you don't know the type of the collection, the simplest
 * course is to just create a new collection:
 * </p>
 * 
 * <pre>
 * zone_to_country = Collections.unmodifiableMap(new HashMap(zone_to_country));
 * </pre>
 * 
 * </blockquote>
 * @stable ICU 3.8
 */
public interface Freezable<T> extends Cloneable {
    /**
     * Determines whether the object has been frozen or not.
     * @stable ICU 3.8
     */
    public boolean isFrozen();

    /**
     * Freezes the object.
     * @return the object itself.
     * @stable ICU 3.8
     */
    public T freeze();

    /**
     * Provides for the clone operation. Any clone is initially unfrozen.
     * @stable ICU 3.8
     */
    public T cloneAsThawed();
}
