1 9 package javolution.context; 10 11 import javolution.lang.ClassInitializer; 12 import javolution.lang.Configurable; 13 import javolution.util.FastTable; 14 import j2me.lang.ThreadLocal; 15 import j2me.lang.UnsupportedOperationException; 16 import j2mex.realtime.MemoryArea; 17 18 47 public abstract class ObjectFactory{ 48 49 54 public static final Configurable MAX_COUNT = new Configurable( 55 new Integer (256)) { 56 protected void notifyChange() { 57 synchronized (LOCK) { 58 final int newCount = ((Integer )MAX_COUNT.get()).intValue(); 59 if (_Count >= newCount) 60 throw new j2me.lang.UnsupportedOperationException( 61 "Already " + _Count 62 + " factories, cannot reduce to " 63 + newCount); 64 MemoryArea.getMemoryArea(_Instances).executeInArea( 65 new Runnable () { 66 public void run() { 67 ObjectFactory[] tmp = new ObjectFactory[newCount]; 68 System.arraycopy(_Instances, 0, tmp, 0, _Count); 69 _Instances = tmp; 70 } 71 }); 72 } 73 } 74 }; 75 76 private static final Object LOCK = new Object (); 77 78 81 static ObjectFactory[] _Instances = new ObjectFactory[((Integer )MAX_COUNT.get()).intValue()]; 82 83 86 static int _Count; 87 88 91 final int _index; 92 93 97 private boolean _doCleanup = true; 98 99 102 protected ObjectFactory() { 103 synchronized (LOCK) { 104 if (_Count >= _Instances.length) 105 throw new UnsupportedOperationException ( 106 "Configuration setting of a maximum " + _Instances.length 107 + " factories has been reached"); 108 Class factoryClass = this.getClass(); 109 for (int i = 0; i < _Count; i++) { 110 if (factoryClass == _Instances[i].getClass()) { 111 throw new UnsupportedOperationException (factoryClass 112 + " cannot have more than one instance"); 113 } 114 } 115 _index = _Count++; 116 _Instances[_index] = this; 117 } 118 } 119 120 126 protected abstract Object create(); 127 128 134 public Object object() { 135 return currentPool().next(); 136 } 137 138 144 public void recycle(Object obj) { 145 currentPool().recycle(obj); 146 } 147 148 154 public ObjectPoolcurrentPool() { 155 ObjectPool pool = (ObjectPool) _currentPool.get(); 156 return (pool._user != null) ? pool : activatePool(); 157 } 158 159 private final ObjectPool activatePool() { 160 LocalPools pools = Context.current().getLocalPools(); 161 ObjectPool pool = pools.getPool(this, true); 162 _currentPool.set(pool); 163 return pool; 164 } 165 166 final ThreadLocal _currentPool = new ThreadLocal () { 167 protected Object initialValue() { 168 return newHeapPool(); 169 } 170 }; 171 172 190 protected void cleanup(Object obj) { 191 _doCleanup = false; 192 } 193 194 201 final boolean doCleanup() { 202 return _doCleanup; 203 } 204 205 211 protected ObjectPool newStackPool() { 212 return new StackPool(); 213 } 214 215 221 protected ObjectPool newHeapPool() { 222 return new HeapPool(); 223 } 224 225 231 static ObjectFactory getInstance(Class factoryClass) { 232 String className = factoryClass.getName(); 234 int sep = className.lastIndexOf('$'); 235 if (sep > 0) { 236 ClassInitializer.initialize(className.substring(0, sep)); 237 } 238 ClassInitializer.initialize(factoryClass); 239 for (int i = 0; i < ObjectFactory._Count; i++) { 240 if (_Instances[i].getClass().equals(factoryClass)) 241 return _Instances[i]; 242 } 243 throw new IllegalArgumentException ("Factory class: " + factoryClass + " not found" 244 + ", possibly container class not initialized"); 245 } 246 247 250 private final class HeapPool extends ObjectPool { 251 252 255 private final FastTable _objects = new FastTable(); 256 257 260 private HeapPool() { 261 } 262 263 public int getSize() { 265 return _objects.size(); 266 } 267 268 public void setSize(int size) { 270 for (int i=getSize(); i < size; i++) { 271 _objects.addLast(create()); 272 } 273 } 274 275 public Object next() { 277 return _objects.isEmpty() ? create() : _objects 278 .removeLast(); 279 } 280 281 public void recycle(Object obj) { 283 cleanup((Object )obj); 284 if (MemoryArea.getMemoryArea(obj) != MemoryArea.getMemoryArea(this)) 285 return; _objects.addLast(obj); 287 } 288 289 protected void recycleAll() { 291 } 293 294 protected void clearAll() { 296 _objects.clear(); 297 } 298 299 } 300 301 306 private final class StackPool extends ObjectPool implements Runnable { 307 308 311 private final FastTable _objects = new FastTable(); 312 313 316 private int _index; 317 318 321 private StackPool() { 322 } 323 324 public int getSize() { 326 return _objects.size(); 327 } 328 329 public void setSize(int size) { 331 for (int i=getSize(); i < size; i++) { 332 _objects.addLast(create()); 333 } 334 } 335 336 public Object next() { 338 return (_index < _objects.size()) ? _objects.get(_index++) 339 : newObject(); 340 } 341 342 private Object newObject() { 343 MemoryArea.getMemoryArea(this).executeInArea(this); 344 _objects.add(_tmpObject); 345 _index++; 346 return _tmpObject; 347 } 348 349 public void recycle(Object obj) { 351 cleanup((Object )obj); 352 for (int i = _index; --i >= 0;) { 353 if (_objects.get(i) == obj) { Object lastObj = _objects.get(--_index); 356 _objects.set(i, lastObj); 357 _objects.set(_index, obj); 358 return; 359 } 360 } 361 throw new IllegalArgumentException ("Object not in the pool"); 362 } 363 364 protected void recycleAll() { 366 for (int i = 0; i < _index; i++) { 368 if (!_doCleanup) 369 break; 370 Object obj = _objects.get(i); 371 cleanup((Object )obj); 372 } 373 _index = 0; 374 } 375 376 protected void clearAll() { 378 _objects.clear(); 379 _index = 0; 380 } 381 382 public void run() { 384 _tmpObject = create(); 385 } 386 387 private Object _tmpObject; 388 } 389 390 } | Popular Tags |