1 /* 2 ****************************************************************************** 3 * Copyright (C) 200-2006, International Business Machines Corporation and * 4 * others. All Rights Reserved. * 5 ****************************************************************************** 6 */ 7 package com.ibm.icu.util; 8 9 /** 10 * <pre> 11 * DRAFT 12 * Copyright (C) 2005, International Business Machines Corporation and 13 * others. All Rights Reserved. 14 * </pre> 15 * 16 * Provides a flexible mechanism for controlling access, without requiring that 17 * a class be immutable. Once locked, an object can never be unlocked, so it is 18 * thread-safe from that point onward. The implementation of both methods must 19 * be synchronized. Once the object has been locked, it must guarantee that no 20 * changes can be made to it. Any attempt to alter it must raise an 21 * UnsupportedOperationException exception. This means that when the object 22 * returns internal objects, or if anyone has references to those internal 23 * objects, that those internal objects must either be immutable, or must also 24 * raise exceptions if any attempt to modify them is made. Of course, the object 25 * can return clones of internal objects, since those are safe. 26 * <h2>Background</h2> 27 * <p> 28 * There are often times when you need objects to be objects 'safe', so that 29 * they can't be modified. Examples are when objects need to be thread-safe, or 30 * in writing robust code, or in caches. If you are only creating your own 31 * objects, you can guarantee this, of course -- but only if you don't make a 32 * mistake. If you have objects handed into you, or are creating objects using 33 * others handed into you, it is a different story. It all comes down to whether 34 * you want to take the Blanche Dubois approach ("depend on the kindness of 35 * strangers") or the Andy Grove approach ("Only the Paranoid 36 * Survive"). 37 * </p> 38 * <p> 39 * For example, suppose we have a simple class: 40 * </p> 41 * 42 * <pre> 43 * public class A { 44 * protected Collection b; 45 * 46 * protected Collection c; 47 * 48 * public Collection get_b() { 49 * return b; 50 * } 51 * 52 * public Collection get_c() { 53 * return c; 54 * } 55 * 56 * public A(Collection new_b, Collection new_c) { 57 * b = new_b; 58 * c = new_c; 59 * } 60 * } 61 * </pre> 62 * 63 * <p> 64 * Since the class doesn't have any setters, someone might think that it is 65 * immutable. You know where this is leading, of course; this class is unsafe in 66 * a number of ways. The following illustrates that. 67 * </p> 68 * 69 * <pre> 70 * public test1(SupposedlyImmutableClass x, SafeStorage y) { 71 * <font color="#0000FF"> <b>// unsafe getter</b> 72 * </font> A a = x.getA(); 73 * Collection col = a.get_b(); 74 * col.add(something);<font color="#0000FF"> // a has now been changed, and x too 75 * </font> 76 * <font color="#0000FF"><b>// unsafe constructor</b></font> 77 * a = new A(col, col); 78 * y.store(a); 79 * col.add(something);<font color="#0000FF"> // a has now been changed, and y too 80 * 81 * </font>} 82 * </pre> 83 * 84 * <p> 85 * There are a few different techniques for having safe classes. 86 * </p> 87 * <ol> 88 * <li>Const objects. In C++, you can declare parameters const.</li> 89 * <li>Immutable wrappers. For example, you can put a collection in an 90 * immutable wrapper.</li> 91 * <li>Always-Immutable objects. Java uses this approach, with a few 92 * variations. Examples: 93 * <ol> 94 * <li>Simple. Once a Color is created (eg from R, G, and B integers) it is 95 * immutable.</li> 96 * <li>Builder Class. There is a separate 'builder' class. For example, 97 * modifiable Strings are created using StringBuffer (which doesn't have the 98 * full String API available). Once you want an immutable form, you create one 99 * 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 } 335