001: /*
002: ******************************************************************************
003: * Copyright (C) 200-2006, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: ******************************************************************************
006: */
007: package com.ibm.icu.util;
008:
009: /**
010: * <pre>
011: * DRAFT
012: * Copyright (C) 2005, International Business Machines Corporation and
013: * others. All Rights Reserved.
014: * </pre>
015: *
016: * Provides a flexible mechanism for controlling access, without requiring that
017: * a class be immutable. Once locked, an object can never be unlocked, so it is
018: * thread-safe from that point onward. The implementation of both methods must
019: * be synchronized. Once the object has been locked, it must guarantee that no
020: * changes can be made to it. Any attempt to alter it must raise an
021: * UnsupportedOperationException exception. This means that when the object
022: * returns internal objects, or if anyone has references to those internal
023: * objects, that those internal objects must either be immutable, or must also
024: * raise exceptions if any attempt to modify them is made. Of course, the object
025: * can return clones of internal objects, since those are safe.
026: * <h2>Background</h2>
027: * <p>
028: * There are often times when you need objects to be objects 'safe', so that
029: * they can't be modified. Examples are when objects need to be thread-safe, or
030: * in writing robust code, or in caches. If you are only creating your own
031: * objects, you can guarantee this, of course -- but only if you don't make a
032: * mistake. If you have objects handed into you, or are creating objects using
033: * others handed into you, it is a different story. It all comes down to whether
034: * you want to take the Blanche Dubois approach ("depend on the kindness of
035: * strangers") or the Andy Grove approach ("Only the Paranoid
036: * Survive").
037: * </p>
038: * <p>
039: * For example, suppose we have a simple class:
040: * </p>
041: *
042: * <pre>
043: * public class A {
044: * protected Collection b;
045: *
046: * protected Collection c;
047: *
048: * public Collection get_b() {
049: * return b;
050: * }
051: *
052: * public Collection get_c() {
053: * return c;
054: * }
055: *
056: * public A(Collection new_b, Collection new_c) {
057: * b = new_b;
058: * c = new_c;
059: * }
060: * }
061: * </pre>
062: *
063: * <p>
064: * Since the class doesn't have any setters, someone might think that it is
065: * immutable. You know where this is leading, of course; this class is unsafe in
066: * a number of ways. The following illustrates that.
067: * </p>
068: *
069: * <pre>
070: * public test1(SupposedlyImmutableClass x, SafeStorage y) {
071: * <font color="#0000FF"> <b>// unsafe getter</b>
072: * </font> A a = x.getA();
073: * Collection col = a.get_b();
074: * col.add(something);<font color="#0000FF"> // a has now been changed, and x too
075: * </font>
076: * <font color="#0000FF"><b>// unsafe constructor</b></font>
077: * a = new A(col, col);
078: * y.store(a);
079: * col.add(something);<font color="#0000FF"> // a has now been changed, and y too
080: *
081: * </font>}
082: * </pre>
083: *
084: * <p>
085: * There are a few different techniques for having safe classes.
086: * </p>
087: * <ol>
088: * <li>Const objects. In C++, you can declare parameters const.</li>
089: * <li>Immutable wrappers. For example, you can put a collection in an
090: * immutable wrapper.</li>
091: * <li>Always-Immutable objects. Java uses this approach, with a few
092: * variations. Examples:
093: * <ol>
094: * <li>Simple. Once a Color is created (eg from R, G, and B integers) it is
095: * immutable.</li>
096: * <li>Builder Class. There is a separate 'builder' class. For example,
097: * modifiable Strings are created using StringBuffer (which doesn't have the
098: * full String API available). Once you want an immutable form, you create one
099: * with toString().</li>
100: * <li>Primitives. These are always safe, since they are copied on input/output
101: * from methods.</li>
102: * </ol>
103: * </li>
104: * <li>Cloning. Where you need an object to be safe, you clone it.</li>
105: * </ol>
106: * <p>
107: * There are advantages and disadvantages of each of these.
108: * </p>
109: * <ol>
110: * <li>Const provides a certain level of protection, but since const can be and
111: * is often cast away, it only protects against most inadvertent mistakes. It
112: * also offers no threading protection, since anyone who has a pointer to the
113: * (unconst) object in another thread can mess you up.</li>
114: * <li>Immutable wrappers are safer than const in that the constness can't be
115: * cast away. But other than that they have all the same problems: not safe if
116: * someone else keeps hold of the original object, or if any of the objects
117: * returned by the class are mutable.</li>
118: * <li>Always-Immutable Objects are safe, but usage can require excessive
119: * object creation.</li>
120: * <li>Cloning is only safe if the object truly has a 'safe' clone; defined as
121: * one that <i>ensures that no change to the clone affects the original</i>.
122: * Unfortunately, many objects don't have a 'safe' clone, and always cloning can
123: * require excessive object creation.</li>
124: * </ol>
125: * <h2>Freezable Model</h2>
126: * <p>
127: * The <code>Freezable</code> model supplements these choices by giving you
128: * the ability to build up an object by calling various methods, then when it is
129: * in a final state, you can <i>make</i> it immutable. Once immutable, an
130: * object cannot <i>ever </i>be modified, and is completely thread-safe: that
131: * is, multiple threads can have references to it without any synchronization.
132: * If someone needs a mutable version of an object, they can use
133: * <code>cloneAsThawed()</code>, and modify the copy. This provides a simple,
134: * effective mechanism for safe classes in circumstances where the alternatives
135: * are insufficient or clumsy. (If an object is shared before it is immutable,
136: * then it is the responsibility of each thread to mutex its usage (as with
137: * other objects).)
138: * </p>
139: * <p>
140: * Here is what needs to be done to implement this interface, depending on the
141: * type of the object.
142: * </p>
143: * <h3><b>Immutable Objects</b></h3>
144: * <p>
145: * These are the easiest. You just use the interface to reflect that, by adding
146: * the following:
147: * </p>
148: *
149: * <pre>
150: * public class A implements Freezable {
151: * ...
152: * public final boolean isFrozen() {return true;}
153: * public final Object freeze() {return this;}
154: * public final Object cloneAsThawed() { return this; }
155: * }
156: * </pre>
157: *
158: * <p>
159: * These can be final methods because subclasses of immutable objects must
160: * themselves be immutable. (Note: <code>freeze</code> is returning
161: * <code>this</code> for chaining.)
162: * </p>
163: * <h3><b>Mutable Objects</b></h3>
164: * <p>
165: * Add a protected 'flagging' field:
166: * </p>
167: *
168: * <pre>
169: * protected boolean immutable;
170: * </pre>
171: *
172: * <p>
173: * Add the following methods:
174: * </p>
175: *
176: * <pre>
177: * public final boolean isFrozen() {
178: * return frozen;
179: * };
180: *
181: * public Object freeze() {
182: * frozen = true;
183: * return this;
184: * }
185: * </pre>
186: *
187: * <p>
188: * Add a <code>cloneAsThawed()</code> method following the normal pattern for
189: * <code>clone()</code>, except that <code>frozen=false</code> in the new
190: * clone.
191: * </p>
192: * <p>
193: * Then take the setters (that is, any method that can change the internal state
194: * of the object), and add the following as the first statement:
195: * </p>
196: *
197: * <pre>
198: * if (isFrozen()) {
199: * throw new UnsupportedOperationException("Attempt to modify frozen object");
200: * }
201: * </pre>
202: *
203: * <h4><b>Subclassing</b></h4>
204: * <p>
205: * Any subclass of a <code>Freezable</code> will just use its superclass's
206: * flagging field. It must override <code>freeze()</code> and
207: * <code>cloneAsThawed()</code> to call the superclass, but normally does not
208: * override <code>isFrozen()</code>. It must then just pay attention to its
209: * own getters, setters and fields.
210: * </p>
211: * <h4><b>Internal Caches</b></h4>
212: * <p>
213: * Internal caches are cases where the object is logically unmodified, but
214: * internal state of the object changes. For example, there are const C++
215: * functions that cast away the const on the "this" pointer in order
216: * to modify an object cache. These cases are handled by mutexing the internal
217: * cache to ensure thread-safety. For example, suppose that UnicodeSet had an
218: * internal marker to the last code point accessed. In this case, the field is
219: * not externally visible, so the only thing you need to do is to synchronize
220: * the field for thread safety.
221: * </p>
222: * <h4>Unsafe Internal Access</h4>
223: * <p>
224: * Internal fields are called <i>safe</i> if they are either
225: * <code>frozen</code> or immutable (such as String or primitives). If you've
226: * never allowed internal access to these, then you are all done. For example,
227: * converting UnicodeSet to be <code>Freezable</code> is just accomplished
228: * with the above steps. But remember that you <i><b>have</b></i> allowed
229: * access to unsafe internals if you have any code like the following, in a
230: * getter, setter, or constructor:
231: * </p>
232: *
233: * <pre>
234: * Collection getStuff() {
235: * return stuff;
236: * } // caller could keep reference & modify
237: *
238: * void setStuff(Collection x) {
239: * stuff = x;
240: * } // caller could keep reference & modify
241: *
242: * MyClass(Collection x) {
243: * stuff = x;
244: * } // caller could keep reference & modify
245: * </pre>
246: *
247: * <p>
248: * These also illustrated in the code sample in <b>Background</b> above.
249: * </p>
250: * <p>
251: * To deal with unsafe internals, the simplest course of action is to do the
252: * work in the <code>
253: freeze()</code> function. Just make all of your internal
254: * fields frozen, and set the frozen flag. Any subsequent getter/setter will
255: * work properly. Here is an example:
256: * </p>
257: *
258: * <pre>
259: * public Object freeze() {
260: * if (!frozen) {
261: * foo.freeze();
262: * frozen = true;
263: * }
264: * return this;
265: * }
266: * </pre>
267: *
268: * <p>
269: * If the field is a <code>Collection</code> or <code>Map</code>, then to
270: * make it frozen you have two choices. If you have never allowed access to the
271: * collection from outside your object, then just wrap it to prevent future
272: * modification.
273: * </p>
274: *
275: * <pre>
276: * zone_to_country = Collections.unmodifiableMap(zone_to_country);
277: * </pre>
278: *
279: * <p>
280: * If you have <i>ever</i> allowed access, then do a <code>clone()</code>
281: * before wrapping it.
282: * </p>
283: *
284: * <pre>
285: * zone_to_country = Collections.unmodifiableMap(zone_to_country.clone());
286: * </pre>
287: *
288: * <p>
289: * If a collection <i>(or any other container of objects)</i> itself can
290: * contain mutable objects, then for a safe clone you need to recurse through it
291: * to make the entire collection immutable. The recursing code should pick the
292: * most specific collection available, to avoid the necessity of later
293: * downcasing.
294: * </p>
295: * <blockquote>
296: * <p>
297: * <b>Note: </b>An annoying flaw in Java is that the generic collections, like
298: * <code>Map</code> or <code>Set</code>, don't have a <code>clone()</code>
299: * operation. When you don't know the type of the collection, the simplest
300: * course is to just create a new collection:
301: * </p>
302: *
303: * <pre>
304: * zone_to_country = Collections.unmodifiableMap(new HashMap(zone_to_country));
305: * </pre>
306: *
307: * </blockquote>
308: *
309: * @internal revisit for ICU 3.6
310: * @deprecated This API is ICU internal only.
311: */
312: public interface Freezable extends Cloneable {
313: /**
314: * Determines whether the object has been locked or not.
315: * @internal revisit for ICU 3.6
316: * @deprecated This API is ICU internal only.
317: */
318: public boolean isFrozen();
319:
320: /**
321: * Locks the object.
322: * @return the object itself.
323: * @internal revisit for ICU 3.6
324: * @deprecated This API is ICU internal only.
325: */
326: public Object freeze();
327:
328: /**
329: * Provides for the clone operation. Any clone is initially unlocked.
330: * @internal revisit for ICU 3.6
331: * @deprecated This API is ICU internal only.
332: */
333: public Object cloneAsThawed();
334: }
|